HariLogicgo commited on
Commit
031a705
·
1 Parent(s): 3c79ccf

added /list-images and faceswap accepts categoryId

Browse files
__pycache__/app.cpython-313.pyc ADDED
Binary file (15.8 kB). View file
 
__pycache__/list.cpython-313.pyc ADDED
Binary file (2.48 kB). View file
 
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import os
2
  os.environ["OMP_NUM_THREADS"] = "1"
3
  import shutil
@@ -13,7 +14,7 @@ import insightface
13
  from insightface.app import FaceAnalysis
14
  from huggingface_hub import hf_hub_download
15
 
16
- from fastapi import FastAPI, UploadFile, File, HTTPException, Response, Depends, Security
17
  from fastapi.responses import RedirectResponse
18
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
19
  from pydantic import BaseModel
@@ -103,7 +104,7 @@ ensure_codeformer()
103
  # --------------------- MongoDB (for API logs only) ---------------------
104
  MONGODB_URL = os.getenv("MONGODB_URL")
105
 
106
- client: AsyncIOMotorClient = None
107
  database = None
108
 
109
  # --------------------- FastAPI ---------------------
@@ -235,26 +236,58 @@ def download_from_spaces(key):
235
  def root():
236
  return RedirectResponse("/gradio")
237
 
238
- @fastapi_app.get("/health", dependencies=[Depends(verify_token)])
239
  async def health():
240
  return {"status": "healthy"}
241
 
 
 
 
242
  @fastapi_app.post("/face-swap", dependencies=[Depends(verify_token)])
243
  async def face_swap_api(
244
  source: UploadFile = File(...),
245
- target: UploadFile = File(...),
246
  credentials: HTTPAuthorizationCredentials = Security(security)
247
  ):
 
248
  try:
249
- # Read images
250
  src_bytes = await source.read()
251
- tgt_bytes = await target.read()
252
 
253
- # Save to Spaces (source/target)
254
  src_key = f"faceswap/source/{uuid.uuid4().hex}_{source.filename}"
255
- tgt_key = f"faceswap/target/{uuid.uuid4().hex}_{target.filename}"
256
  upload_to_spaces(src_bytes, src_key, content_type=source.content_type)
257
- upload_to_spaces(tgt_bytes, tgt_key, content_type=target.content_type)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
259
  # Decode for processing
260
  src_array = np.frombuffer(src_bytes, np.uint8)
@@ -301,6 +334,45 @@ async def preview_result(result_key: str):
301
  headers={"Content-Disposition": "inline; filename=result.png"}
302
  )
303
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  # --------------------- Mount Gradio ---------------------
305
  fastapi_app = mount_gradio_app(fastapi_app, demo, path="/gradio")
306
 
 
1
+ # --------------------- List Images Endpoint ---------------------
2
  import os
3
  os.environ["OMP_NUM_THREADS"] = "1"
4
  import shutil
 
14
  from insightface.app import FaceAnalysis
15
  from huggingface_hub import hf_hub_download
16
 
17
+ from fastapi import FastAPI, UploadFile, File, HTTPException, Response, Depends, Security, Query
18
  from fastapi.responses import RedirectResponse
19
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
20
  from pydantic import BaseModel
 
104
  # --------------------- MongoDB (for API logs only) ---------------------
105
  MONGODB_URL = os.getenv("MONGODB_URL")
106
 
107
+ client = None
108
  database = None
109
 
110
  # --------------------- FastAPI ---------------------
 
236
  def root():
237
  return RedirectResponse("/gradio")
238
 
239
+ @fastapi_app.get("/health")
240
  async def health():
241
  return {"status": "healthy"}
242
 
243
+ from fastapi import Form
244
+ import requests
245
+
246
  @fastapi_app.post("/face-swap", dependencies=[Depends(verify_token)])
247
  async def face_swap_api(
248
  source: UploadFile = File(...),
249
+ target_category_id: str = Form(...),
250
  credentials: HTTPAuthorizationCredentials = Security(security)
251
  ):
252
+
253
  try:
254
+ # Read source image
255
  src_bytes = await source.read()
 
256
 
257
+ # Save source to Spaces
258
  src_key = f"faceswap/source/{uuid.uuid4().hex}_{source.filename}"
 
259
  upload_to_spaces(src_bytes, src_key, content_type=source.content_type)
260
+
261
+ # Find target image URL from categoryId by searching all categories
262
+ client = get_spaces_client()
263
+ base_prefix = "faceswap/target/"
264
+ resp = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=base_prefix, Delimiter="/")
265
+ categories = [prefix["Prefix"].split("/")[2] for prefix in resp.get("CommonPrefixes", [])]
266
+ target_url = None
267
+ for category in categories:
268
+ original_prefix = f"faceswap/target/{category}/original/"
269
+ thumb_prefix = f"faceswap/target/{category}/thumb/"
270
+ original_objects = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=original_prefix)
271
+ thumb_objects = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=thumb_prefix)
272
+ original_files = [obj["Key"].split("/")[-1] for obj in original_objects.get("Contents", []) if obj["Key"].endswith(".png")]
273
+ thumb_files = [obj["Key"].split("/")[-1] for obj in thumb_objects.get("Contents", []) if obj["Key"].endswith(".png")]
274
+ for idx, filename in enumerate(sorted(original_files), start=1):
275
+ cid = f"{category.lower()}image_{idx}"
276
+ if filename in thumb_files and cid == target_category_id:
277
+ target_url = f"https://{DO_SPACES_BUCKET}.blr1.digitaloceanspaces.com/{original_prefix}{filename}"
278
+ break
279
+ if target_url:
280
+ break
281
+ if not target_url:
282
+ await log_faceswap_hit(credentials.credentials, status="error")
283
+ raise HTTPException(status_code=404, detail="Target categoryId not found")
284
+
285
+ # Download target image from Spaces
286
+ resp = requests.get(target_url)
287
+ if resp.status_code != 200:
288
+ await log_faceswap_hit(credentials.credentials, status="error")
289
+ raise HTTPException(status_code=404, detail="Target image not found in Spaces")
290
+ tgt_bytes = resp.content
291
 
