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() @router.get("/view_images") 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 ={"doe", "mule bucks", "white tail bucks"} 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 }