LogicGoInfotechSpaces commited on
Commit
02f88ee
·
1 Parent(s): 67a41f0

Fix Dockerfile build errors: improve dependency installation order and error handling

Browse files
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==1.24.3
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 insightface last - try multiple approaches, allow pip to find compatible version
76
- RUN pip install --no-cache-dir --no-build-isolation insightface==0.7.3 2>&1 || \
77
- pip install --no-cache-dir insightface>=0.7.0,<0.8.0 2>&1 || \
78
- pip install --no-cache-dir insightface 2>&1 || \
79
- pip install --no-cache-dir --no-build-isolation git+https://github.com/deepinsight/insightface.git@v0.7.3 2>&1 || \
80
- pip install --no-cache-dir git+https://github.com/deepinsight/insightface.git 2>&1 || \
81
- (echo "All insightface installation methods failed" && exit 1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 to store binaries in MongoDB -------- #
366
-
367
- async def _gridfs_put(file: UploadFile, metadata: dict) -> str:
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