292
  # Decode for processing
293
  src_array = np.frombuffer(src_bytes, np.uint8)
 
334
  headers={"Content-Disposition": "inline; filename=result.png"}
335
  )
336
 
337
+ @fastapi_app.get("/list-images", dependencies=[Depends(verify_token)])
338
+ def list_images(category: str = Query(None, description="Category name to list images for. If not provided, returns all available categories.")):
339
+ client = get_spaces_client()
340
+ base_prefix = "faceswap/target/"
341
+
342
+ # If no category is provided, list all categories (folders) under faceswap/target/
343
+ if not category:
344
+ # List all prefixes (categories)
345
+ resp = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=base_prefix, Delimiter="/")
346
+ categories = []
347
+ for prefix in resp.get("CommonPrefixes", []):
348
+ cat = prefix["Prefix"].split("/")[2] # faceswap/target/<category>/
349
+ categories.append(cat)
350
+ return {"categories": categories, "note": "These are available categories. Use /list-images?category=<category> to list images."}
351
+
352
+ # If category is provided, list images in that category
353
+ original_prefix = f"faceswap/target/{category}/original/"
354
+ thumb_prefix = f"faceswap/target/{category}/thumb/"
355
+
356
+ original_objects = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=original_prefix)
357
+ thumb_objects = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=thumb_prefix)
358
+
359
+ original_files = [obj["Key"].split("/")[-1] for obj in original_objects.get("Contents", []) if obj["Key"].endswith(".png")]
360
+ thumb_files = [obj["Key"].split("/")[-1] for obj in thumb_objects.get("Contents", []) if obj["Key"].endswith(".png")]
361
+
362
+ items = []
363
+ for idx, filename in enumerate(sorted(original_files), start=1):
364
+ if filename in thumb_files:
365
+ items.append({
366
+ "categoryId": f"{category.lower()}image_{idx}",
367
+ "url": f"https://{DO_SPACES_BUCKET}.blr1.digitaloceanspaces.com/{original_prefix}{filename}",
368
+ "thumburl": f"https://{DO_SPACES_BUCKET}.blr1.digitaloceanspaces.com/{thumb_prefix}{filename}"
369
+ })
370
+
371
+ return {
372
+ "categoryName": category,
373
+ "items": items,
374
+ "note": "The URLs returned are public and do not require a bearer token."
375
+ }
376
  # --------------------- Mount Gradio ---------------------
377
  fastapi_app = mount_gradio_app(fastapi_app, demo, path="/gradio")
378
 
list.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # from fastapi import FastAPI
2
+ # import boto3
3
+ # import os
4
+
5
+ # app = FastAPI()
6
+
7
+ # # Configure DigitalOcean Spaces (S3 Compatible)
8
+ # session = boto3.session.Session()
9
+ # client = session.client(
10
+ # 's3',
11
+ # region_name='blr1', # DigitalOcean region
12
+ # endpoint_url='https://blr1.digitaloceanspaces.com', # endpoint
13
+ # aws_access_key_id=os.getenv("DO_SPACES_KEY"),
14
+ # aws_secret_access_key=os.getenv("DO_SPACES_SECRET")
15
+ # )
16
+
17
+ # BUCKET_NAME = "milestone"
18
+ # BASE_URL = f"https://{BUCKET_NAME}.blr1.digitaloceanspaces.com"
19
+
20
+ # @app.get("/list-images")
21
+ # def list_images():
22
+ # category_name = "BirthdayParty"
23
+ # original_prefix = f"faceswap/target/{category_name}/original/"
24
+ # thumb_prefix = f"faceswap/target/{category_name}/thumb/"
25
+
26
+ # # List objects in original
27
+ # original_objects = client.list_objects_v2(Bucket=BUCKET_NAME, Prefix=original_prefix)
28
+ # thumb_objects = client.list_objects_v2(Bucket=BUCKET_NAME, Prefix=thumb_prefix)
29
+
30
+ # original_files = [obj["Key"].split("/")[-1] for obj in original_objects.get("Contents", []) if obj["Key"].endswith(".png")]
31
+ # thumb_files = [obj["Key"].split("/")[-1] for obj in thumb_objects.get("Contents", []) if obj["Key"].endswith(".png")]
32
+
33
+ # items = []
34
+ # for idx, filename in enumerate(sorted(original_files), start=1):
35
+ # if filename in thumb_files: # match only if both exist
36
+ # items.append({
37
+ # "categoryId": f"birthdaypartyimage_{idx}",
38
+ # "url": f"{BASE_URL}/{original_prefix}{filename}",
39
+ # "thumburl": f"{BASE_URL}/{thumb_prefix}{filename}"
40
+ # })
41
+
42
+ # return {
43
+ # "categoryName": category_name,
44
+ # "items": items
45
+ # }