Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
movies: curated fallback + v4 read token support
Browse files- app/movies_tmdb.py +42 -28
app/movies_tmdb.py
CHANGED
|
@@ -1,15 +1,19 @@
|
|
| 1 |
"""
|
| 2 |
-
RewardPilot - latest movies (TMDB adapter)
|
| 3 |
-
==========================================
|
| 4 |
-
Feeds the Movies category a
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
"""
|
| 14 |
|
| 15 |
import os
|
|
@@ -18,36 +22,46 @@ from typing import List, Dict
|
|
| 18 |
_NOW_PLAYING = "https://api.themoviedb.org/3/movie/now_playing"
|
| 19 |
|
| 20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
def is_live() -> bool:
|
| 22 |
-
return bool(os.getenv("TMDB_API_KEY")) and os.getenv("MOVIES_MOCK") != "1"
|
| 23 |
|
| 24 |
|
| 25 |
def now_playing(limit: int = 24) -> List[Dict]:
|
| 26 |
-
"""Current theatrical releases, most popular first. Falls back to
|
| 27 |
-
|
| 28 |
if not is_live():
|
| 29 |
-
return
|
| 30 |
import httpx
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
rows.sort(key=lambda m: m.get("popularity", 0), reverse=True)
|
| 41 |
out: List[Dict] = []
|
| 42 |
for m in rows[:limit]:
|
| 43 |
title = m.get("title") or m.get("original_title")
|
| 44 |
if title:
|
| 45 |
out.append({"title": title, "release_date": m.get("release_date"), "id": m.get("id")})
|
| 46 |
-
return out
|
| 47 |
|
| 48 |
|
| 49 |
-
|
|
|
|
|
|
|
| 50 |
return [{"title": t} for t in [
|
| 51 |
-
"
|
| 52 |
-
"
|
| 53 |
]]
|
|
|
|
| 1 |
"""
|
| 2 |
+
RewardPilot - latest movies (TMDB adapter, with a curated fallback)
|
| 3 |
+
===================================================================
|
| 4 |
+
Feeds the Movies category a "now playing in India" list so the user picks from
|
| 5 |
+
a dropdown instead of typing. The movie title does NOT affect the reward answer
|
| 6 |
+
(that is city + platform + ticket amount) - this is UX polish.
|
| 7 |
+
|
| 8 |
+
Credentials (either one works; never hardcoded):
|
| 9 |
+
TMDB_READ_TOKEN v4 API Read Access Token (Bearer) - the easiest to obtain,
|
| 10 |
+
generated instantly on the TMDB API settings page.
|
| 11 |
+
TMDB_API_KEY v3 API key (needs the short application form).
|
| 12 |
+
TMDB_REGION optional, default "IN".
|
| 13 |
+
MOVIES_MOCK=1 force the curated fallback (no network).
|
| 14 |
+
|
| 15 |
+
With NO credential set, we serve a small CURATED list of titles actually in
|
| 16 |
+
Indian theatres (refresh it periodically, or set a token for a live feed).
|
| 17 |
"""
|
| 18 |
|
| 19 |
import os
|
|
|
|
| 22 |
_NOW_PLAYING = "https://api.themoviedb.org/3/movie/now_playing"
|
| 23 |
|
| 24 |
|
| 25 |
+
def _read_token() -> str:
|
| 26 |
+
return os.getenv("TMDB_READ_TOKEN", "")
|
| 27 |
+
|
| 28 |
+
|
| 29 |
def is_live() -> bool:
|
| 30 |
+
return bool(_read_token() or os.getenv("TMDB_API_KEY")) and os.getenv("MOVIES_MOCK") != "1"
|
| 31 |
|
| 32 |
|
| 33 |
def now_playing(limit: int = 24) -> List[Dict]:
|
| 34 |
+
"""Current theatrical releases, most popular first. Falls back to the
|
| 35 |
+
curated list when no credential is configured."""
|
| 36 |
if not is_live():
|
| 37 |
+
return _curated()
|
| 38 |
import httpx
|
| 39 |
+
region = os.getenv("TMDB_REGION", "IN")
|
| 40 |
+
params = {"region": region, "language": "en-US", "page": 1}
|
| 41 |
+
headers = {}
|
| 42 |
+
if _read_token():
|
| 43 |
+
headers["Authorization"] = f"Bearer {_read_token()}" # v4
|
| 44 |
+
else:
|
| 45 |
+
params["api_key"] = os.environ["TMDB_API_KEY"] # v3
|
| 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() # never break the dropdown
|
| 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,
|
| 62 |
+
# or set TMDB_READ_TOKEN / TMDB_API_KEY for an always-current live feed.
|
| 63 |
+
def _curated() -> List[Dict]:
|
| 64 |
return [{"title": t} for t in [
|
| 65 |
+
"Alpha", "Dhamaal 4", "Baby Do Die Do", "The India Story", "Uttejana",
|
| 66 |
+
"Bhooth Bangla", "Welcome to the Jungle",
|
| 67 |
]]
|