Spaces:
Running
Running
fix: multi search face
Browse files- src/api/search.py +25 -4
src/api/search.py
CHANGED
|
@@ -2,6 +2,7 @@ import asyncio
|
|
| 2 |
import hashlib
|
| 3 |
import time
|
| 4 |
import traceback
|
|
|
|
| 5 |
|
| 6 |
from fastapi import APIRouter, File, Form, HTTPException, Request, UploadFile, Depends
|
| 7 |
|
|
@@ -270,8 +271,8 @@ async def _run_object_search(object_vectors, idx_obj, start, user_id, ip, mode)
|
|
| 270 |
async def search_by_face(
|
| 271 |
request: Request,
|
| 272 |
front: UploadFile = File(...),
|
| 273 |
-
left: UploadFile = File(None),
|
| 274 |
-
right: UploadFile = File(None),
|
| 275 |
user_id: str = Form(""),
|
| 276 |
keys: dict = Depends(get_verified_keys),
|
| 277 |
):
|
|
@@ -292,13 +293,23 @@ async def search_by_face(
|
|
| 292 |
ai_manager = request.app.state.ai
|
| 293 |
sem = request.app.state.ai_semaphore
|
| 294 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 295 |
# Read all image bytes in parallel
|
| 296 |
images = {}
|
| 297 |
for name, file in [("front", front), ("left", left), ("right", right)]:
|
| 298 |
if file:
|
| 299 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
|
| 301 |
if not images:
|
|
|
|
|
|
|
| 302 |
raise HTTPException(400, "At least front image required")
|
| 303 |
|
| 304 |
# Process all images in parallel
|
|
@@ -318,15 +329,25 @@ async def search_by_face(
|
|
| 318 |
for result in results:
|
| 319 |
if isinstance(result, Exception):
|
| 320 |
log("WARN", "search.search_by_face.process_error",
|
| 321 |
-
user_id=user_id or "anonymous", ip=ip,
|
|
|
|
| 322 |
continue
|
| 323 |
|
| 324 |
name, vectors = result
|
| 325 |
face_vecs = [v for v in vectors if v["type"] == "face"]
|
| 326 |
if face_vecs:
|
| 327 |
face_vectors_by_angle[name] = face_vecs[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
if not face_vectors_by_angle:
|
|
|
|
|
|
|
| 330 |
raise HTTPException(400, "No face detected in provided images")
|
| 331 |
|
| 332 |
# Fuse embeddings: front weighted higher
|
|
|
|
| 2 |
import hashlib
|
| 3 |
import time
|
| 4 |
import traceback
|
| 5 |
+
from typing import Optional
|
| 6 |
|
| 7 |
from fastapi import APIRouter, File, Form, HTTPException, Request, UploadFile, Depends
|
| 8 |
|
|
|
|
| 271 |
async def search_by_face(
|
| 272 |
request: Request,
|
| 273 |
front: UploadFile = File(...),
|
| 274 |
+
left: Optional[UploadFile] = File(None),
|
| 275 |
+
right: Optional[UploadFile] = File(None),
|
| 276 |
user_id: str = Form(""),
|
| 277 |
keys: dict = Depends(get_verified_keys),
|
| 278 |
):
|
|
|
|
| 293 |
ai_manager = request.app.state.ai
|
| 294 |
sem = request.app.state.ai_semaphore
|
| 295 |
|
| 296 |
+
log("DEBUG", "search.search_by_face.received_files",
|
| 297 |
+
user_id=user_id or "anonymous", ip=ip,
|
| 298 |
+
front=bool(front), left=bool(left), right=bool(right))
|
| 299 |
+
|
| 300 |
# Read all image bytes in parallel
|
| 301 |
images = {}
|
| 302 |
for name, file in [("front", front), ("left", left), ("right", right)]:
|
| 303 |
if file:
|
| 304 |
+
file_bytes = await file.read()
|
| 305 |
+
images[name] = file_bytes
|
| 306 |
+
log("DEBUG", "search.search_by_face.file_read",
|
| 307 |
+
user_id=user_id or "anonymous", ip=ip,
|
| 308 |
+
angle=name, size_bytes=len(file_bytes))
|
| 309 |
|
| 310 |
if not images:
|
| 311 |
+
log("ERROR", "search.search_by_face.no_images",
|
| 312 |
+
user_id=user_id or "anonymous", ip=ip)
|
| 313 |
raise HTTPException(400, "At least front image required")
|
| 314 |
|
| 315 |
# Process all images in parallel
|
|
|
|
| 329 |
for result in results:
|
| 330 |
if isinstance(result, Exception):
|
| 331 |
log("WARN", "search.search_by_face.process_error",
|
| 332 |
+
user_id=user_id or "anonymous", ip=ip,
|
| 333 |
+
error=str(result), traceback=traceback.format_exc()[-500:])
|
| 334 |
continue
|
| 335 |
|
| 336 |
name, vectors = result
|
| 337 |
face_vecs = [v for v in vectors if v["type"] == "face"]
|
| 338 |
if face_vecs:
|
| 339 |
face_vectors_by_angle[name] = face_vecs[0]
|
| 340 |
+
log("DEBUG", "search.search_by_face.face_detected",
|
| 341 |
+
user_id=user_id or "anonymous", ip=ip,
|
| 342 |
+
angle=name, det_score=face_vecs[0].get("det_score", 0))
|
| 343 |
+
else:
|
| 344 |
+
log("WARN", "search.search_by_face.no_face_in_angle",
|
| 345 |
+
user_id=user_id or "anonymous", ip=ip,
|
| 346 |
+
angle=name, vectors_count=len(vectors) if vectors else 0)
|
| 347 |
|
| 348 |
if not face_vectors_by_angle:
|
| 349 |
+
log("ERROR", "search.search_by_face.no_faces_detected",
|
| 350 |
+
user_id=user_id or "anonymous", ip=ip)
|
| 351 |
raise HTTPException(400, "No face detected in provided images")
|
| 352 |
|
| 353 |
# Fuse embeddings: front weighted higher
|