animedex.backends.jikan.models

Rich Jikan dataclasses (one per response shape).

Jikan exposes ~91 endpoints. Many share response shapes (every /anime/{id}/... returning a list of records uses the same row type). the high-level backend layer captures distinct shapes once and reuses them across endpoints; the mapper layer picks the right shape per call.

The JikanAnime to_common() projects MAL data onto Anime, including a duration parser (“24 min per ep” → 24), an aired ISO-string parser, and a status normaliser (“Currently Airing” → “airing”).

JikanImageJpg

class animedex.backends.jikan.models.JikanImageJpg(*, image_url: str | None = None, small_image_url: str | None = None, large_image_url: str | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

image_url: str | None
small_image_url: str | None
large_image_url: str | None

JikanImages

class animedex.backends.jikan.models.JikanImages(*, jpg: JikanImageJpg | None = None, webp: JikanImageJpg | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

jpg: JikanImageJpg | None
webp: JikanImageJpg | None

JikanTrailerImages

class animedex.backends.jikan.models.JikanTrailerImages(*, image_url: str | None = None, small_image_url: str | None = None, medium_image_url: str | None = None, large_image_url: str | None = None, maximum_image_url: str | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

image_url: str | None
small_image_url: str | None
medium_image_url: str | None
large_image_url: str | None
maximum_image_url: str | None

JikanTrailer

class animedex.backends.jikan.models.JikanTrailer(*, youtube_id: str | None = None, url: str | None = None, embed_url: str | None = None, images: JikanTrailerImages | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

youtube_id: str | None
url: str | None
embed_url: str | None
images: JikanTrailerImages | None

JikanTitleEntry

class animedex.backends.jikan.models.JikanTitleEntry(*, type: str, title: str, **extra_data: Any)[source]

Bases: BackendRichModel

type: str
title: str

JikanAiredProp

class animedex.backends.jikan.models.JikanAiredProp(*, day: int | None = None, month: int | None = None, year: int | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

day: int | None
month: int | None
year: int | None

JikanAiredFromTo

class animedex.backends.jikan.models.JikanAiredFromTo(*, from_: JikanAiredProp | None = None, to: JikanAiredProp | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

aired.prop / published.prop sub-block.

from is a Python keyword, so it’s stored as from_ with alias="from". populate_by_name=True (inherited from BackendRichModel) lets pydantic accept either name on input; model_dump(by_alias=True) re-emits from.

from_: JikanAiredProp | None
to: JikanAiredProp | None

JikanAired

class animedex.backends.jikan.models.JikanAired(*, from_: str | None = None, to: str | None = None, prop: JikanAiredFromTo | None = None, string: str | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

aired / published block on Jikan anime / manga.

from_: str | None
to: str | None
prop: JikanAiredFromTo | None
string: str | None

JikanBroadcast

class animedex.backends.jikan.models.JikanBroadcast(*, day: str | None = None, time: str | None = None, timezone: str | None = None, string: str | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

day: str | None
time: str | None
timezone: str | None
string: str | None

JikanEntity

class animedex.backends.jikan.models.JikanEntity(*, mal_id: int, type: str | None = None, name: str | None = None, url: str | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

Generic { mal_id, type, name, url } entity reference used across Jikan responses (producers, licensors, studios, genres, themes, etc.).

Some upstream rows omit name for archival entries; the field is left Optional so the mapper tolerates them rather than raising mid-replay.

mal_id: int
type: str | None
name: str | None
url: str | None

JikanThemes

class animedex.backends.jikan.models.JikanThemes(*, openings: List[str] = [], endings: List[str] = [], **extra_data: Any)[source]

Bases: BackendRichModel

openings: List[str]
endings: List[str]

JikanExternal

class animedex.backends.jikan.models.JikanExternal(*, name: str, url: str | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

name: str
url: str | None

JikanRelation

class animedex.backends.jikan.models.JikanRelation(*, relation: str, entry: List[JikanEntity] = [], **extra_data: Any)[source]

Bases: BackendRichModel

relation: str
entry: List[JikanEntity]

JikanAnime

class animedex.backends.jikan.models.JikanAnime(*, mal_id: int, url: str | None = None, images: JikanImages | None = None, trailer: JikanTrailer | None = None, approved: bool | None = None, titles: List[JikanTitleEntry] = [], title: str | None = None, title_english: str | None = None, title_japanese: str | None = None, title_synonyms: List[str] = [], type: str | None = None, source: str | None = None, episodes: int | None = None, status: str | None = None, airing: bool | None = None, aired: JikanAired | None = None, duration: str | None = None, rating: str | None = None, score: float | None = None, scored_by: int | None = None, rank: int | None = None, popularity: int | None = None, members: int | None = None, favorites: int | None = None, synopsis: str | None = None, background: str | None = None, season: str | None = None, year: int | None = None, broadcast: JikanBroadcast | None = None, producers: List[JikanEntity] = [], licensors: List[JikanEntity] = [], studios: List[JikanEntity] = [], genres: List[JikanEntity] = [], explicit_genres: List[JikanEntity] = [], themes: List[JikanEntity] = [], demographics: List[JikanEntity] = [], relations: List[JikanRelation] = [], theme: JikanThemes | None = None, external: List[JikanExternal] = [], streaming: List[JikanExternal] = [], source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

Full Jikan /anime/{id}/full response payload (rich).

mal_id: int
url: str | None
images: JikanImages | None
trailer: JikanTrailer | None
approved: bool | None
titles: List[JikanTitleEntry]
title: str | None
title_english: str | None
title_japanese: str | None
title_synonyms: List[str]
type: str | None
source: str | None
episodes: int | None
status: str | None
airing: bool | None
aired: JikanAired | None
duration: str | None
rating: str | None
score: float | None
scored_by: int | None
rank: int | None
popularity: int | None
members: int | None
favorites: int | None
synopsis: str | None
background: str | None
season: str | None
year: int | None
broadcast: JikanBroadcast | None
producers: List[JikanEntity]
licensors: List[JikanEntity]
studios: List[JikanEntity]
genres: List[JikanEntity]
explicit_genres: List[JikanEntity]
themes: List[JikanEntity]
demographics: List[JikanEntity]
relations: List[JikanRelation]
theme: JikanThemes | None
external: List[JikanExternal]
streaming: List[JikanExternal]
source_tag: SourceTag
to_common() Anime[source]

JikanManga

class animedex.backends.jikan.models.JikanManga(*, mal_id: int, url: str | None = None, images: JikanImages | None = None, approved: bool | None = None, titles: List[JikanTitleEntry] = [], title: str, title_english: str | None = None, title_japanese: str | None = None, title_synonyms: List[str] = [], type: str | None = None, chapters: int | None = None, volumes: int | None = None, status: str | None = None, publishing: bool | None = None, published: JikanAired | None = None, score: float | None = None, scored_by: int | None = None, rank: int | None = None, popularity: int | None = None, members: int | None = None, favorites: int | None = None, synopsis: str | None = None, background: str | None = None, authors: List[JikanEntity] = [], serializations: List[JikanEntity] = [], genres: List[JikanEntity] = [], explicit_genres: List[JikanEntity] = [], themes: List[JikanEntity] = [], demographics: List[JikanEntity] = [], relations: List[JikanRelation] = [], external: List[JikanExternal] = [], source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

/manga/{id}/full response. Same shape as JikanAnime minus a few anime-specific fields plus chapter/volume counts.

mal_id: int
url: str | None
images: JikanImages | None
approved: bool | None
titles: List[JikanTitleEntry]
title: str
title_english: str | None
title_japanese: str | None
title_synonyms: List[str]
type: str | None
chapters: int | None
volumes: int | None
status: str | None
publishing: bool | None
published: JikanAired | None
score: float | None
scored_by: int | None
rank: int | None
popularity: int | None
members: int | None
favorites: int | None
synopsis: str | None
background: str | None
authors: List[JikanEntity]
serializations: List[JikanEntity]
genres: List[JikanEntity]
explicit_genres: List[JikanEntity]
themes: List[JikanEntity]
demographics: List[JikanEntity]
relations: List[JikanRelation]
external: List[JikanExternal]
source_tag: SourceTag

JikanCharacterAnimeRole

class animedex.backends.jikan.models.JikanCharacterAnimeRole(*, role: str | None = None, anime: JikanEntity | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

role: str | None
anime: JikanEntity | None

JikanCharacterMangaRole

class animedex.backends.jikan.models.JikanCharacterMangaRole(*, role: str | None = None, manga: JikanEntity | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

role: str | None
manga: JikanEntity | None

JikanCharacterVoiceActor

class animedex.backends.jikan.models.JikanCharacterVoiceActor(*, language: str | None = None, person: JikanEntity | None = None, **extra_data: Any)[source]

Bases: BackendRichModel

language: str | None
person: JikanEntity | None

JikanCharacter

class animedex.backends.jikan.models.JikanCharacter(*, mal_id: int, url: str | None = None, images: JikanImages | None = None, name: str, name_kanji: str | None = None, nicknames: List[str] = [], favorites: int | None = None, about: str | None = None, anime: List[JikanCharacterAnimeRole] = [], manga: List[JikanCharacterMangaRole] = [], voices: List[JikanCharacterVoiceActor] = [], source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

/characters/{id}/full and /characters/{id}.

mal_id: int
url: str | None
images: JikanImages | None
name: str
name_kanji: str | None
nicknames: List[str]
favorites: int | None
about: str | None
anime: List[JikanCharacterAnimeRole]
manga: List[JikanCharacterMangaRole]
voices: List[JikanCharacterVoiceActor]
source_tag: SourceTag
to_common() Character[source]

JikanPerson

class animedex.backends.jikan.models.JikanPerson(*, mal_id: int, url: str | None = None, website_url: str | None = None, images: JikanImages | None = None, name: str, given_name: str | None = None, family_name: str | None = None, alternate_names: List[str] = [], birthday: str | None = None, favorites: int | None = None, about: str | None = None, source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

/people/{id}/full and /people/{id}.

mal_id: int
url: str | None
website_url: str | None
images: JikanImages | None
name: str
given_name: str | None
family_name: str | None
alternate_names: List[str]
birthday: str | None
favorites: int | None
about: str | None
source_tag: SourceTag

JikanProducer

class animedex.backends.jikan.models.JikanProducer(*, mal_id: int, url: str | None = None, titles: List[JikanTitleEntry] = [], images: JikanImages | None = None, favorites: int | None = None, established: str | None = None, about: str | None = None, count: int | None = None, external: List[JikanExternal] = [], source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

mal_id: int
url: str | None
titles: List[JikanTitleEntry]
images: JikanImages | None
favorites: int | None
established: str | None
about: str | None
count: int | None
external: List[JikanExternal]
source_tag: SourceTag

JikanMagazine

class animedex.backends.jikan.models.JikanMagazine(*, mal_id: int, name: str, url: str | None = None, count: int | None = None, source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

mal_id: int
name: str
url: str | None
count: int | None
source_tag: SourceTag

JikanGenre

class animedex.backends.jikan.models.JikanGenre(*, mal_id: int, name: str, url: str | None = None, count: int | None = None, source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

mal_id: int
name: str
url: str | None
count: int | None
source_tag: SourceTag

JikanClub

class animedex.backends.jikan.models.JikanClub(*, mal_id: int, name: str, url: str | None = None, images: JikanImages | None = None, members: int | None = None, category: str | None = None, created: str | None = None, access: str | None = None, source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

mal_id: int
name: str
url: str | None
images: JikanImages | None
members: int | None
category: str | None
created: str | None
access: str | None
source_tag: SourceTag

JikanUser

class animedex.backends.jikan.models.JikanUser(*, mal_id: int | None = None, username: str, url: str | None = None, images: JikanImages | None = None, last_online: str | None = None, gender: str | None = None, birthday: str | None = None, location: str | None = None, joined: str | None = None, about: str | None = None, source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

mal_id: int | None
username: str
url: str | None
images: JikanImages | None
last_online: str | None
gender: str | None
birthday: str | None
location: str | None
joined: str | None
about: str | None
source_tag: SourceTag

JikanGenericRow

class animedex.backends.jikan.models.JikanGenericRow(**extra_data: Any)[source]

Bases: BackendRichModel

Pydantic-loose row used by long-tail endpoints (news, forum, pictures, statistics, moreinfo, recommendations, userupdates, reviews, relations, themes, external, streaming, episodes, videos, schedules, watch, recommendations).

Allows arbitrary upstream fields by setting extra='allow'.

model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'frozen': True, 'populate_by_name': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

JikanGenericResponse

class animedex.backends.jikan.models.JikanGenericResponse(*, rows: List[JikanGenericRow] = [], pagination: JikanGenericRow | None = None, source_tag: SourceTag, **extra_data: Any)[source]

Bases: BackendRichModel

Wrapper for any Jikan endpoint whose payload is too large / unstable to map field-by-field. Carries the parsed data array as a list of permissive rows + the source tag.

Use sites: /anime/{id}/news, /anime/{id}/forum, /anime/{id}/videos, /anime/{id}/pictures, /anime/{id}/statistics, /anime/{id}/moreinfo, /anime/{id}/recommendations, /anime/{id}/userupdates, /anime/{id}/reviews, /anime/{id}/relations, /anime/{id}/themes, /anime/{id}/external, /anime/{id}/streaming, /anime/{id}/episodes, schedules, watch endpoints, club sub-endpoints, user sub-endpoints, recommendations, reviews, top-reviews, etc.

rows: List[JikanGenericRow]
pagination: JikanGenericRow | None
source_tag: SourceTag

selftest

animedex.backends.jikan.models.selftest() bool[source]

Smoke-test every Jikan dataclass.