Commit
·
02f88ee
1
Parent(s):
67a41f0
Fix Dockerfile build errors: improve dependency installation order and error handling
Browse files- Dockerfile +26 -16
- api/COLLECTIONS_INDEX.md +189 -0
- api/Face_Swap_Video_API.postman_collection.json +332 -0
- api/main.py +3 -36
- docker-compose.yml +22 -0
Dockerfile
CHANGED
|
@@ -33,6 +33,9 @@ RUN apt-get update && apt-get install -y \
|
|
| 33 |
g++ \
|
| 34 |
cmake \
|
| 35 |
pkg-config \
|
|
|
|
|
|
|
|
|
|
| 36 |
&& rm -rf /var/lib/apt/lists/*
|
| 37 |
|
| 38 |
# Create user for Hugging Face Spaces (following HF Spaces best practices)
|
|
@@ -54,31 +57,38 @@ RUN pip install --no-cache-dir \
|
|
| 54 |
python-dotenv==1.0.0 \
|
| 55 |
dnspython==2.4.2
|
| 56 |
|
| 57 |
-
# Install numpy first (required by other packages)
|
| 58 |
-
RUN pip install --no-cache-dir numpy
|
| 59 |
-
|
| 60 |
-
# Install OpenCV first (needed by insightface)
|
| 61 |
-
RUN pip install --no-cache-dir opencv-python-headless
|
| 62 |
-
|
| 63 |
-
# Install ONNX Runtime
|
| 64 |
-
RUN pip install --no-cache-dir onnxruntime==1.17.3
|
| 65 |
|
| 66 |
# Install utility dependencies (install these before insightface as they might be dependencies)
|
| 67 |
RUN pip install --no-cache-dir \
|
| 68 |
psutil==5.9.5 \
|
| 69 |
tqdm==4.65.0 \
|
| 70 |
Pillow \
|
| 71 |
-
moviepy==1.0.3 \
|
| 72 |
imageio-ffmpeg \
|
| 73 |
huggingface_hub>=0.23.0
|
| 74 |
|
| 75 |
-
# Install
|
| 76 |
-
RUN pip install --no-cache-dir
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 82 |
|
| 83 |
# Copy only essential application files
|
| 84 |
COPY --chown=user:user api_server.py /app/
|
|
|
|
| 33 |
g++ \
|
| 34 |
cmake \
|
| 35 |
pkg-config \
|
| 36 |
+
curl \
|
| 37 |
+
wget \
|
| 38 |
+
ca-certificates \
|
| 39 |
&& rm -rf /var/lib/apt/lists/*
|
| 40 |
|
| 41 |
# Create user for Hugging Face Spaces (following HF Spaces best practices)
|
|
|
|
| 57 |
python-dotenv==1.0.0 \
|
| 58 |
dnspython==2.4.2
|
| 59 |
|
| 60 |
+
# Install numpy first (required by other packages) - use compatible version
|
| 61 |
+
RUN pip install --no-cache-dir "numpy>=1.24.0,<1.27.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
# Install utility dependencies (install these before insightface as they might be dependencies)
|
| 64 |
RUN pip install --no-cache-dir \
|
| 65 |
psutil==5.9.5 \
|
| 66 |
tqdm==4.65.0 \
|
| 67 |
Pillow \
|
|
|
|
| 68 |
imageio-ffmpeg \
|
| 69 |
huggingface_hub>=0.23.0
|
| 70 |
|
| 71 |
+
# Install OpenCV first (needed by insightface)
|
| 72 |
+
RUN pip install --no-cache-dir opencv-python-headless
|
| 73 |
+
|
| 74 |
+
# Install ONNX Runtime - try CPU version first as it's more compatible
|
| 75 |
+
RUN (pip install --no-cache-dir onnxruntime==1.17.3 || \
|
| 76 |
+
pip install --no-cache-dir "onnxruntime>=1.16.0,<1.18.0" || \
|
| 77 |
+
pip install --no-cache-dir onnxruntime-cpu==1.17.3 || \
|
| 78 |
+
pip install --no-cache-dir "onnxruntime-cpu>=1.16.0,<1.18.0") && \
|
| 79 |
+
python -c "import onnxruntime; print(f'ONNX Runtime version: {onnxruntime.__version__}')" || \
|
| 80 |
+
(echo "ERROR: Failed to install ONNX Runtime. Check build logs above." && exit 1)
|
| 81 |
+
|
| 82 |
+
# Install moviepy after other dependencies
|
| 83 |
+
RUN pip install --no-cache-dir moviepy==1.0.3
|
| 84 |
+
|
| 85 |
+
# Install insightface last - try multiple approaches with better error handling
|
| 86 |
+
RUN pip install --no-cache-dir --no-build-isolation insightface==0.7.3 || \
|
| 87 |
+
pip install --no-cache-dir "insightface>=0.7.0,<0.8.0" || \
|
| 88 |
+
pip install --no-cache-dir insightface || \
|
| 89 |
+
pip install --no-cache-dir --no-build-isolation git+https://github.com/deepinsight/insightface.git@v0.7.3 || \
|
| 90 |
+
pip install --no-cache-dir git+https://github.com/deepinsight/insightface.git || \
|
| 91 |
+
(echo "ERROR: All insightface installation methods failed. Check build logs above for details." && exit 1)
|
| 92 |
|
| 93 |
# Copy only essential application files
|
| 94 |
COPY --chown=user:user api_server.py /app/
|
api/COLLECTIONS_INDEX.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Face Swap Video API - Collections Index
|
| 2 |
+
|
| 3 |
+
**Base URL:** `https://logicgoinfotechspaces-face-swap-video.hf.space`
|
| 4 |
+
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
## 📊 **MongoDB Collections**
|
| 8 |
+
|
| 9 |
+
### **1. source_images**
|
| 10 |
+
**Collection Name:** `source_images`
|
| 11 |
+
**Database:** `face_swap_video`
|
| 12 |
+
|
| 13 |
+
**Schema:**
|
| 14 |
+
```json
|
| 15 |
+
{
|
| 16 |
+
"_id": "ObjectId",
|
| 17 |
+
"filename": "string",
|
| 18 |
+
"file_path": "string",
|
| 19 |
+
"uploaded_at": "datetime",
|
| 20 |
+
"status": "string",
|
| 21 |
+
"content_type": "string",
|
| 22 |
+
"file_size": "number"
|
| 23 |
+
}
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
**API Endpoints:**
|
| 27 |
+
- **Upload:** `POST https://logicgoinfotechspaces-face-swap-video.hf.space/api/source-image`
|
| 28 |
+
- **List All:** `GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/source-images`
|
| 29 |
+
- **Get One:** Use `_id` from list response
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
|
| 33 |
+
### **2. target_videos**
|
| 34 |
+
**Collection Name:** `target_videos`
|
| 35 |
+
**Database:** `face_swap_video`
|
| 36 |
+
|
| 37 |
+
**Schema:**
|
| 38 |
+
```json
|
| 39 |
+
{
|
| 40 |
+
"_id": "ObjectId",
|
| 41 |
+
"filename": "string",
|
| 42 |
+
"file_path": "string",
|
| 43 |
+
"uploaded_at": "datetime",
|
| 44 |
+
"status": "string",
|
| 45 |
+
"content_type": "string",
|
| 46 |
+
"file_size": "number"
|
| 47 |
+
}
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
**API Endpoints:**
|
| 51 |
+
- **Upload:** `POST https://logicgoinfotechspaces-face-swap-video.hf.space/api/target-video`
|
| 52 |
+
- **List All:** `GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/target-videos`
|
| 53 |
+
- **Get One:** Use `_id` from list response
|
| 54 |
+
|
| 55 |
+
---
|
| 56 |
+
|
| 57 |
+
### **3. result_videos**
|
| 58 |
+
**Collection Name:** `result_videos`
|
| 59 |
+
**Database:** `face_swap_video`
|
| 60 |
+
|
| 61 |
+
**Schema:**
|
| 62 |
+
```json
|
| 63 |
+
{
|
| 64 |
+
"_id": "ObjectId",
|
| 65 |
+
"source_image_path": "string",
|
| 66 |
+
"target_video_path": "string",
|
| 67 |
+
"result_file_path": "string",
|
| 68 |
+
"created_at": "datetime",
|
| 69 |
+
"status": "string",
|
| 70 |
+
"job_id": "string",
|
| 71 |
+
"processing_time": "number (optional)"
|
| 72 |
+
}
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
**API Endpoints:**
|
| 76 |
+
- **Download:** `GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/result-video/{result_video_id}`
|
| 77 |
+
- **List All:** `GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/result-videos`
|
| 78 |
+
- **Get Download URL:** Use `result_video_url` from job status when `status = "completed"`
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
|
| 82 |
+
### **4. processing_jobs**
|
| 83 |
+
**Collection Name:** `processing_jobs`
|
| 84 |
+
**Database:** `face_swap_video`
|
| 85 |
+
|
| 86 |
+
**Schema:**
|
| 87 |
+
```json
|
| 88 |
+
{
|
| 89 |
+
"_id": "ObjectId",
|
| 90 |
+
"job_id": "string (UUID)",
|
| 91 |
+
"source_image_id": "string",
|
| 92 |
+
"target_video_id": "string",
|
| 93 |
+
"status": "string (queued|processing|completed|failed)",
|
| 94 |
+
"created_at": "datetime",
|
| 95 |
+
"progress": "number (0-100)",
|
| 96 |
+
"result_video_id": "string (optional)",
|
| 97 |
+
"result_video_url": "string (optional)",
|
| 98 |
+
"error": "string (optional)"
|
| 99 |
+
}
|
| 100 |
+
```
|
| 101 |
+
|
| 102 |
+
**API Endpoints:**
|
| 103 |
+
- **Create Job:** `POST https://logicgoinfotechspaces-face-swap-video.hf.space/api/face-swap`
|
| 104 |
+
- **Get Status:** `GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/job/{job_id}`
|
| 105 |
+
|
| 106 |
+
---
|
| 107 |
+
|
| 108 |
+
## 🔗 **Complete API Endpoints Index**
|
| 109 |
+
|
| 110 |
+
### **Upload Endpoints**
|
| 111 |
+
```
|
| 112 |
+
POST https://logicgoinfotechspaces-face-swap-video.hf.space/api/source-image
|
| 113 |
+
POST https://logicgoinfotechspaces-face-swap-video.hf.space/api/target-video
|
| 114 |
+
```
|
| 115 |
+
|
| 116 |
+
### **Processing Endpoints**
|
| 117 |
+
```
|
| 118 |
+
POST https://logicgoinfotechspaces-face-swap-video.hf.space/api/face-swap
|
| 119 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/job/{job_id}
|
| 120 |
+
```
|
| 121 |
+
|
| 122 |
+
### **Download Endpoints**
|
| 123 |
+
```
|
| 124 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/result-video/{result_video_id}
|
| 125 |
+
```
|
| 126 |
+
|
| 127 |
+
### **List Endpoints**
|
| 128 |
+
```
|
| 129 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/source-images
|
| 130 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/target-videos
|
| 131 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/result-videos
|
| 132 |
+
```
|
| 133 |
+
|
| 134 |
+
### **Utility Endpoints**
|
| 135 |
+
```
|
| 136 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/api/health
|
| 137 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/docs
|
| 138 |
+
GET https://logicgoinfotechspaces-face-swap-video.hf.space/
|
| 139 |
+
```
|
| 140 |
+
|
| 141 |
+
---
|
| 142 |
+
|
| 143 |
+
## 📝 **MongoDB Connection String**
|
| 144 |
+
|
| 145 |
+
```
|
| 146 |
+
mongodb+srv://itishalogicgo_db_user:HR837xi0B9yh2vZK@cluster0.jeeytpz.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0
|
| 147 |
+
```
|
| 148 |
+
|
| 149 |
+
**Database:** `face_swap_video`
|
| 150 |
+
|
| 151 |
+
**Collections:**
|
| 152 |
+
1. `source_images`
|
| 153 |
+
2. `target_videos`
|
| 154 |
+
3. `result_videos`
|
| 155 |
+
4. `processing_jobs`
|
| 156 |
+
|
| 157 |
+
---
|
| 158 |
+
|
| 159 |
+
## 🔄 **Workflow Example**
|
| 160 |
+
|
| 161 |
+
1. **Upload Source Image** → Get `source_image_id`
|
| 162 |
+
2. **Upload Target Video** → Get `target_video_id`
|
| 163 |
+
3. **Start Face Swap** → Get `job_id`
|
| 164 |
+
4. **Poll Job Status** → Get `result_video_url` when `status = "completed"`
|
| 165 |
+
5. **Download Result** → Use `result_video_url` directly
|
| 166 |
+
|
| 167 |
+
---
|
| 168 |
+
|
| 169 |
+
## 📋 **Quick Reference**
|
| 170 |
+
|
| 171 |
+
| Collection | Insert Endpoint | List Endpoint | Get One |
|
| 172 |
+
|------------|----------------|---------------|---------|
|
| 173 |
+
| `source_images` | `POST /api/source-image` | `GET /api/source-images` | Use `_id` |
|
| 174 |
+
| `target_videos` | `POST /api/target-video` | `GET /api/target-videos` | Use `_id` |
|
| 175 |
+
| `result_videos` | Auto via job completion | `GET /api/result-videos` | `GET /api/result-video/{id}` |
|
| 176 |
+
| `processing_jobs` | `POST /api/face-swap` | N/A | `GET /api/job/{job_id}` |
|
| 177 |
+
|
| 178 |
+
---
|
| 179 |
+
|
| 180 |
+
## 🌐 **MongoDB Atlas Dashboard**
|
| 181 |
+
|
| 182 |
+
Access your collections at:
|
| 183 |
+
```
|
| 184 |
+
https://cloud.mongodb.com/
|
| 185 |
+
```
|
| 186 |
+
|
| 187 |
+
**Cluster:** `Cluster0`
|
| 188 |
+
**Database:** `face_swap_video`
|
| 189 |
+
**Collections:** 4 collections listed above
|
api/Face_Swap_Video_API.postman_collection.json
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"info": {
|
| 3 |
+
"_postman_id": "face-swap-video-api",
|
| 4 |
+
"name": "Face Swap Video API",
|
| 5 |
+
"description": "Complete API collection for Face Swap Video processing with MongoDB storage",
|
| 6 |
+
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
| 7 |
+
},
|
| 8 |
+
"item": [
|
| 9 |
+
{
|
| 10 |
+
"name": "Source Image",
|
| 11 |
+
"item": [
|
| 12 |
+
{
|
| 13 |
+
"name": "Upload Source Image",
|
| 14 |
+
"request": {
|
| 15 |
+
"method": "POST",
|
| 16 |
+
"header": [
|
| 17 |
+
{
|
| 18 |
+
"key": "accept",
|
| 19 |
+
"value": "application/json"
|
| 20 |
+
}
|
| 21 |
+
],
|
| 22 |
+
"body": {
|
| 23 |
+
"mode": "formdata",
|
| 24 |
+
"formdata": [
|
| 25 |
+
{
|
| 26 |
+
"key": "file",
|
| 27 |
+
"type": "file",
|
| 28 |
+
"src": []
|
| 29 |
+
}
|
| 30 |
+
]
|
| 31 |
+
},
|
| 32 |
+
"url": {
|
| 33 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/source-image",
|
| 34 |
+
"protocol": "https",
|
| 35 |
+
"host": [
|
| 36 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 37 |
+
"hf",
|
| 38 |
+
"space"
|
| 39 |
+
],
|
| 40 |
+
"path": [
|
| 41 |
+
"api",
|
| 42 |
+
"source-image"
|
| 43 |
+
]
|
| 44 |
+
},
|
| 45 |
+
"description": "Upload and store source image in MongoDB"
|
| 46 |
+
},
|
| 47 |
+
"response": []
|
| 48 |
+
},
|
| 49 |
+
{
|
| 50 |
+
"name": "List All Source Images",
|
| 51 |
+
"request": {
|
| 52 |
+
"method": "GET",
|
| 53 |
+
"header": [],
|
| 54 |
+
"url": {
|
| 55 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/source-images",
|
| 56 |
+
"protocol": "https",
|
| 57 |
+
"host": [
|
| 58 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 59 |
+
"hf",
|
| 60 |
+
"space"
|
| 61 |
+
],
|
| 62 |
+
"path": [
|
| 63 |
+
"api",
|
| 64 |
+
"source-images"
|
| 65 |
+
]
|
| 66 |
+
},
|
| 67 |
+
"description": "List all uploaded source images"
|
| 68 |
+
},
|
| 69 |
+
"response": []
|
| 70 |
+
}
|
| 71 |
+
],
|
| 72 |
+
"description": "Source image management endpoints"
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"name": "Target Video",
|
| 76 |
+
"item": [
|
| 77 |
+
{
|
| 78 |
+
"name": "Upload Target Video",
|
| 79 |
+
"request": {
|
| 80 |
+
"method": "POST",
|
| 81 |
+
"header": [
|
| 82 |
+
{
|
| 83 |
+
"key": "accept",
|
| 84 |
+
"value": "application/json"
|
| 85 |
+
}
|
| 86 |
+
],
|
| 87 |
+
"body": {
|
| 88 |
+
"mode": "formdata",
|
| 89 |
+
"formdata": [
|
| 90 |
+
{
|
| 91 |
+
"key": "file",
|
| 92 |
+
"type": "file",
|
| 93 |
+
"src": []
|
| 94 |
+
}
|
| 95 |
+
]
|
| 96 |
+
},
|
| 97 |
+
"url": {
|
| 98 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/target-video",
|
| 99 |
+
"protocol": "https",
|
| 100 |
+
"host": [
|
| 101 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 102 |
+
"hf",
|
| 103 |
+
"space"
|
| 104 |
+
],
|
| 105 |
+
"path": [
|
| 106 |
+
"api",
|
| 107 |
+
"target-video"
|
| 108 |
+
]
|
| 109 |
+
},
|
| 110 |
+
"description": "Upload and store target video in MongoDB"
|
| 111 |
+
},
|
| 112 |
+
"response": []
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"name": "List All Target Videos",
|
| 116 |
+
"request": {
|
| 117 |
+
"method": "GET",
|
| 118 |
+
"header": [],
|
| 119 |
+
"url": {
|
| 120 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/target-videos",
|
| 121 |
+
"protocol": "https",
|
| 122 |
+
"host": [
|
| 123 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 124 |
+
"hf",
|
| 125 |
+
"space"
|
| 126 |
+
],
|
| 127 |
+
"path": [
|
| 128 |
+
"api",
|
| 129 |
+
"target-videos"
|
| 130 |
+
]
|
| 131 |
+
},
|
| 132 |
+
"description": "List all uploaded target videos"
|
| 133 |
+
},
|
| 134 |
+
"response": []
|
| 135 |
+
}
|
| 136 |
+
],
|
| 137 |
+
"description": "Target video management endpoints"
|
| 138 |
+
},
|
| 139 |
+
{
|
| 140 |
+
"name": "Face Swap Processing",
|
| 141 |
+
"item": [
|
| 142 |
+
{
|
| 143 |
+
"name": "Start Face Swap",
|
| 144 |
+
"request": {
|
| 145 |
+
"method": "POST",
|
| 146 |
+
"header": [
|
| 147 |
+
{
|
| 148 |
+
"key": "Content-Type",
|
| 149 |
+
"value": "application/json"
|
| 150 |
+
}
|
| 151 |
+
],
|
| 152 |
+
"body": {
|
| 153 |
+
"mode": "raw",
|
| 154 |
+
"raw": "{\n \"source_image_id\": \"SOURCE_IMAGE_ID\",\n \"target_video_id\": \"TARGET_VIDEO_ID\"\n}",
|
| 155 |
+
"options": {
|
| 156 |
+
"raw": {
|
| 157 |
+
"language": "json"
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
},
|
| 161 |
+
"url": {
|
| 162 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/face-swap",
|
| 163 |
+
"protocol": "https",
|
| 164 |
+
"host": [
|
| 165 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 166 |
+
"hf",
|
| 167 |
+
"space"
|
| 168 |
+
],
|
| 169 |
+
"path": [
|
| 170 |
+
"api",
|
| 171 |
+
"face-swap"
|
| 172 |
+
]
|
| 173 |
+
},
|
| 174 |
+
"description": "Start face swap processing. Returns job_id for status tracking."
|
| 175 |
+
},
|
| 176 |
+
"response": []
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"name": "Get Job Status",
|
| 180 |
+
"request": {
|
| 181 |
+
"method": "GET",
|
| 182 |
+
"header": [],
|
| 183 |
+
"url": {
|
| 184 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/job/{{job_id}}",
|
| 185 |
+
"protocol": "https",
|
| 186 |
+
"host": [
|
| 187 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 188 |
+
"hf",
|
| 189 |
+
"space"
|
| 190 |
+
],
|
| 191 |
+
"path": [
|
| 192 |
+
"api",
|
| 193 |
+
"job",
|
| 194 |
+
"{{job_id}}"
|
| 195 |
+
]
|
| 196 |
+
},
|
| 197 |
+
"description": "Get job status. When status='completed', result_video_url will contain the download URL."
|
| 198 |
+
},
|
| 199 |
+
"response": []
|
| 200 |
+
}
|
| 201 |
+
],
|
| 202 |
+
"description": "Face swap processing endpoints"
|
| 203 |
+
},
|
| 204 |
+
{
|
| 205 |
+
"name": "Result Videos",
|
| 206 |
+
"item": [
|
| 207 |
+
{
|
| 208 |
+
"name": "Download Result Video",
|
| 209 |
+
"request": {
|
| 210 |
+
"method": "GET",
|
| 211 |
+
"header": [],
|
| 212 |
+
"url": {
|
| 213 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/result-video/{{result_video_id}}",
|
| 214 |
+
"protocol": "https",
|
| 215 |
+
"host": [
|
| 216 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 217 |
+
"hf",
|
| 218 |
+
"space"
|
| 219 |
+
],
|
| 220 |
+
"path": [
|
| 221 |
+
"api",
|
| 222 |
+
"result-video",
|
| 223 |
+
"{{result_video_id}}"
|
| 224 |
+
]
|
| 225 |
+
},
|
| 226 |
+
"description": "Download result video file. Use result_video_url from job status when completed."
|
| 227 |
+
},
|
| 228 |
+
"response": []
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"name": "List All Result Videos",
|
| 232 |
+
"request": {
|
| 233 |
+
"method": "GET",
|
| 234 |
+
"header": [],
|
| 235 |
+
"url": {
|
| 236 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/result-videos",
|
| 237 |
+
"protocol": "https",
|
| 238 |
+
"host": [
|
| 239 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 240 |
+
"hf",
|
| 241 |
+
"space"
|
| 242 |
+
],
|
| 243 |
+
"path": [
|
| 244 |
+
"api",
|
| 245 |
+
"result-videos"
|
| 246 |
+
]
|
| 247 |
+
},
|
| 248 |
+
"description": "List all processed result videos"
|
| 249 |
+
},
|
| 250 |
+
"response": []
|
| 251 |
+
}
|
| 252 |
+
],
|
| 253 |
+
"description": "Result video management endpoints"
|
| 254 |
+
},
|
| 255 |
+
{
|
| 256 |
+
"name": "Utility",
|
| 257 |
+
"item": [
|
| 258 |
+
{
|
| 259 |
+
"name": "Health Check",
|
| 260 |
+
"request": {
|
| 261 |
+
"method": "GET",
|
| 262 |
+
"header": [],
|
| 263 |
+
"url": {
|
| 264 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/api/health",
|
| 265 |
+
"protocol": "https",
|
| 266 |
+
"host": [
|
| 267 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 268 |
+
"hf",
|
| 269 |
+
"space"
|
| 270 |
+
],
|
| 271 |
+
"path": [
|
| 272 |
+
"api",
|
| 273 |
+
"health"
|
| 274 |
+
]
|
| 275 |
+
},
|
| 276 |
+
"description": "Check API health status"
|
| 277 |
+
},
|
| 278 |
+
"response": []
|
| 279 |
+
},
|
| 280 |
+
{
|
| 281 |
+
"name": "API Root",
|
| 282 |
+
"request": {
|
| 283 |
+
"method": "GET",
|
| 284 |
+
"header": [],
|
| 285 |
+
"url": {
|
| 286 |
+
"raw": "https://logicgoinfotechspaces-face-swap-video.hf.space/",
|
| 287 |
+
"protocol": "https",
|
| 288 |
+
"host": [
|
| 289 |
+
"logicgoinfotechspaces-face-swap-video",
|
| 290 |
+
"hf",
|
| 291 |
+
"space"
|
| 292 |
+
],
|
| 293 |
+
"path": [
|
| 294 |
+
""
|
| 295 |
+
]
|
| 296 |
+
},
|
| 297 |
+
"description": "API root endpoint"
|
| 298 |
+
},
|
| 299 |
+
"response": []
|
| 300 |
+
}
|
| 301 |
+
],
|
| 302 |
+
"description": "Utility endpoints"
|
| 303 |
+
}
|
| 304 |
+
],
|
| 305 |
+
"variable": [
|
| 306 |
+
{
|
| 307 |
+
"key": "base_url",
|
| 308 |
+
"value": "https://logicgoinfotechspaces-face-swap-video.hf.space",
|
| 309 |
+
"type": "string"
|
| 310 |
+
},
|
| 311 |
+
{
|
| 312 |
+
"key": "source_image_id",
|
| 313 |
+
"value": "",
|
| 314 |
+
"type": "string"
|
| 315 |
+
},
|
| 316 |
+
{
|
| 317 |
+
"key": "target_video_id",
|
| 318 |
+
"value": "",
|
| 319 |
+
"type": "string"
|
| 320 |
+
},
|
| 321 |
+
{
|
| 322 |
+
"key": "job_id",
|
| 323 |
+
"value": "",
|
| 324 |
+
"type": "string"
|
| 325 |
+
},
|
| 326 |
+
{
|
| 327 |
+
"key": "result_video_id",
|
| 328 |
+
"value": "",
|
| 329 |
+
"type": "string"
|
| 330 |
+
}
|
| 331 |
+
]
|
| 332 |
+
}
|
api/main.py
CHANGED
|
@@ -11,7 +11,6 @@ from bson import ObjectId
|
|
| 11 |
import json
|
| 12 |
import shutil
|
| 13 |
from pathlib import Path
|
| 14 |
-
from gridfs import GridFS
|
| 15 |
from fastapi.responses import FileResponse, StreamingResponse, JSONResponse
|
| 16 |
|
| 17 |
# Import face swap functionality
|
|
@@ -35,7 +34,6 @@ MONGODB_URL = os.getenv("MONGODB_URL", "mongodb+srv://itishalogicgo_db_user:HR83
|
|
| 35 |
DATABASE_NAME = "face_swap_video"
|
| 36 |
client = motor.motor_asyncio.AsyncIOMotorClient(MONGODB_URL)
|
| 37 |
db = client[DATABASE_NAME]
|
| 38 |
-
fs = GridFS(db)
|
| 39 |
|
| 40 |
# Collections
|
| 41 |
source_images_collection = db["source_images"]
|
|
@@ -362,40 +360,9 @@ async def list_result_videos():
|
|
| 362 |
async def api_health():
|
| 363 |
return {"status": "ok", "time": datetime.utcnow().isoformat()}
|
| 364 |
|
| 365 |
-
# -------- Optional: GridFS variants
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
data = await file.read()
|
| 369 |
-
file_id = fs.put(data, filename=file.filename, content_type=file.content_type, metadata=metadata)
|
| 370 |
-
return str(file_id)
|
| 371 |
-
|
| 372 |
-
@app.post("/api/source-image/gridfs")
|
| 373 |
-
async def upload_source_image_gridfs(file: UploadFile = File(...)):
|
| 374 |
-
if not file.content_type.startswith('image/'):
|
| 375 |
-
raise HTTPException(status_code=400, detail="File must be an image")
|
| 376 |
-
file_id = await _gridfs_put(file, {"kind": "source_image", "uploaded_at": datetime.utcnow()})
|
| 377 |
-
doc = {"gridfs_id": file_id, "filename": file.filename, "uploaded_at": datetime.utcnow(), "status": "uploaded"}
|
| 378 |
-
result = await source_images_collection.insert_one(doc)
|
| 379 |
-
return {"id": str(result.inserted_id), "gridfs_id": file_id}
|
| 380 |
-
|
| 381 |
-
@app.post("/api/target-video/gridfs")
|
| 382 |
-
async def upload_target_video_gridfs(file: UploadFile = File(...)):
|
| 383 |
-
if not file.content_type.startswith('video/'):
|
| 384 |
-
raise HTTPException(status_code=400, detail="File must be a video")
|
| 385 |
-
file_id = await _gridfs_put(file, {"kind": "target_video", "uploaded_at": datetime.utcnow()})
|
| 386 |
-
doc = {"gridfs_id": file_id, "filename": file.filename, "uploaded_at": datetime.utcnow(), "status": "uploaded"}
|
| 387 |
-
result = await target_videos_collection.insert_one(doc)
|
| 388 |
-
return {"id": str(result.inserted_id), "gridfs_id": file_id}
|
| 389 |
-
|
| 390 |
-
@app.get("/api/file/{file_id}")
|
| 391 |
-
async def get_file_from_gridfs(file_id: str):
|
| 392 |
-
try:
|
| 393 |
-
oid = ObjectId(file_id)
|
| 394 |
-
except Exception:
|
| 395 |
-
raise HTTPException(status_code=400, detail="Invalid file id")
|
| 396 |
-
gf = fs.get(oid)
|
| 397 |
-
headers = {"Content-Disposition": f"inline; filename={gf.filename}"}
|
| 398 |
-
return StreamingResponse(gf, media_type=gf.content_type or "application/octet-stream", headers=headers)
|
| 399 |
|
| 400 |
@app.get("/")
|
| 401 |
async def root():
|
|
|
|
| 11 |
import json
|
| 12 |
import shutil
|
| 13 |
from pathlib import Path
|
|
|
|
| 14 |
from fastapi.responses import FileResponse, StreamingResponse, JSONResponse
|
| 15 |
|
| 16 |
# Import face swap functionality
|
|
|
|
| 34 |
DATABASE_NAME = "face_swap_video"
|
| 35 |
client = motor.motor_asyncio.AsyncIOMotorClient(MONGODB_URL)
|
| 36 |
db = client[DATABASE_NAME]
|
|
|
|
| 37 |
|
| 38 |
# Collections
|
| 39 |
source_images_collection = db["source_images"]
|
|
|
|
| 360 |
async def api_health():
|
| 361 |
return {"status": "ok", "time": datetime.utcnow().isoformat()}
|
| 362 |
|
| 363 |
+
# -------- Optional: GridFS variants (disabled - using file system storage) -------- #
|
| 364 |
+
# GridFS endpoints removed - using file system storage instead
|
| 365 |
+
# If needed, can be re-enabled with motor's GridFSBucketAsync for async operations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
|
| 367 |
@app.get("/")
|
| 368 |
async def root():
|
docker-compose.yml
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version: '3.8'
|
| 2 |
+
|
| 3 |
+
services:
|
| 4 |
+
face-swap-api:
|
| 5 |
+
build: .
|
| 6 |
+
ports:
|
| 7 |
+
- "8000:8000"
|
| 8 |
+
environment:
|
| 9 |
+
- MONGODB_URL=${MONGODB_URL:-mongodb+srv://itishalogicgo_db_user:HR837xi0B9yh2vZK@cluster0.jeeytpz.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0}
|
| 10 |
+
- BASE_URL=http://localhost:8000
|
| 11 |
+
- CUDA_VISIBLE_DEVICES=0
|
| 12 |
+
volumes:
|
| 13 |
+
- ./uploads:/app/uploads
|
| 14 |
+
- ./DeepFakeAI/.assets:/app/DeepFakeAI/.assets
|
| 15 |
+
deploy:
|
| 16 |
+
resources:
|
| 17 |
+
reservations:
|
| 18 |
+
devices:
|
| 19 |
+
- driver: nvidia
|
| 20 |
+
count: 1
|
| 21 |
+
capabilities: [gpu]
|
| 22 |
+
restart: unless-stopped
|