MCPcopy Create free account
hub / github.com/AggieSportsAnalytics/CourtCheck / process_video

Function process_video

backend/app.py:59–151  ·  view source on GitHub ↗
(request: Request)

Source from the content-addressed store, hash-verified

57 modal.Secret.from_name("webhook-secret"),
58 ]
59)
60@modal.fastapi_endpoint(method="POST")
61async def process_video(request: Request):
62 auth_header = request.headers.get("Authorization", "")
63 expected_secret = os.environ.get("MODAL_WEBHOOK_SECRET", "")
64 # hmac.compare_digest avoids the byte-by-byte short-circuit that lets a
65 # network-adjacent attacker enumerate the secret via response timing.
66 if not expected_secret or not hmac.compare_digest(
67 auth_header, f"Bearer {expected_secret}"
68 ):
69 raise HTTPException(status_code=401, detail="Unauthorized")
70
71 try:
72 payload = await request.json()
73 if not isinstance(payload, dict):
74 raise ValueError("Expected an object")
75 match_id = payload.get("match_id")
76 file_key = payload.get("file_key")
77 if not isinstance(match_id, str):
78 raise ValueError("Missing recording ID")
79 uuid.UUID(match_id)
80 if not isinstance(file_key, str) or not file_key.startswith(f"{match_id}/"):
81 raise ValueError("Storage key does not belong to the recording")
82 if any(part in ("", ".", "..") for part in file_key.split("/")):
83 raise ValueError("Invalid storage key")
84 except (ValueError, TypeError):
85 return JSONResponse({"error": "Invalid recording ID or storage key."}, status_code=400)
86
87 supabase = None
88
89 def _stage(stage: str, progress: float, *, failure: str | None = None) -> None:
90 """Write an early-stage breadcrumb to Supabase so the UI shows what's
91 happening during the 15-90s window between the trigger-process webhook
92 and run_pipeline's heartbeat. Without this the page sat on
93 'Calibrating the court · STARTING' (derived stage from progress=0)
94 for the entire Modal cold-start + download + import phase.
95 Defensive on column-missing so an un-migrated environment still
96 runs to completion."""
97 nonlocal supabase
98 payload: dict = {"progress": round(float(progress), 3), "processing_stage": stage}
99 if failure:
100 payload = {**payload, "status": "failed", "error": failure}
101 try:
102 if supabase is None:
103 from supabase import create_client
104 supabase = create_client(os.environ["SUPABASE_URL"], os.environ["SUPABASE_SERVICE_ROLE_KEY"])
105 supabase.table("matches").update(payload).eq("id", match_id).execute()
106 print(f"[Stage] {stage} ({progress:.3f})", flush=True)
107 except Exception as e:
108 payload.pop("processing_stage", None)
109 try:
110 supabase.table("matches").update(payload).eq("id", match_id).execute()
111 print(f"[Stage] {stage} ({progress:.3f}) — stage col missing", flush=True)
112 except Exception as e2:
113 print(f"[Stage] {stage} write failed: {e2}", flush=True)
114
115 try:
116 from supabase import create_client

Callers

nothing calls this directly

Calls 2

run_pipelineFunction · 0.90
_stageFunction · 0.85

Tested by

no test coverage detected