Шкалы настроения
GET /3/movie/{movie_id}/moods и GET /3/tv/{tv_id}/moods возвращают source и список results. Каждый результат содержит название настроения, например fear или humor, значение avg по шкале от 0 до 10 и данные, на которых оно основано. Добавьте append_to_response=moods к запросу деталей, чтобы получить шкалы без второго запроса.
Получение шкал настроения фильма
GET / возвращает шкалы настроения одного фильма. Шкала настроения состоит из названия и среднего значения по шкале от 0 до 10. В ответе есть id фильма, source и массив results. Каждый результат содержит name, avg и values.
Пример загружает шкалы для The Dark Knight (ID 155) и выводит их от самой сильной к самой слабой.
curl -sf "https://api.amodb.dev/3/movie/155/moods" \
-H "Authorization: Bearer $AMODB_KEY"const res = await fetch('https://api.amodb.dev/3/movie/155/moods', {
headers: { Authorization: `Bearer ${process.env.AMODB_KEY}` },
});
if (!res.ok) throw new Error(`amodb returned ${res.status}`);
const { source, results } = await res.json();
console.log('source:', source);
for (const m of [...results].sort((a, b) => b.avg - a.avg)) {
console.log(m.name.padEnd(10), m.avg);
}import os
import requests
r = requests.get(
"https://api.amodb.dev/3/movie/155/moods",
headers={"Authorization": f"Bearer {os.environ['AMODB_KEY']}"},
timeout=10,
)
r.raise_for_status()
data = r.json()
print("source:", data.get("source"))
for m in sorted(data["results"], key=lambda m: m["avg"], reverse=True):
print(f"{m['name']:<10} {m['avg']}")<?php
$ch = curl_init('https://api.amodb.dev/3/movie/155/moods');
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");
}
$data = json_decode($body, true);
echo 'source: ', $data['source'] ?? 'none', PHP_EOL;
$results = $data['results'];
usort($results, fn ($a, $b) => $b['avg'] <=> $a['avg']);
foreach ($results as $m) {
printf("%-10s %.1f\n", $m['name'], $m['avg']);
}package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"sort"
"time"
)
type Mood struct {
Name string `json:"name"`
Avg float64 `json:"avg"`
Values []float64 `json:"values"`
}
func main() {
req, _ := http.NewRequest("GET", "https://api.amodb.dev/3/movie/155/moods", 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 body struct {
Source string `json:"source"`
Results []Mood `json:"results"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
panic(err)
}
fmt.Println("source:", body.Source)
sort.Slice(body.Results, func(i, j int) bool { return body.Results[i].Avg > body.Results[j].Avg })
for _, m := range body.Results {
fmt.Printf("%-10s %.1f\n", m.Name, m.Avg)
}
}Параметры
movie_idpathобязателенЧисловой ID фильма, например155.api_keyqueryодин из двухВаш ключ. Используйте его или заголовокAuthorization: Bearer.
Поля ответа
| Поле | Тип | Примечания |
|---|---|---|
id | целое число | ID фильма. |
source | строка или null | measured для данных зрителей, estimated, когда значения выведены из жанров, null, когда у тайтла нет данных. |
results | массив | Шкалы настроения, отсортированные по name. Пуст, если ничего не известно. |
results[].name | строка | Короткое слово в нижнем регистре, например fear. |
results[].avg | число | Среднее по шкале от 0 до 10. Один десятичный знак для измеренных тайтлов, целое число для оцененных. |
results[].values | массив чисел | До 24 значений по той же шкале от 0 до 10. У встреченных измеренных тайтлов их 6, у оцененных 5. |
Сейчас встречаются названия action, fear, humor, pace, profanity, romance, sadness, sex и violence. Не у каждого тайтла есть все девять, поэтому выводите названия из данных, а не из фиксированного списка.
Пример ответа
{
"id": 155,
"source": "measured",
"results": [
{ "name": "action", "avg": 3.9, "values": [3.6, 3.4, 4.2, 4.2, 4.8, 3] },
{ "name": "fear", "avg": 5.2, "values": [3.6, 6, 4.8, 6.4, 6.4, 3.8] },
{ "name": "humor", "avg": 0.9, "values": [2.4, 1.8, 0.4, 0.4, 0, 0.5] }
]
}Список сокращен до 3 из 9 результатов.
Измеренные и оцененные тайтлы
У Fight Club (ID 550) пока нет данных зрителей, поэтому его шкалы выведены из жанров. Каждое значение avg целое, а в values 5 элементов.
{
"id": 550,
"source": "estimated",
"results": [
{ "name": "action", "avg": 4, "values": [3, 4, 5, 4, 3] },
{ "name": "fear", "avg": 7, "values": [6, 7, 8, 7, 6] }
]
}Проверяйте source, если хотите обрабатывать оцененные шкалы иначе, чем измеренные.
Шкалы настроения сериала
GET / возвращает ответ такой же структуры, а ID сериала лежит в id. Для Breaking Bad используйте 1396.
| Метод и путь | Возвращает | Параметры |
|---|---|---|
GET / | id, source и results | movie_id |
GET /tv/{tv_id}/moods | id, source и results | tv_id |
append_ | source и results в ключе moods | Добавляется к деталям фильма или сериала |
curl -sf "https://api.amodb.dev/3/tv/1396?append_to_response=moods" -H "Authorization: Bearer $AMODB_KEY"Когда вы добавляете moods к запросу деталей, ключ moods находится на верхнем уровне записи рядом с title или name. Он содержит source и results и не имеет собственного id. Это стоит один запрос, тогда как два отдельных вызова стоят два.
Как читать шкалу
Поле avg показывает интенсивность от 0 до 10. Чем выше число, тем сильнее настроение в тайтле.
| Диапазон | Как читать |
|---|---|
| От 0 до 2.9 | Настроение слабое или отсутствует. |
| От 3 до 5.9 | Настроение присутствует. |
| От 6 до 7.9 | Настроение выражено явно. |
| От 8 до 10 | Настроение определяет тайтл. |
Диапазоны предлагаются для вашего интерфейса и не являются полем ответа. Массив values содержит значения, из которых получено среднее, по той же шкале.
Бейджи и фильтры
Настроения подходят для трех типичных интерфейсных паттернов. Выберите пороги, подходящие вашему каталогу, и подстройте их.
| Паттерн | Правило | Примечания |
|---|---|---|
| Бейдж | Показывать до 3 настроений с avg 6 и выше | Сначала сортируйте по avg. |
| Полоса шкалы | Ширина полосы в процентах равна avg, умноженному на 10 | Шкала идет от 0 до 10. |
| Чип фильтра | Подбирать тайтлы, у которых выбранное настроение 7 или выше | Получите шкалы для каждого тайтла, затем фильтруйте локально. |
function topMoods(results, min = 6, limit = 3) {
return results
.filter((m) => m.avg >= min)
.sort((a, b) => b.avg - a.avg)
.slice(0, limit)
.map((m) => m.name);
}
function matchesMood(results, name, min = 7) {
return results.some((m) => m.name === name && m.avg >= min);
}Пустой массив results должен отображаться как отсутствие бейджей, а не как ошибка.
Ошибки
Тело ошибки содержит success, status_code и status_message, те же поля, что использует TMDB.
| HTTP | status_code | Когда |
|---|---|---|
| 401 | 7 | Ключ отсутствует или неверен. |
| 402 | 36 | Период тарифа закончился. |
| 429 | 25 | Превышен лимит запросов в минуту. Подождите Retry-After секунд. |
Эндпоинт moods не отвечает 404 на неизвестный ID. Он отвечает 200 с пустым массивом results, а source равен null или отсутствует. При добавлении к деталям неизвестный ID дает 404 от запроса деталей. Полный список ошибок на странице ошибки, а лимиты на странице лимиты запросов.
Практические советы
- Как и остальные данные деталей, шкалы настроения кэшируются на edge на 6 часов. Более частые запросы вернут то же тело ответа.
- Для списка из 20 тайтлов нужно 20 запросов настроений. Если вы уже запрашиваете детали каждого тайтла, добавьте
moodsи сэкономьте второй вызов. - Проверяйте
sourceперед сравнением тайтлов. Измеренные и оцененные значения лежат на одной шкале, но имеют разную точность. - Если вы часто фильтруете, храните
nameиavgвместе с ID тайтла в своей базе. Локальный фильтр лучше запроса на каждый тайтл. - Сочетайте шкалы с рейтингами для оценки и с саундтреками для музыки того же тайтла.