Add full-catalog bulk import from TMDb's daily ID exports
CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
app/services/bulk_import.py fetches and parses TMDb's daily ID export files (published once a day specifically for full-catalog sync, unlike /discover which caps at 10,000 results per query) -- today's file with a fallback to yesterday's, since TMDb publishes at a fixed time and "today's" may not exist yet. app/scripts/bulk_import.py is a standalone ops script (not an arq task, since enqueueing millions of jobs would blow past arq's job_timeout) that fans every id from the export into the existing per-entity ingestion pipeline -- get_or_create_ingestion_job + the same arq task each admin endpoint already uses, so a single id's behavior is identical whether it came from the admin API or this script. Bounded concurrency (50) on the enqueue phase; idempotency-keyed jobs make interrupting and re-running the script safe. Real TMDb catalog size (checked live): ~1.24M movies, 231K series, 4.9M people, 9.8K collections -- ~6.4M entities. At default worker concurrency this is realistically weeks of continuous processing, not hours, documented as such in README.md. Also added 429 (rate-limited) handling to TMDbProvider before running this at volume: previously a 429 fell into the generic >=400 branch and failed the request outright with zero retry, since only httpx.TransportError triggered the existing retry decorator. Now a 429 raises ProviderRateLimitedError carrying the response's own Retry-After hint, and tenacity's wait strategy honors that hint directly instead of guessing via exponential backoff. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
39b2d4bfcd
commit
a52ac676ff
@@ -107,6 +107,40 @@ Ingesting a series also queues its posters/backdrops/profile images for
|
||||
local download automatically (only the provider's *primary* image per
|
||||
entity, not every alternate) — see the next section.
|
||||
|
||||
### Bulk-importing TMDb's entire catalog
|
||||
|
||||
`app/scripts/bulk_import.py` enqueues an ingestion job for every id in
|
||||
TMDb's [daily ID export files](https://developer.themoviedb.org/docs/daily-id-exports)
|
||||
(published once a day specifically for full-catalog sync, unlike
|
||||
`/discover`, which caps at 10,000 results per query) — the same
|
||||
one-id-at-a-time pipeline the admin endpoints above use, just enqueued for
|
||||
every id TMDb has rather than one at a time by hand:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml exec worker \
|
||||
python -m app.scripts.bulk_import movie series person collection
|
||||
```
|
||||
|
||||
As of 2026-09, TMDb's real catalog is roughly 1.24M movies, 231K TV
|
||||
series, 4.9M people, and 9.8K collections — **~6.4M entities total**. At
|
||||
this project's default worker concurrency (`WORKER_CONCURRENCY=4` × 2
|
||||
worker replicas), expect this to run for **on the order of weeks**, not
|
||||
hours — it does not rate-limit itself against TMDb; TMDb's request rate is
|
||||
governed entirely by how many workers are consuming the queue
|
||||
concurrently (raise `WORKER_CONCURRENCY` / scale up workers to go faster,
|
||||
mindful of TMDb's own rate limits — `app/providers/tmdb.py` backs off on a
|
||||
429 using TMDb's own `Retry-After` hint, but sustained high concurrency
|
||||
will still see more of them). Run it detached
|
||||
(`docker compose ... exec -d worker ...`, or under `nohup`/`tmux`/`screen`)
|
||||
so it survives a disconnect, and use `--dry-run` first to see counts
|
||||
without enqueueing anything. Re-running (e.g. after an interruption) is
|
||||
safe — every id is idempotency-keyed, so already-created jobs are reused,
|
||||
never duplicated.
|
||||
|
||||
Expect substantial disk usage from artwork self-hosting cascading on
|
||||
every successful ingestion (see the next section) at this scale — budget
|
||||
accordingly before running it against the full catalog.
|
||||
|
||||
## Artwork
|
||||
|
||||
Images are referenced by their provider CDN URL (TMDb) from the moment
|
||||
|
||||
Reference in New Issue
Block a user