Spaces:
Running
Running
| from fastapi import APIRouter, HTTPException, Query, Request | |
| import json | |
| from .utils import ( | |
| _bucket_key, | |
| _key_exists, | |
| _list_prefix, | |
| _read_bucket_json, | |
| user_exists, | |
| BUCKET_ID, | |
| ) | |
| router = APIRouter() | |
| def view_images( | |
| request: Request, | |
| user_id: str = Query(...), | |
| camera_name: str = Query(...), | |
| filter_label: str = Query(None, description="Optional filter: Buck, Doe, Mule, Whitetail") | |
| ): | |
| """ | |
| Get images and detection info for a user's camera. | |
| Returns clickable URLs for each image. | |
| Optionally filter images based on labels (Buck, Doe, Mule, Whitetail). | |
| """ | |
| # ββ existence checks against the bucket ββββββββββββββββββββββ | |
| if not user_exists(user_id): | |
| raise HTTPException(status_code=404, detail="User not found") | |
| raw_prefix = _bucket_key(user_id, camera_name, "raw") | |
| detection_key = _bucket_key(user_id, camera_name, f"{camera_name}_detections.json") | |
| raw_files = _list_prefix(raw_prefix) | |
| if not raw_files: | |
| raise HTTPException(status_code=404, detail="Camera raw folder not found") | |
| if not _key_exists(detection_key): | |
| raise HTTPException(status_code=404, detail="Detection JSON not found") | |
| # ββ load detections from bucket βββββββββββββββββββββββββββββββ | |
| detections = _read_bucket_json(detection_key) | |
| if detections is None: | |
| raise HTTPException(status_code=500, detail="Failed to read detection file") | |
| # ββ build a set of filenames that exist in the bucket βββββββββ | |
| existing_filenames = {item.path.split("/")[-1] for item in raw_files} | |
| # ββ validate filter label βββββββββββββββββββββββββββββββββββββ | |
| valid_filters = {"buck", "doe", "mule", "whitetail"} | |
| filter_lower = filter_label.lower() if filter_label else None | |
| if filter_lower and filter_lower not in valid_filters: | |
| raise HTTPException( | |
| status_code=400, | |
| detail=f"Invalid filter_label. Must be one of {valid_filters}" | |
| ) | |
| # ββ build response ββββββββββββββββββββββββββββββββββββββββββββ | |
| images = [] | |
| for item in detections: | |
| filename = item["filename"] | |
| if filename in existing_filenames: | |
| item["image_url"] = f"https://huggingface.co/buckets/{BUCKET_ID}/resolve/{raw_prefix}/{filename}" | |
| else: | |
| item["missing"] = True | |
| item["image_url"] = None | |
| # Apply label filter if provided | |
| if filter_lower: | |
| filtered_detections = [ | |
| det for det in item.get("detections", []) | |
| if any(lbl.lower().find(filter_lower) != -1 for lbl in det["label"].split("|")) | |
| ] | |
| if filtered_detections: | |
| item["detections"] = filtered_detections | |
| images.append(item) | |
| else: | |
| images.append(item) | |
| return { | |
| "success": True, | |
| "user_id": user_id, | |
| "camera_name": camera_name, | |
| "filter_label": filter_label, | |
| "images": images | |
| } |