Postavte si vlastní databázi filmů z API
amodb je nezávislé API, které mluví protokolem TMDB v3. Filmy, osoby, společnosti, kolekce, klíčová slova i žánry mají číselná ID a odkazují na sebe, takže z něj můžete plnit SQL tabulky a udržovat je aktuální. Tabulky naplňte stránkováním discover, obnovujte je podle stáří a vlastní identifikátory přiřazujte přes find. amodb nemá feed změn, takže obnova je prosté opětovné stažení řádků, které ponecháváte.
Co dostanete:
- Šest propojených typů entit se stálými číselnými ID.
- Stránkování discover pro první načtení: až 20 výsledků na stránku, 500 stránek na dotaz.
- Okna dat premiér v discover, kterými rozdělíte první načtení a vypíšete nové premiéry.
- Vyhledání podle externích ID
imdb_id,tvdb_id,wikidata_idakinopoisk_id.
Jaká data dostanete
Toto je datový model. Každý řádek je jedna tabulka v relační kopii.
| Entita | Čtení | Klíč | Odkazuje na |
|---|---|---|---|
| Film | GET / | id, imdb_id | genres[].id, production_, belongs_ |
| Osoba | GET / | id, imdb_id | Filmy přes / |
| Společnost | GET / | id | Filmy přes with_companies v discover. parent_company je vždy null a description je prázdné |
| Kolekce | GET / | id | parts[], seznam filmů |
| Klíčové slovo | GET / | id | Filmy přes / nebo with_keywords |
| Žánr | GET / | id | genres[].id u filmů |
Vazby mnoho k mnoha potřebují spojovací tabulky: movie_genre, movie_company, movie_keyword a movie_credit. Jako klíč poslední použijte credit_id ze stránky obsazení a štáb. Seznamy polí jsou na stránkách filmy, osoby a kolekce.
Začněte ve 3 krocích
- Porovnejte tři rychlosti požadavků na stránce ceník. Vyšší rychlost zkrátí první načtení, nic jiného se nemění.
- Vytvořte klíč v panelu účtu a držte ho v proměnné prostředí.
- Zavolejte
/3/discover/moviepro jednodenní okno dat premiér a pak načtěte každé ID ze seznamu.
Příklad požadavku
Skript v PHP vypíše filmy vydané včera a dnes přes discover a každý záznam uloží (upsert) do tabulky SQLite. Mezi čteními detailů čeká 3 sekundy, aby zůstal pod 20 požadavky za minutu, po Retry-After zopakuje 429 a maže řádky, jejichž ID nyní vrací 404.
curl -s "https://api.amodb.dev/3/discover/movie?primary_release_date.gte=2026-10-17&primary_release_date.lte=2026-10-18&sort_by=primary_release_date.asc&page=1" \
-H "Authorization: Bearer $AMODB_KEY"<?php
const BASE = 'https://api.amodb.dev/3';
function amodb(string $path, array $query = []): ?array
{
$url = BASE . $path . '?' . http_build_query($query);
for ($attempt = 0; $attempt < 3; $attempt++) {
$retryAfter = 1;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
CURLOPT_HEADERFUNCTION => function ($handle, $line) use (&$retryAfter) {
if (stripos($line, 'Retry-After:') === 0) {
$retryAfter = max(1, (int) trim(substr($line, 12)));
}
return strlen($line);
},
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 429) {
sleep($retryAfter);
continue;
}
if ($status === 404) {
return null;
}
if ($status !== 200) {
throw new RuntimeException("amodb returned $status for $path");
}
return json_decode($body, true);
}
throw new RuntimeException("Still rate limited on $path");
}
$db = new PDO('sqlite:movies.sqlite');
$db->exec('CREATE TABLE IF NOT EXISTS movie (id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, release_date TEXT, raw TEXT)');
$save = $db->prepare('INSERT OR REPLACE INTO movie (id, imdb_id, title, release_date, raw) VALUES (?, ?, ?, ?, ?)');
$drop = $db->prepare('DELETE FROM movie WHERE id = ?');
$from = date('Y-m-d', strtotime('-1 day'));
$to = date('Y-m-d');
$page = 1;
do {
$list = amodb('/discover/movie', [
'primary_release_date.gte' => $from,
'primary_release_date.lte' => $to,
'sort_by' => 'primary_release_date.asc',
'page' => $page,
]);
foreach ($list['results'] as $row) {
$movie = amodb('/movie/' . $row['id'], ['language' => 'en-US']);
if ($movie === null) {
$drop->execute([$row['id']]);
continue;
}
$save->execute([$movie['id'], $movie['imdb_id'] ?? null, $movie['title'], $movie['release_date'] ?? null, json_encode($movie)]);
sleep(3);
}
$page++;
} while ($page <= min($list['total_pages'], 500));Discover vrací řádky seznamu, ne plné záznamy. Toto jsou 2 z 20 výsledků na stránce 1. Ostatní pole načtěte z /3/movie/{id}.
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/siepLRGVjM8yLKppApkD3uSh8Y0.jpg",
"genre_ids": [
35
],
"id": 1800227,
"original_language": "en",
"original_title": "Sly's Pack",
"overview": "Nesmith, Gary, & Tony are smoking weed on the roof of a parking garage, but a...",
"popularity": 0.0071,
"poster_path": "/3HpIWZUI7jmpKZkfZNdchS2WsvN.jpg",
"release_date": "2026-10-17",
"title": "Sly's Pack",
"video": false,
"vote_average": 0,
"vote_count": 0
},
{
"adult": false,
"backdrop_path": null,
"genre_ids": [
99
],
"id": 1800168,
"original_language": "en",
"original_title": "The Good Life",
"overview": "The Good LIfe is based on the best-selling book by Drs. Robert Waldinger and...",
"popularity": 0.0143,
"poster_path": null,
"release_date": "2026-10-17",
"title": "The Good Life",
"video": false,
"vote_average": 0,
"vote_count": 0
}
],
"total_pages": 15,
"total_results": 299
}Plnění a obnova tabulek
| Úloha | Volání | Limity |
|---|---|---|
| První načtení | GET /3/discover/movie se sort_by a oknem dat | page 1 až 500, až 20 výsledků na stránku, tedy 10 000 na dotaz. K překonání dělte podle primary_ a .lte. |
| Nové premiéry | GET /3/discover/movie s primary_ nastaveným na poslední běh a GET /3/movie/upcoming | Cache 30 minut. |
| Obnova řádků | GET / pro řádky starší než 6 hodin | Neexistuje feed změn. Obnovujte tituly, které uživatelé otevírají, a ostatní méně často. |
| Spojení vlastních ID | GET / | Jedno ID na volání, zdroj se volí přes external_source. |
| Líné plnění | GET /, když uživatel otevře titul | Odpověď uložte s časovým razítkem. |
Okno stránkování je hlavní návrhové rozhodnutí. Když je total_pages v odpovědi nad 500, okno obsahuje víc než 10 000 řádků, rozpůlte ho tedy, dokud se nevejde. Poslední rok potřebuje měsíce a jeden den premiér jsou několik set titulů. Ukládejte dokončený úsek, aby se spadlý běh mohl obnovit. Pravidla párování pro spojení jsou na stránce hledání podle externího ID.
Dimenzování synchronizace
Každý obnovovaný řádek stojí jedno čtení detailu. Tarif s 20 požadavky za minutu dává 1 200 volání za hodinu, 40 dává 2 400 a 120 dává 7 200. Stránka discover vypíše 20 ID za jedno volání. Obnovu pouštějte mimo špičku, pokud aplikace sdílí klíč, protože limit platí na klíč, ne na skript. Hlavičky, které hlásí, co v okně zbývá, jsou na stránce limity požadavků.
Cache ve dvou vrstvách
| Vrstva | Obsahuje | TTL |
|---|---|---|
| Cache na edge | Detaily a obsazení | 6 hodin |
| Cache na edge | Seznamy discover, trending a populární | 30 minut |
| Cache na edge | Vyhledávání | 10 minut |
| Cache na edge | Konfigurace | 24 hodin |
| Cache na edge | Obrázky | 30 dní |
| Vaše tabulky | Řádky, které ponecháváte | Dokud pravidlo stáří neřekne znovu načíst, nikdy dřív než za 6 hodin |
Cache na edge je sdílená mezi klíči, ale limit požadavků se vyhodnocuje před ní, takže zásah cache stále spotřebuje jeden požadavek z vaší minuty. Čtení řádku častěji než každých 6 hodin vrátí stejnou kopii a plýtvá kvótou. O novém načtení nechte rozhodnout pravidlo stáří.
Jak si stojí v porovnání
| Schopnost | Scrapování stránek vlastními silami | Statické soubory datasetu | amodb |
|---|---|---|---|
| Aktuálnost | Tak čerstvé jako poslední crawl | Tak čerstvé jako poslední zveřejněný soubor | Detaily v cache 6 hodin, obnova podle stáří |
| Přírůstkové aktualizace | Znovu procházet a porovnávat | Stáhnout nový soubor | Discover s oknem dat premiér, bez feedu změn |
| ID napříč entitami | URL stránek | Určuje vydavatel | Číselná ID, imdb_id a /3/find |
| Co provozujete | Crawlery a úložiště | Úložiště a importní úloha | Úložiště a synchronizační skript |
| Limit požadavků | Určují weby, které procházíte | Netýká se | 20, 40 nebo 120 požadavků za minutu, počítáno na klíč |
| Jazyky na záznam | Co nabízí která stránka | Záleží na souborech | 14, vybírané přes language |
Ceník
Nákladné je první načtení a omezuje ho váš počet požadavků za minutu. Vyberte 20, 40 nebo 120 za minutu na stránce ceník. Platíte za 1, 3, 6, 12 nebo 24 měsíců se slevou 0, 10, 20, 30 nebo 40 procent. Nic se neobnovuje automaticky, bezplatný tarif neexistuje a každý tarif čte stejná data.