Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
movies: auto-detect v3/v4 credential + source field
Browse files- app/main.py +2 -1
- app/movies_tmdb.py +22 -16
app/main.py
CHANGED
|
@@ -370,7 +370,8 @@ def movies_now_playing(request: Request = None):
|
|
| 370 |
if request is not None:
|
| 371 |
_limit(request, "mov", rate=60)
|
| 372 |
import movies_tmdb
|
| 373 |
-
|
|
|
|
| 374 |
|
| 375 |
|
| 376 |
@app.post("/voice", dependencies=[Depends(require_app_key)])
|
|
|
|
| 370 |
if request is not None:
|
| 371 |
_limit(request, "mov", rate=60)
|
| 372 |
import movies_tmdb
|
| 373 |
+
movies, source = movies_tmdb.now_playing()
|
| 374 |
+
return {"live": movies_tmdb.is_live(), "source": source, "movies": movies}
|
| 375 |
|
| 376 |
|
| 377 |
@app.post("/voice", dependencies=[Depends(require_app_key)])
|
app/movies_tmdb.py
CHANGED
|
@@ -22,40 +22,46 @@ from typing import List, Dict
|
|
| 22 |
_NOW_PLAYING = "https://api.themoviedb.org/3/movie/now_playing"
|
| 23 |
|
| 24 |
|
| 25 |
-
def
|
| 26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
|
| 29 |
def is_live() -> bool:
|
| 30 |
-
|
|
|
|
| 31 |
|
| 32 |
|
| 33 |
-
def now_playing(limit: int = 24)
|
| 34 |
-
"""
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
|
|
|
| 38 |
import httpx
|
| 39 |
-
|
| 40 |
-
params = {"region": region, "language": "en-US", "page": 1}
|
| 41 |
headers = {}
|
| 42 |
-
if
|
| 43 |
-
headers["Authorization"] = f"Bearer {
|
| 44 |
else:
|
| 45 |
-
params["api_key"] =
|
| 46 |
try:
|
| 47 |
r = httpx.get(_NOW_PLAYING, params=params, headers=headers, timeout=10.0)
|
| 48 |
r.raise_for_status()
|
| 49 |
rows = r.json().get("results", [])
|
| 50 |
-
except Exception:
|
| 51 |
-
return _curated()
|
| 52 |
rows.sort(key=lambda m: m.get("popularity", 0), reverse=True)
|
| 53 |
out: List[Dict] = []
|
| 54 |
for m in rows[:limit]:
|
| 55 |
title = m.get("title") or m.get("original_title")
|
| 56 |
if title:
|
| 57 |
out.append({"title": title, "release_date": m.get("release_date"), "id": m.get("id")})
|
| 58 |
-
return out or _curated()
|
| 59 |
|
| 60 |
|
| 61 |
# Curated fallback: titles in Indian theatres as of Jul 2026. Refresh when stale,
|
|
|
|
| 22 |
_NOW_PLAYING = "https://api.themoviedb.org/3/movie/now_playing"
|
| 23 |
|
| 24 |
|
| 25 |
+
def _credential():
|
| 26 |
+
"""Accept the token in either env var and auto-detect its type, so it works
|
| 27 |
+
whether the user pasted a v3 API key or a v4 Read Access Token, in either
|
| 28 |
+
slot. v4 tokens are long JWTs beginning 'eyJ'; v3 keys are short hex."""
|
| 29 |
+
val = (os.getenv("TMDB_READ_TOKEN") or os.getenv("TMDB_API_KEY") or "").strip()
|
| 30 |
+
is_v4 = val.startswith("eyJ") or len(val) > 45
|
| 31 |
+
return val, is_v4
|
| 32 |
|
| 33 |
|
| 34 |
def is_live() -> bool:
|
| 35 |
+
val, _ = _credential()
|
| 36 |
+
return bool(val) and os.getenv("MOVIES_MOCK") != "1"
|
| 37 |
|
| 38 |
|
| 39 |
+
def now_playing(limit: int = 24):
|
| 40 |
+
"""Returns (movies, source). source is 'tmdb' on a live hit, else a 'curated…'
|
| 41 |
+
string that names why we fell back - so a caller can diagnose a bad key."""
|
| 42 |
+
val, is_v4 = _credential()
|
| 43 |
+
if not val or os.getenv("MOVIES_MOCK") == "1":
|
| 44 |
+
return _curated(), "curated (no credential)"
|
| 45 |
import httpx
|
| 46 |
+
params = {"region": os.getenv("TMDB_REGION", "IN"), "language": "en-US", "page": 1}
|
|
|
|
| 47 |
headers = {}
|
| 48 |
+
if is_v4:
|
| 49 |
+
headers["Authorization"] = f"Bearer {val}" # v4 read token
|
| 50 |
else:
|
| 51 |
+
params["api_key"] = val # v3 api key
|
| 52 |
try:
|
| 53 |
r = httpx.get(_NOW_PLAYING, params=params, headers=headers, timeout=10.0)
|
| 54 |
r.raise_for_status()
|
| 55 |
rows = r.json().get("results", [])
|
| 56 |
+
except Exception as e: # never break the dropdown
|
| 57 |
+
return _curated(), f"curated (tmdb error: {type(e).__name__})"
|
| 58 |
rows.sort(key=lambda m: m.get("popularity", 0), reverse=True)
|
| 59 |
out: List[Dict] = []
|
| 60 |
for m in rows[:limit]:
|
| 61 |
title = m.get("title") or m.get("original_title")
|
| 62 |
if title:
|
| 63 |
out.append({"title": title, "release_date": m.get("release_date"), "id": m.get("id")})
|
| 64 |
+
return (out, "tmdb") if out else (_curated(), "curated (tmdb empty)") or _curated()
|
| 65 |
|
| 66 |
|
| 67 |
# Curated fallback: titles in Indian theatres as of Jul 2026. Refresh when stale,
|