nyanimedb/modules/anime_etl/sources/anilist_async_client.py
2025-12-03 19:59:58 +03:00

47 lines
1.3 KiB
Python

import httpx
import asyncio
from rate_limiter import ANILIST_RATE_LIMITER
URL = "https://graphql.anilist.co"
QUERY = """
query ($search: String, $season: MediaSeason, $seasonYear: Int, $format: MediaFormat, $page: Int, $perPage: Int) {
Page(page: $page, perPage: $perPage) {
media(search: $search, type: ANIME, season: $season, seasonYear: $seasonYear, format: $format) {
id
title { romaji english native }
status
season
seasonYear
format
episodes
duration
popularity
averageScore
coverImage { extraLarge large }
genres
studios(isMain: true) { nodes { id name } }
nextAiringEpisode { episode }
}
}
}
"""
CLIENT = httpx.AsyncClient(timeout=15.0)
async def _post(payload: dict) -> dict:
for i in range(5):
await ANILIST_RATE_LIMITER.acquire()
try:
r = await CLIENT.post(URL, json=payload)
r.raise_for_status()
return r.json()
except Exception:
await asyncio.sleep(1 * 2**i)
raise RuntimeError("AniList unreachable")
async def search_raw(filters: dict) -> list[dict]:
payload = {"query": QUERY, "variables": filters}
data = await _post(payload)
return data.get("data", {}).get("Page", {}).get("media") or []