Anilist extractor added

This commit is contained in:
garaev kamil 2025-12-02 01:15:58 +03:00
parent df188cb531
commit e11c5aec00
2 changed files with 81 additions and 0 deletions

View file

@ -0,0 +1,46 @@
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
# seasonNumber
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 []

View file

@ -0,0 +1,35 @@
from mappers.anilist_filters import to_anilist_filters
from sources.anilist_async_client import search_raw
from normalizers.anilist_normalizer import normalize_media
import asyncio
import pprint
class AniListSource:
async def search(self, local_filters: dict) -> list:
ani_filters = to_anilist_filters(local_filters)
raw_list = await search_raw(ani_filters)
return [normalize_media(r) for r in raw_list]
async def _demo() -> None:
src = AniListSource()
filters = {
"query": "monogatari",
# "year": 2017,
# "season": "winter",
# "type": "tv",
# "limit": 5,
}
print("Запускаю поиск с фильтрами:", filters)
titles = await src.search(filters)
print("Найдено тайтлов:", len(titles))
for t in titles:
# t.title_names — dict[str, list[str]]
# en = (t.title_names.get("en") or [""])[0]
# print("-", en, "|", t.release_year, t.release_season)
pprint.pprint(t)
if __name__ == "__main__":
asyncio.run(_demo())