API сезонаў і эпізодаў серыялаў

Адзін сезон з усімі эпізодамі чытаецца праз GET /3/tv/{series_id}/season/{season_number}, а асобны эпізод на ўзровень глыбей. JSON адпавядае TMDB v3 з air_date, episode_number, runtime і still_path. Кожны эпізод мае crew і guest_stars, сезон 0 змяшчае спецвыпускі, а append_to_response дадае credits, images і videos.

Абноўлена Адкрыць у Markdown

Атрыманне сезона

GET /3/tv/{series_id}/season/{season_number} вяртае адзін сезон і поўны масіў episodes за адзін адказ. Нумары сезонаў пачынаюцца з 1, а 0 зарэзерваваны пад спецвыпускі. Id серыяла і нумары сезонаў бярыце з запісу серыялы.

У прыкладзе чытаецца сезон 1 серыяла Breaking Bad. Код друкуе па радку на эпізод.

bashjspyphpgo
curl -sSf "https://api.amodb.dev/3/tv/1396/season/1?language=en-US" \
  -H "Authorization: Bearer $AMODB_KEY"
const url = 'https://api.amodb.dev/3/tv/1396/season/1?language=en-US';
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` } });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const season = await res.json();
for (const ep of season.episodes) {
  console.log(String(ep.episode_number).padStart(2, '0'), ep.name, ep.air_date, `${ep.runtime ?? '?'} min`);
}
import os
import requests

r = requests.get(
    "https://api.amodb.dev/3/tv/1396/season/1",
    params={"language": "en-US"},
    headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
    timeout=10,
)
r.raise_for_status()
season = r.json()
for ep in season["episodes"]:
    print(f"{ep['episode_number']:02d}", ep["name"], ep["air_date"], ep["runtime"] or "?")
<?php
$url = 'https://api.amodb.dev/3/tv/1396/season/1?language=en-US';
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
    throw new RuntimeException("amodb returned $status");
}
$season = json_decode($body, true);
foreach ($season['episodes'] as $ep) {
    printf("%02d %s %s\n", $ep['episode_number'], $ep['name'], $ep['air_date']);
}
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

type Season struct {
	Name     string `json:"name"`
	Episodes []struct {
		EpisodeNumber int    `json:"episode_number"`
		Name          string `json:"name"`
		AirDate       string `json:"air_date"`
		Runtime       int    `json:"runtime"`
	} `json:"episodes"`
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/tv/1396/season/1?language=en-US", nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AMODB_KEY"))
	client := &http.Client{Timeout: 10 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		panic(res.Status)
	}
	var s Season
	if err := json.NewDecoder(res.Body).Decode(&s); err != nil {
		panic(err)
	}
	for _, e := range s.Episodes {
		fmt.Printf("%02d %s %s %d min\n", e.EpisodeNumber, e.Name, e.AirDate, e.Runtime)
	}
}

Параметры

  • series_idшляхабавязковы
    Лікавы id серыяла, напрыклад 1396.
  • season_numberшляхабавязковы
    Цэлы нумар сезона. 0 вяртае спецвыпускі.
  • api_keyзапытадзін з двух
    Ваш ключ. Выкарыстоўвайце яго або загаловак Authorization: Bearer.
  • languageзапыт
    Тэг TMDB, напрыклад en-US або fr-FR. Падтрымліваюцца 14 базавых моў. Па змаўчанні en-US.
  • append_to_responseзапыт
    Значэнні ўзроўню сезона: credits, external_ids, images, videos. Іншыя назвы ігнаруюцца.

Палі адказу

ПолеТыпЗаўвагі
id, season_numberцэлы лікId сезона і яго нумар у межах серыяла.
name, overviewрадокЛакалізаваны тэкст, пусты, калі перакладу няма.
air_dateрадок або nullДата першага эпізода, YYYY-MM-DD.
poster_pathрадок або nullДадайце да https://img.amodb.dev/t/p/{size}.
vote_averageлікЗводная ацэнка карыстальнікаў для сезона.
episodesмасіўУсе эпізоды з палямі, пералічанымі ў наступным раздзеле.

Прыклад адказу

GET /3/tv/1396/season/1?language=en-US. У сезоне 7 эпізодаў, таму episodes скарочаны да аднаго запісу, а масівы crew і guest_stars гэтага запісу прапушчаны:

JSON
{
  "air_date": "2008-01-20",
  "episodes": [
    {
      "air_date": "2008-01-20",
      "episode_number": 1,
      "episode_type": "standard",
      "id": 62085,
      "name": "Pilot",
      "overview": "When an unassuming high school chemistry teacher discovers he has a rare form of lung cancer, he decides to...",
      "production_code": "",
      "runtime": 59,
      "season_number": 1,
      "show_id": 1396,
      "still_path": "/ydlY3iPfeOAvu8gVqrxPoMvzNCn.jpg",
      "vote_average": 0,
      "vote_count": 0
    }
  ],
  "name": "Season 1",
  "overview": "High school chemistry teacher Walter White's life is suddenly transformed by a dire medical diagnosis. Stre...",
  "id": 3572,
  "poster_path": "/91EIXdWxmp2mHNRsSuDW3WyDJLj.jpg",
  "season_number": 1,
  "vote_average": 0
}

Кожны эпізод у адказе па сезоне таксама нясе масівы crew і guest_stars з формай запісу, апісанай на старонцы удзельнікі. runtime можа быць null для эпізода, які яшчэ не выйшаў.

Атрыманне эпізода

GET /3/tv/{series_id}/season/{season_number}/episode/{episode_number} вяртае адзін эпізод. Адказ па сезоне ўжо ўтрымлівае кожны эпізод з crew і guest_stars, таму выкарыстоўвайце гэты эндпоінт, каб абнавіць адзін запіс без перазагрузкі сезона. Ён прымае language і append_to_response са значэннямі credits, external_ids, images, translations і videos. Запыт /3/tv/1396/season/1/episode/1?append_to_response=credits каштуе адзін запыт.

ПолеТыпЗаўвагі
idцэлы лікId эпізода.
show_idцэлы лікId серыяла. Ёсць у адказе па сезоне і ў спасылках серыяла, але не ў адказе па асобным эпізодзе.
season_number, episode_numberцэлы лікМесца ў серыяле. Выкарыстоўвайце іх, каб скласці шлях запыту.
name, overviewрадокЛакалізаваны тэкст.
air_dateрадок або nullТолькі дата, без часу і гадзіннага пояса. Null, калі эпізод не запланаваны.
episode_typeрадокstandard для звычайных эпізодаў. Каб заўважыць фінал, параўнайце episode_number з episode_count гэтага сезона ў запісе серыяла.
runtimeцэлы лік або nullХвіліны.
production_codeрадокКод студыі, часта пусты.
still_pathрадок або nullКадр эпізода. Выкарыстоўвайце w300 або original з https://img.amodb.dev/t/p/{size}.
vote_average, vote_countлік, цэлы лікЗводная ацэнка карыстальнікаў.
crew, guest_starsмасіўУдзельнікі гэтага эпізода, гл. удзельнікі.

Наступны і апошні эпізод у запісе серыяла

Эндпоінт серыяла вяртае next_episode_to_air і last_episode_to_air. Кожны з іх уяўляе сабой кароткае апісанне эпізода з вышэйпаказанымі палямі, плюс show_id, але без crew і guest_stars. Наступны роўны null для завершаных серыялаў і для тых, што працягваюцца, але без пацверджанай даты. У прыкладзе чытаецца South Park, серыял, які працягваецца.

JavaScript
const headers = { Authorization: `Bearer ${process.env.AMODB_KEY}` };
const res = await fetch('https://api.amodb.dev/3/tv/2190', { headers });
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const next = (await res.json()).next_episode_to_air;
console.log(next ? `Next: S${next.season_number}E${next.episode_number} on ${next.air_date}` : 'No upcoming episode');

Для зваротнага адліку параўноўвайце air_date з мясцовай датай гледача. Значэнне не нясе часу сутак, таму паказвайце дату, а не гадзіну.

Падрэсурсы сезона і эпізода

Шляхі сезона і эпізода маюць уласныя падрэсурсы. Некалькі з іх сёння вяртаюць пустыя даныя.

Метад і шляхШто вяртае
GET /tv/{series_id}/season/{season_number}/creditsid, cast і crew для сезона
GET /tv/{series_id}/season/{season_number}/imagesid і пусты масіў posters
GET /tv/{series_id}/season/{season_number}/videosid і пусты масіў results
GET /tv/{series_id}/season/{season_number}/external_idsid плюс tvdb_id, wikidata_id і іншыя id, усе null
GET /tv/{series_id}/season/{season_number}/translationsid і пусты масіў translations
GET .../episode/{episode_number}/creditsid, пусты cast, crew і guest_stars
GET .../episode/{episode_number}/imagesid і масіў stills з кадрам эпізода
GET .../episode/{episode_number}/videosid і пусты масіў results
GET .../episode/{episode_number}/external_idsid плюс imdb_id, tvdb_id і іншыя id, усе null
GET .../episode/{episode_number}/translationsid і масіў translations з назвай і апісаннем для кожнай мовы

Удзельнікі сезона і эпізода апісаны на старонцы удзельнікі, а кадры на старонцы выявы. amodb не прапануе шляхі TMDB changes і эндпоінт для эпізодаў адной групы эпізодаў.

Памылкі

HTTPstatus_codeКалі
4017Ключ адсутнічае або няправільны.
40236Тэрмін дзеяння плана скончыўся.
40434Серыяла, сезона або эпізода не існуе, напрыклад сезон 0 у серыяла без спецвыпускаў, або шлях не падтрымліваецца.
40537Вы выклікалі метад запісу.
42925Перавышаны ліміт запытаў у хвіліну. Пачакайце Retry-After секунд.

Поўны фармат цела гл. на старонцы памылкі, а акны лімітаў на старонцы ліміты запытаў.

Практычныя заўвагі

  • Сезоны і эпізоды кэшуюцца на 6 гадзін. Пакуль серыял выходзіць, перачытвайце бягучы сезон раз-два на дзень.
  • Серыялу з 10 сезонамі патрэбна 10 выклікаў сезонаў. На плане з 20 запытаў у хвіліну гэта палова хвіліннага ліміту, а паўторны запуск на працягу 6 гадзін абслугоўваецца з edge-кэшу.
  • Эпізод, які не выйшаў, можа мець air_date роўны null, runtime роўны null і пусты overview. Паказвайце запаўняльнік замест таго, каб падаць з памылкай.
  • Кадры гэта шырокія выявы, а не постэры. Запытвайце w300 для спісаў і original толькі тады, калі патрэбен прагляд поўнага памеру.