III — MANGALIB-PYTHON-SDK · MANGALIB

    mangalib API reference

    Текст страницы — оригинал из репозитория SDK, на английском. Исходный файл ↗

    mangalib-python-sdk (import mangalib): the SDK for mangalib.me, on the same libsocial-core as ranobelib. Chapters are page images rather than text. What the API returns for MangaLib is in API notes.

    Entry point

    mangalib.MangaLib

    класс
    MangaLib(
        url: str,
        *,
        cache_dir: str | Path | None = None,
        cache_ttl: float | None = None,
        verbosity: Verbosity = False,
        headers: Mapping[str, str] | None = None,
    )

    Базовые классы TitleClient[Title, Chapter, Volume]

    Entry point for interacting with a single mangalib.me title.

    Closed chapters (paid, or in early access) can't be read without an account, which the SDK doesn't support: get_chapter() raises AuthRequiredError for one, while download_title() and estimate_title_size() leave out every translation the chapter list marks as closed (ChapterBranch.is_open) — a chapter with only closed ones is skipped, and translation_index counts the open translations only.

    ИСХОДНИК ↗

    slug_url

    атрибутсвойство
    slug_url: str

    The title's {id}--{slug} identifier.

    ИСХОДНИК ↗

    aclose

    методasync
    aclose() -> None

    Close the underlying HTTP clients.

    ИСХОДНИК ↗

    chapter_size

    методasync
    chapter_size(
        chapter: Chapter,
        *,
        server: str | None = None,
        concurrency: int = DEFAULT_IMAGE_CONCURRENCY,
    ) -> int

    The exact size in bytes of a fetched chapter's page images, without downloading them.

    One HEAD request per page: the image servers answer it with the file's exact Content-Length (see docs/api-notes.md, "MangaLib"), so this costs requests, not image traffic. Servers are tried, paced and retried as in download_page().

    Параметры

    ИмяТипОписаниеПо умолчанию
    chapterChapter

    A chapter fetched with get_chapter() (or another fetching method).

    serverstr | None

    The ImageServer.id to try first — see download_page().

    None
    concurrencyint

    How many pages to ask about at once.

    DEFAULT_IMAGE_CONCURRENCY

    Исключения

    ТипОписание
    ValueError

    If chapter has no pages (not fetched), server isn't one of list_image_servers(), or concurrency is less than 1.

    PageDownloadError

    If no server gave a page's size.

    ИСХОДНИК ↗

    download_page

    методasync
    download_page(page: Page, *, server: str | None = None) -> bytes

    Download one page image.

    Tries server first, if given, then images.DEFAULT_SERVER_ORDER (compress, download, main, secondary). compress comes first because it's the one that served full-size pages when checked; main/secondary sit behind a DDoS-Guard check scripts don't pass (see docs/api-notes.md, "MangaLib"). Requests to an image host are paced across the process (images.DEFAULT_IMAGE_REQUEST_DELAY), and a 429, a 5xx or a network error is retried with backoff on the same server before moving on to the next one; a refusal (another 4xx, a response that isn't an image) moves on at once.

    Параметры

    ИмяТипОписаниеПо умолчанию
    pagePage

    The page, from a fetched chapter's pages.

    serverstr | None

    The ImageServer.id to try first (see list_image_servers()).

    None

    Возвращает

    ТипОписание
    bytes

    The image file's bytes, as the server sent them.

    Исключения

    ТипОписание
    ValueError

    If server isn't one of list_image_servers().

    PageDownloadError

    If no server served the image.

    ИСХОДНИК ↗

    download_pages

    методasync
    download_pages(
        chapter: Chapter,
        *,
        server: str | None = None,
        concurrency: int = DEFAULT_IMAGE_CONCURRENCY,
    ) -> list[bytes]

    Download every page image of a fetched chapter, in reading order.

    Each page as download_page() does it, up to concurrency at a time.

    Параметры

    ИмяТипОписаниеПо умолчанию
    chapterChapter

    A chapter fetched with get_chapter() (or get_chapters(), get_volume(), ...): one from get_table_of_contents() has no pages.

    serverstr | None

    The ImageServer.id to try first — see download_page().

    None
    concurrencyint

    How many pages to download at once. The pacing per image host applies on top, so more than a few mostly adds waiting.

    DEFAULT_IMAGE_CONCURRENCY

    Исключения

    ТипОписание
    ValueError

    If server isn't one of list_image_servers(), or concurrency is less than 1.

    PageDownloadError

    If a page couldn't be downloaded from any server; the other downloads still in flight are cancelled.

    ИСХОДНИК ↗

    download_title

    методasync
    download_title(
        *,
        branch_id: int | None = None,
        translation_index: int | None = None,
        chapter_delay: float = 0.0,
        on_chapter: Callable[[int, int], None] | None = None,
        max_rate_limit_retries: int = DEFAULT_RATE_LIMIT_RETRIES,
    ) -> list[VolumeT]

    Download every chapter of the title, across all its volumes.

    Fetches the chapter list once, then every chapter's content, sequentially, in the API's own order — same pacing/retry/backoff as any other chapter fetch (see ApiClient), plus chapter_delay on top if given.

    Resolving translations is checked for the whole title up front, not chapter by chapter: if any chapters have more than one translation, this fetches nothing and raises MultipleTitleTranslationsError listing all of them at once (unless branch_id or translation_index resolves every one of them), rather than failing partway through a long download on the first ambiguous chapter.

    A long title's sequential download can outlast ApiClient's own retry budget for 429s (tuned for a single one-off request, not hundreds/thousands of sequential fetches — see docs/api-notes.md). On top of that, each chapter fetch that still comes back rate-limited is retried again here, up to max_rate_limit_retries times, with its own (coarser) backoff. If a chapter fetch still fails after that — from rate limiting or anything else — the chapters already downloaded are not discarded: they're attached to a raised DownloadTitleInterruptedError instead of being lost.

    Параметры

    ИмяТипОписаниеПо умолчанию
    branch_idint | None

    Translation to use for every chapter that has more than one — same meaning as get_chapter(..., branch_id=...), applied title-wide. Chapters with only one translation are unaffected. Mutually exclusive with translation_index.

    None
    translation_indexint | None

    Alternative to branch_id: pick the translation at this position in each ambiguous chapter's branches list (0 for the first, and so on) — useful when ambiguous chapters don't share one branch_id across the title. Mutually exclusive with branch_id.

    None
    chapter_delayfloat

    Extra delay, in seconds, after fetching each chapter, on top of ApiClient's own per-request pacing — to be gentler on the API during a large bulk download. Defaults to no extra delay.

    0.0
    on_chapterCallable[[int, int], None] | None

    Called with (completed, total) after each chapter is fetched, if given — a programmatic progress hook for callers that aren't printing to a console (e.g. a web app polling/streaming download progress to a browser), who would otherwise have no way to observe anything before this whole await returns. Independent of verbosity: both can be set at once, each drives its own output.

    None
    max_rate_limit_retriesint

    How many extra times to retry a single chapter fetch that comes back rate-limited, on top of ApiClient's own retries, before giving up on the whole download — see above. Each retry honors the API's Retry-After if it sent one, otherwise waits with its own capped exponential backoff. Set to 0 to disable this extra layer and let a persistent RateLimitError end the download immediately (still wrapped in DownloadTitleInterruptedError with whatever was already fetched).

    DEFAULT_RATE_LIMIT_RETRIES

    Исключения

    ТипОписание
    ValueError

    If both branch_id and translation_index are given.

    MultipleTitleTranslationsError

    If the title has one or more chapters with more than one translation that branch_id/translation_index didn't resolve.

    DownloadTitleInterruptedError

    If fetching a chapter fails unrecoverably partway through the download — carries every chapter already fetched.

    ИСХОДНИК ↗

    estimate_title_size

    методasync
    estimate_title_size(
        *,
        sample_size: int = DEFAULT_SAMPLE_SIZE,
        branch_id: int | None = None,
        translation_index: int | None = None,
        server: str | None = None,
        concurrency: int = DEFAULT_IMAGE_CONCURRENCY,
    ) -> int

    Estimate the whole title's page images in bytes, from a sample of its chapters.

    Fetches the chapter list, then up to sample_size chapters spread evenly across the title (their page lists, cached like any chapter fetch), sizes their pages exactly with chapter_size() — HEAD requests, no image traffic — and extrapolates the sample's average across every chapter download_title() would download. The chapter list has no page counts, so the sample is what both the page count and the page weight are estimated from.

    Параметры

    ИмяТипОписаниеПо умолчанию
    sample_sizeint

    How many chapters to sample — clamped to how many there are.

    DEFAULT_SAMPLE_SIZE
    branch_idint | None

    Same as download_title(branch_id=...). Mutually exclusive with translation_index.

    None
    translation_indexint | None

    Same as download_title(translation_index=...).

    None
    serverstr | None

    The ImageServer.id to try first — see download_page().

    None
    concurrencyint

    How many pages to ask about at once.

    DEFAULT_IMAGE_CONCURRENCY

    Возвращает

    ТипОписание
    int

    The estimated size in bytes, or 0 if the title has no chapter with an open

    int

    translation that branch_id/translation_index resolves.

    Исключения

    ТипОписание
    ValueError

    If both branch_id and translation_index are given, or if sample_size or concurrency is less than 1.

    ИСХОДНИК ↗

    export

    методasync
    export(
        chapters: Chapter | Volume | Sequence[Chapter | Volume],
        *,
        fmt: str,
        path: str | Path,
        server: str | None = None,
        concurrency: int = DEFAULT_IMAGE_CONCURRENCY,
        on_chapter: Callable[[int, int], None] | None = None,
    ) -> Path

    Export fetched chapters to one file, downloading their page images as it goes.

    One chapter, several, a volume, several, or a whole title — download_title()'s result — all go in: volumes are expanded into their chapters, in order. Pages are downloaded chapter by chapter (as download_pages() does it) and written into the file, which only appears at path once complete.

    Параметры

    ИмяТипОписаниеПо умолчанию
    chaptersChapter | Volume | Sequence[Chapter | Volume]

    Fetched chapters and/or volumes, in the order they should appear.

    fmtstr

    Export format — a key of mangalib.exporters.EXPORTERS: "cbz", and "pdf" when the pdf extra (img2pdf) is installed.

    pathstr | Path

    Where to write the exported file.

    serverstr | None

    The ImageServer.id to try first — see download_page().

    None
    concurrencyint

    How many pages to download at once.

    DEFAULT_IMAGE_CONCURRENCY
    on_chapterCallable[[int, int], None] | None

    Called with (completed, total) after each chapter is written — the same progress hook as download_title(on_chapter=...), independent of verbosity.

    None

    Исключения

    ТипОписание
    ValueError

    If fmt isn't a registered format, there are no chapters, one of them has no pages (not fetched), server isn't one of list_image_servers(), or concurrency is less than 1 — all checked before anything is downloaded.

    PageDownloadError

    If a page couldn't be downloaded from any server. Nothing is written to path then.

    ИСХОДНИК ↗

    get_chapter

    методasync
    get_chapter(
        volume: int,
        number: str,
        *,
        branch_id: int | None = None,
        refresh: bool = False,
    ) -> ChapterT

    Fetch a single chapter, including its content.

    When a chapter has more than one team's translation and branch_id isn't given, this raises MultipleTranslationsError rather than guessing — see get_translations() and docs/api-notes.md for why the API's own default (when branch_id is omitted) isn't relied on. Doing this check costs an extra request to fetch the chapter list, only when branch_id isn't already given.

    Параметры

    ИмяТипОписаниеПо умолчанию
    volumeint

    The chapter's volume number.

    numberstr

    The chapter number, as returned by the API — may contain a decimal (e.g. "51.6").

    branch_idint | None

    Which translation to fetch, as returned by get_translations(). Only required when the chapter has more than one.

    None
    refreshbool

    Bypass the disk cache and re-fetch from the API even if a cached response is on hand.

    False

    Исключения

    ТипОписание
    MultipleTranslationsError

    If the chapter has more than one translation and branch_id wasn't given.

    ИСХОДНИК ↗

    get_chapters

    методasync
    get_chapters(chapters: list[tuple[int, str]]) -> list[ChapterT]

    Fetch several chapters, including their content.

    Fetches the chapter list once, shared across all requested chapters (also used to detect chapters with more than one translation — see get_chapter), then each chapter individually and sequentially, in the order given.

    Параметры

    ИмяТипОписание
    chapterslist[tuple[int, str]]

    A list of (volume, number) pairs identifying each chapter.

    Исключения

    ТипОписание
    ChapterNotFoundError

    If any requested chapter doesn't exist.

    MultipleTranslationsError

    If any requested chapter has more than one translation.

    ИСХОДНИК ↗

    get_info

    методasync
    get_info(*, refresh: bool = False) -> TitleT

    Fetch title metadata: names, cover, summary, genres, tags, authors, teams.

    Параметры

    ИмяТипОписаниеПо умолчанию
    refreshbool

    Bypass the disk cache and re-fetch from the API even if a cached response is on hand.

    False
    ИСХОДНИК ↗

    get_table_of_contents

    методasync
    get_table_of_contents(*, refresh: bool = False) -> list[VolumeT]

    Fetch the title's volumes and chapter names/numbers, without chapter content.

    Параметры

    ИмяТипОписаниеПо умолчанию
    refreshbool

    Bypass the disk cache and re-fetch from the API even if a cached response is on hand — needed to pick up newly published chapters, since otherwise the cached chapter list would keep being reused.

    False
    ИСХОДНИК ↗

    get_translations

    методasync
    get_translations(volume: int, number: str) -> list[ChapterBranch]

    Fetch the available translations (branches) for a chapter.

    Each one says whether it's open to read without an account (ChapterBranch.is_open).

    Параметры

    ИмяТипОписание
    volumeint

    The chapter's volume number.

    numberstr

    The chapter number.

    Исключения

    ТипОписание
    ChapterNotFoundError

    If no chapter exists for this volume/number.

    ИСХОДНИК ↗

    get_volume

    методasync
    get_volume(volume: int) -> VolumeT

    Fetch a whole volume: all its chapters, each including content.

    The API has no bulk "volume content" endpoint (see docs/api-notes.md), so this fetches the chapter list once to find which numbers belong to the volume, then fetches each of those chapters individually and sequentially.

    Параметры

    ИмяТипОписание
    volumeint

    The volume number.

    Исключения

    ТипОписание
    VolumeNotFoundError

    If the title has no chapters for this volume.

    MultipleTranslationsError

    If any of the volume's chapters has more than one translation.

    ИСХОДНИК ↗

    get_volumes

    методasync
    get_volumes(volumes: list[int]) -> list[VolumeT]

    Fetch several whole volumes, each including chapter content.

    Fetches the chapter list once, shared across all requested volumes, then each chapter individually and sequentially — same approach as get_volume, applied to more than one volume without re-fetching the chapter list per volume.

    Параметры

    ИмяТипОписание
    volumeslist[int]

    The volume numbers to fetch.

    Исключения

    ТипОписание
    VolumeNotFoundError

    If the title has no chapters for one of the volumes.

    MultipleTranslationsError

    If any of the volumes' chapters has more than one translation.

    ИСХОДНИК ↗

    list_image_servers

    методasync
    list_image_servers(*, refresh: bool = False) -> list[ImageServer]

    List the servers mangalib.me serves page images from.

    Not every one serves pages to a script: see download_page() for which are tried.

    Параметры

    ИмяТипОписаниеПо умолчанию
    refreshbool

    Bypass the disk cache and re-fetch from the API.

    False
    ИСХОДНИК ↗

    volume_size

    методasync
    volume_size(
        volume: Volume,
        *,
        server: str | None = None,
        concurrency: int = DEFAULT_IMAGE_CONCURRENCY,
    ) -> int

    The exact size in bytes of a fetched volume's page images — chapter_size() summed.

    Параметры

    ИмяТипОписаниеПо умолчанию
    volumeVolume

    A volume fetched with get_volume()/get_volumes()/ download_title().

    serverstr | None

    The ImageServer.id to try first — see download_page().

    None
    concurrencyint

    How many pages to ask about at once.

    DEFAULT_IMAGE_CONCURRENCY

    Исключения

    ТипОписание
    ValueError

    See chapter_size().

    PageDownloadError

    If no server gave a page's size.

    ИСХОДНИК ↗

    mangalib.Catalog

    класс
    Catalog(
        *,
        cache_dir: str | Path | None = None,
        cache_ttl: float | None = None,
        headers: Mapping[str, str] | None = None,
    )

    Базовые классы _CoreCatalog[Title]

    Entry point for listing/searching the mangalib.me catalog.

    Lists titles (list_titles()) and the filter options for them (list_genres(), list_countries() — on mangalib.me these are the title types: manga, manhwa, manhua, ... — and list_statuses()), each filtered to mangalib.me.

    ИСХОДНИК ↗

    aclose

    методasync
    aclose() -> None

    Close the underlying HTTP client.

    ИСХОДНИК ↗

    list_countries

    методasync
    list_countries(*, refresh: bool = False) -> list[Country]

    Fetch the full list of catalog countries (id → name), for use as filter options with list_titles(countries=...).

    Mirrors list_genres() exactly, down to the network-wide, not-site-scoped shape of the underlying endpoint (GET /api/constants?fields[]=types — the API's own name for what this SDK calls "country" is "type", see docs/api-notes.md and Country's docstring). This filters that down to entries tagged for site before returning, same as list_genres() does for genres.

    Параметры

    ИмяТипОписаниеПо умолчанию
    refreshbool

    Bypass the disk cache and re-fetch from the API even if the country list was already cached.

    False

    Возвращает

    ТипОписание
    list[Country]

    Every Country (id, name) that applies to site.

    ИСХОДНИК ↗

    list_genres

    методasync
    list_genres(*, refresh: bool = False) -> list[Genre]

    Fetch the full list of catalog genres (id → name), for use as filter options with list_titles(genres=[...]).

    The underlying endpoint (GET /api/constants?fields[]=genres) has no site-scoping parameter — it returns the full genre list shared across the whole lib.social network in one shot, each tagged with the site ids it applies to (see docs/api-notes.md). This filters that down to genres tagged for site before returning, so callers don't get filter options that could never match any of the site's titles (e.g. "Детское", tagged only for site 5, on ranobelib.me).

    Параметры

    ИмяТипОписаниеПо умолчанию
    refreshbool

    Bypass the disk cache and re-fetch from the API even if the genre list was already cached.

    False

    Возвращает

    ТипОписание
    list[Genre]

    Every Genre (id, name, adult flag) that applies to site.

    ИСХОДНИК ↗

    list_statuses

    методasync
    list_statuses(*, refresh: bool = False) -> list[Label]

    Fetch the full list of title statuses (id → label), for use as filter options with list_titles(statuses=...).

    Mirrors list_genres()/list_countries(): the underlying endpoint (GET /api/constants?fields[]=status) isn't site-scoped, so entries not tagged for site are dropped before returning (see docs/api-notes.md). Returns the same Label model as Title.status, so a title's status can be compared against these directly.

    Параметры

    ИмяТипОписаниеПо умолчанию
    refreshbool

    Bypass the disk cache and re-fetch from the API even if the status list was already cached.

    False

    Возвращает

    ТипОписание
    list[Label]

    Every status (Label: id, label) that applies to site.

    ИСХОДНИК ↗

    list_titles

    методasync
    list_titles(
        *,
        page: int = 1,
        per_page: int = 30,
        query: str | None = None,
        genres: list[int] | None = None,
        tags: list[int] | None = None,
        statuses: list[int] | None = None,
        countries: list[int] | None = None,
        min_chapters: int | None = None,
        max_chapters: int | None = None,
        sort: str = DEFAULT_SORT,
        refresh: bool = False,
    ) -> CatalogPage[TitleT]

    Fetch one page of catalog listing/search results.

    Параметры

    ИмяТипОписаниеПо умолчанию
    pageint

    1-based page number.

    1
    per_pageint

    How many titles per page. Must be between MIN_PER_PAGE (10) and MAX_PER_PAGE (60) — the API's own limits (see docs/api-notes.md); anything outside that range raises here instead of a confusing 422 from the API.

    30
    querystr | None

    Free-text search term, matched against name/rus_name/eng_name. None (the default) or an empty string lists without searching.

    None
    genreslist[int] | None

    Genre ids to filter by. A title must have all of them, not just one (AND, not OR — see docs/api-notes.md). Not validated against list_genres() before sending — an unrecognized id just matches nothing rather than erroring.

    None
    tagslist[int] | None

    Tag.ids (from Title.tags) to filter by. Same AND semantics as genres — a title must have all of them, not just any one (confirmed against the live API, see docs/api-notes.md; not the OR some might expect from tags being more numerous/specific than genres). Also not validated before sending, same as genres.

    None
    statuseslist[int] | None

    Title.status.ids to filter by (e.g. ongoing, completed). A title matches if its own status is any of these (OR, same as countries — a title only has one status, see docs/api-notes.md). None or an empty list applies no status filter. Ids come from list_statuses().

    None
    countrieslist[int] | None

    Country.ids to filter by. A title matches if its own country is any of these (OR, not AND like genres/tags — a title only has one country of origin, so requiring all of them could never match past the first, see docs/api-notes.md). None or an empty list applies no country filter. Ids come from list_countries(). Sent on the wire as the API's types[] parameter, not a country/countries[] one — see docs/api-notes.md for why (Country mirrors the API's own "type" concept, which isn't strictly limited to literal countries).

    None
    min_chaptersint | None

    Only titles with at least this many chapters (inclusive). Counts the same number as Title.chapter_count (uploaded chapters). None (the default) applies no lower bound.

    None
    max_chaptersint | None

    Only titles with at most this many chapters (inclusive). None (the default) applies no upper bound.

    None
    sortstr

    Sort order. Despite the name, this is sent as the API's sort_by parameter — an actual sort parameter exists but is silently ignored by the API (see docs/api-notes.md). Known accepted values: "name", "created_at", "views", "chap_count", "last_chapter_at" (the default), "rate_avg", "random" — this list isn't guaranteed exhaustive.

    DEFAULT_SORT
    refreshbool

    Bypass the disk cache and re-fetch from the API even if this exact combination of parameters was already cached.

    False

    Возвращает

    ТипОписание
    CatalogPage[TitleT]

    A page_model page: the matching titles plus whether a next page exists.

    Исключения

    ТипОписание
    ValueError

    If page is less than 1, per_page is outside MIN_PER_PAGE..MAX_PER_PAGE, min_chapters/max_chapters is negative, or min_chapters is greater than max_chapters.

    ИСХОДНИК ↗

    Models

    mangalib.CatalogPage

    класс
    CatalogPage()

    Базовые классы _core.CatalogPage[Title]

    One page of catalog listing/search results, as returned by Catalog.list_titles().

    items reuses Title as-is: the fields a listing doesn't send (genres, summary, chapter_count, last_chapter_at, ...) come back at their defaults.

    ИСХОДНИК ↗

    mangalib.Title

    класс
    Title()

    Базовые классы _core.Title

    Metadata for a single title (manga, manhwa, manhua, comic, ...).

    ИСХОДНИК ↗

    base_names

    атрибутсвойство
    base_names: list[str]

    The title's names without a trailing format marker.

    rus_name, eng_name, name and other_names, in that order, each with a bare format marker at the end removed — "Return of the Runebound Professor (webtoon)" → "Return of the Runebound Professor", likewise (Manhwa), (Манга), [Вебтун], (Комикс), ... Unlike ranobelib.me's (Новелла), mangalib.me doesn't append one itself: only a few dozen names have one, typed by hand. Other bracketed tails — (Doujinshi), (Colored), (перезапуск), a year, (манга-версия) — tell titles apart and are kept. Whitespace is trimmed; empty names and duplicates (keeping the first) are dropped. Nothing else is normalized (case, punctuation): that's up to whatever compares the names.

    The original fields are left as they are. On Catalog.list_titles() items other_names is empty (the listing doesn't return it), so it contributes nothing.

    ИСХОДНИК ↗

    chapter_count

    атрибут
    chapter_count: int | None = None

    Number of uploaded chapters. Only TitleClient.get_info() fills it in: the catalog listing endpoint doesn't return it (see docs/api-notes.md), so it's None on Catalog.list_titles() items.

    ИСХОДНИК ↗

    last_chapter_at

    атрибут
    last_chapter_at: datetime | None = Field(default=None, alias='last_item_at')

    When the most recent chapter was published — the value the catalog's sort="last_chapter_at" orders by. Only TitleClient.get_info() fills it in: the catalog listing endpoint doesn't return it (see docs/api-notes.md), so it's None on Catalog.list_titles() items, and on a title with no chapters yet.

    ИСХОДНИК ↗

    mangalib.Chapter

    класс
    Chapter()

    Базовые классы _core.Chapter

    A chapter: volume, number, name, available translations, and optionally its pages.

    index/item_number/branches_count/branches come from the chapter-list endpoint (see MangaLib.get_table_of_contents()) and are None/empty when a Chapter instead comes from fetching a single chapter, which has a different response shape. pages is the reverse: only filled in by fetching the chapter (MangaLib.get_chapter() and friends), in reading order.

    ИСХОДНИК ↗

    restricted_view

    атрибут
    restricted_view: RestrictedView | None = None

    Set on a fetched chapter whose translation is (or was) paid or in early access.

    ИСХОДНИК ↗

    teams

    атрибут
    teams: list[Team] = Field(default_factory=list)

    The teams credited for the fetched translation (empty on the chapter list's entries, where each of branches has its own).

    ИСХОДНИК ↗

    mangalib.Page

    класс
    Page()

    Базовые классы BaseModel

    One page image of a chapter.

    url is relative to an image server (see ImageServer and mangalib.page_url()): the API doesn't say which server a page is on, every server serves every page.

    ИСХОДНИК ↗

    image

    атрибут
    image: str

    The image's file name. Its extension isn't reliable as a format: the compress server sends a JPEG for a .png name (see docs/api-notes.md).

    ИСХОДНИК ↗

    number

    атрибут
    number: int = Field(alias='slug')

    1-based position in the chapter — the API's slug.

    ИСХОДНИК ↗

    url

    атрибут
    url: str

    Path of the image on an image server, e.g. "//manga/{slug}/chapters/1-1/00.jpg".

    ИСХОДНИК ↗

    mangalib.ChapterBranch

    класс
    ChapterBranch()

    A single team's (or solo uploader's) translation of a chapter.

    A chapter has more than one branch when several teams have translated it independently; see Chapter.branches_count.

    ИСХОДНИК ↗

    is_open

    атрибутсвойство
    is_open: bool

    Whether this translation can be read without an account.

    False means MangaLib.get_chapter() raises AuthRequiredError for it.

    ИСХОДНИК ↗

    restricted_view

    атрибут
    restricted_view: RestrictedView | None = None

    Set when this translation is paid or in early access — see is_open.

    ИСХОДНИК ↗

    mangalib.RestrictedView

    класс
    RestrictedView()

    Базовые классы BaseModel

    Access to a paid or early-access chapter translation.

    Present only on translations that are (or were) restricted. Logging in isn't supported by the SDK, so a closed one can't be read through it — see ChapterBranch.is_open.

    ИСХОДНИК ↗

    expired_at

    атрибут
    expired_at: datetime | None = None

    When early access ends and the chapter opens for everyone; None for a chapter that stays paid.

    ИСХОДНИК ↗

    is_open

    атрибут
    is_open: bool

    Whether anyone can read it now, without an account.

    ИСХОДНИК ↗

    price

    атрибут
    price: int | None = None

    The price the site asks, in its own currency. The chapter list leaves it None; fetching the chapter fills it in.

    ИСХОДНИК ↗

    mangalib.ImageServer

    класс
    ImageServer()

    Базовые классы BaseModel

    A server page images are downloaded from (GET /constants?fields[]=imageServers).

    A page's full URL is the server's url followed by Page.url.

    ИСХОДНИК ↗

    id

    атрибут
    id: str

    The API's name for it: "main", "secondary", "compress", "download", "crop" (see docs/api-notes.md for which of them actually serve pages).

    ИСХОДНИК ↗

    mangalib.Volume

    класс
    Volume()

    Базовые классы _core.Volume[Chapter]

    A volume: its number and the chapters it contains, in title order.

    ИСХОДНИК ↗

    Page images

    mangalib.page_url

    функция
    page_url(page: Page, server: ImageServer) -> str

    The full URL of page's image on server.

    Page.url starts with //; the slashes are collapsed to one (both forms serve the same image, checked on every server).

    ИСХОДНИК ↗

    mangalib.images.DEFAULT_SERVER_ORDER

    атрибут
    DEFAULT_SERVER_ORDER = ('compress', 'download', 'main', 'secondary')

    Image servers tried, in this order, when no server is chosen. crop isn't one of them: it serves 310×450 previews, not the page itself — choose it explicitly if that's what you want.

    ИСХОДНИК ↗

    mangalib.images.DEFAULT_IMAGE_CONCURRENCY

    атрибут
    DEFAULT_IMAGE_CONCURRENCY = 5

    Page requests in flight at once by default (download_pages(), export(), size methods).

    ИСХОДНИК ↗

    mangalib.images.DEFAULT_IMAGE_REQUEST_DELAY

    атрибут
    DEFAULT_IMAGE_REQUEST_DELAY = 0.2

    Minimum time, in seconds, between the starts of two requests to the same image host, across every client in the process. With five at once, 300 full-size pages went through without a single 429 when checked; much denser request rates got DDoS-Guard's 429.

    ИСХОДНИК ↗

    Exporters

    Not re-exported from the top-level mangalib package — import from mangalib.exporters. A new format is a new module in mangalib/exporters/ implementing Exporter, decorated with @register. "pdf" is registered only when the pdf extra (img2pdf) is installed.

    mangalib.exporters.Exporter

    класс
    Exporter()

    Базовые классы Protocol

    Renders a title's chapters, as page images, to a single file in some format.

    ИСХОДНИК ↗

    format

    атрибут
    format: str

    The registry key this exporter is selected by, e.g. "cbz".

    ИСХОДНИК ↗

    export

    методasync
    export(
        title: Title,
        chapters: list[Chapter],
        output_path: Path,
        *,
        fetch_pages: FetchPages,
        on_chapter: Callable[[], None] | None = None,
    ) -> Path

    Write chapters (in the given order) to output_path.

    Параметры

    ИмяТипОписаниеПо умолчанию
    titleTitle

    The chapters' parent title, for metadata (name, authors, ...).

    chapterslist[Chapter]

    The chapters to include, in the order they should appear — fetched ones, with pages.

    output_pathPath

    Where to write the exported file.

    fetch_pagesFetchPages

    Downloads one chapter's page images. The exporter calls it once per chapter, in order, so it never holds more than it has to in memory.

    on_chapterCallable[[], None] | None

    Called once per chapter written, if given — drives MangaLib.export()'s progress reporting.

    None

    Возвращает

    ТипОписание
    Path

    output_path, once the file has been written.

    ИСХОДНИК ↗

    mangalib.exporters.register

    функция
    register(exporter: ExporterT) -> ExporterT

    Class decorator: register exporter under its format key.

    ИСХОДНИК ↗

    Registered exporters, keyed by Exporter.format.

    mangalib.exporters.cbz.CbzExporter

    класс
    CbzExporter()

    Writes chapters as one CBZ: every page image in reading order, plus ComicInfo.xml.

    Pages are stored without recompression (they're JPEGs already), named by their position in the book with zero padding (0001.jpg, 0002.jpg, ...) so every reader sorts them right, with the extension taken from the image's bytes. Where each chapter starts is recorded as a Bookmark on its first page in ComicInfo.xml (schema 2.1, as read by Komga, Kavita, ComicRack and others), which also carries the title's metadata.

    ИСХОДНИК ↗

    export

    методasync
    export(
        title: Title,
        chapters: list[Chapter],
        output_path: Path,
        *,
        fetch_pages: FetchPages,
        on_chapter: Callable[[], None] | None = None,
    ) -> Path

    Write chapters to output_path as a CBZ — see Exporter.export().

    ИСХОДНИК ↗

    mangalib.exporters.pdf.PdfExporter

    класс
    PdfExporter()

    Writes chapters as one PDF: a page per page image, an outline entry per chapter.

    JPEGs are embedded as they are, without recompression (img2pdf), so the file is about the size of the images. Each PDF page is the image's own size; a tall webtoon strip beyond the PDF page-size limit is scaled with /UserUnit rather than cut. The PDF is assembled in memory, so for a whole long title CBZ is the lighter choice.

    ИСХОДНИК ↗

    export

    методasync
    export(
        title: Title,
        chapters: list[Chapter],
        output_path: Path,
        *,
        fetch_pages: FetchPages,
        on_chapter: Callable[[], None] | None = None,
    ) -> Path

    Write chapters to output_path as a PDF — see Exporter.export().

    ИСХОДНИК ↗

    Exceptions

    MangaLibError is the base class of every error the SDK raises, the same class as ranobelib.RanobeLibError; the others are shared with ranobelib too, except PageDownloadError.

    mangalib.PageDownloadError

    класс
    PageDownloadError(failures: list[tuple[str, str]])

    Базовые классы LibSocialError

    Raised when a page image couldn't be downloaded from any image server.

    Each server is tried in turn (see MangaLib.download_page()); this is raised only after the last one failed too.

    Атрибуты

    ИмяТипОписание
    failures

    (url, reason) for every attempt, in the order they were made.

    ИСХОДНИК ↗

    mangalib.AuthRequiredError

    класс
    AuthRequiredError(url: str)

    Базовые классы LibSocialError

    Raised when the requested content requires authorization (paid or early access).

    Атрибуты

    ИмяТипОписание
    url

    The request URL that returned 403.

    ИСХОДНИК ↗

    mangalib.ChapterNotFoundError

    класс
    ChapterNotFoundError(slug_url: str, *, volume: str, number: str)

    Базовые классы LibSocialError

    Raised when a chapter cannot be found for a given volume/number.

    Атрибуты

    ИмяТипОписание
    slug_url

    The title's {id}--{slug} identifier.

    volume

    The volume number that was requested.

    number

    The chapter number that was requested.

    ИСХОДНИК ↗

    mangalib.VolumeNotFoundError

    класс
    VolumeNotFoundError(slug_url: str, *, volume: str)

    Базовые классы LibSocialError

    Raised when a title has no chapters for a given volume number.

    Атрибуты

    ИмяТипОписание
    slug_url

    The title's {id}--{slug} identifier.

    volume

    The volume number that was requested.

    ИСХОДНИК ↗

    mangalib.MultipleTranslationsError

    класс
    MultipleTranslationsError(
        slug_url: str,
        *,
        volume: str,
        number: str,
        branches: list[ChapterBranch],
    )

    Базовые классы LibSocialError

    Raised when a chapter has more than one team's translation and none was selected.

    The SDK does not guess a default: the API's own default when branch_id is omitted is not simply the first branch listed, and the actual rule it uses isn't documented (see docs/api-notes.md) — returning it silently would be unpredictable. Call TitleClient.get_translations() to list the available branches, then pass one's branch_id explicitly.

    Атрибуты

    ИмяТипОписание
    slug_url

    The title's {id}--{slug} identifier.

    volume

    The chapter's volume number.

    number

    The chapter number.

    branches

    The chapter's available translations, as returned by TitleClient.get_translations().

    ИСХОДНИК ↗

    mangalib.MultipleTitleTranslationsError

    класс
    MultipleTitleTranslationsError(
        slug_url: str,
        *,
        chapters: list[AmbiguousChapter],
    )

    Базовые классы LibSocialError

    Raised by download_title() when one or more chapters have an unresolved translation.

    Unlike MultipleTranslationsError (one chapter), this can list several: a title-wide bulk download checks every chapter up front rather than stopping at the first ambiguous one, so a caller doesn't have to fix one chapter, rerun, hit the next, and rerun again. Pass branch_id or translation_index to download_title() to resolve them, or fetch the listed chapters individually with get_chapter(..., branch_id=...).

    Атрибуты

    ИмяТипОписание
    slug_url

    The title's {id}--{slug} identifier.

    chapters

    The ambiguous chapters and their available translations.

    ИСХОДНИК ↗

    mangalib.DownloadTitleInterruptedError

    класс
    DownloadTitleInterruptedError(
        slug_url: str,
        *,
        volumes: Sequence[Volume[Any]],
        completed: int,
        total: int,
    )

    Базовые классы LibSocialError

    Raised by download_title() when a chapter fetch fails unrecoverably partway through.

    download_title() fetches hundreds-to-thousands of chapters sequentially for a long title, which can outlast even the extra, bulk-specific rate-limit retry budget described in download_title()'s max_rate_limit_retries — or hit some other unrecoverable error (e.g. AuthRequiredError on a chapter that turns out to need a paywall/auth token). Rather than letting that error propagate on its own and silently discard every chapter already fetched, it's wrapped in this exception instead, carrying what was already downloaded — so a caller can keep that partial result, or simply call download_title() again: the SDK's disk cache means already-fetched chapters aren't re-requested, so a retry resumes close to where this one stopped rather than restarting the whole title. See docs/api-notes.md's "Rate limiting и retry" section and issue #41.

    Атрибуты

    ИмяТипОписание
    slug_url

    The title's {id}--{slug} identifier.

    volumeslist[Volume[Any]]

    Chapters fetched before the failure, grouped into volumes the same way a successful download_title() call would return them.

    completed

    How many chapters were fetched before the failure.

    total

    How many chapters download_title() had planned to fetch in total.

    ИСХОДНИК ↗

    Cache maintenance

    mangalib.cache_stats

    функция
    cache_stats(cache_dir: str | Path = DEFAULT_CACHE_DIR) -> CacheStats

    Count the entries in an SDK disk cache and their total size on disk.

    Параметры

    ИмяТипОписаниеПо умолчанию
    cache_dirstr | Path

    The cache directory — the same cache_dir passed to MangaLib / Catalog (default: theirs, .mangalib_cache in the current directory).

    DEFAULT_CACHE_DIR

    Возвращает

    ТипОписание
    CacheStats

    The number of entries and their total size in bytes. A missing directory is an empty

    CacheStats

    cache, CacheStats(entries=0, bytes=0), not an error.

    ИСХОДНИК ↗

    mangalib.clear_cache

    функция
    clear_cache(
        cache_dir: str | Path = DEFAULT_CACHE_DIR,
        *,
        older_than: float | None = None,
    ) -> CacheStats

    Remove entries from an SDK disk cache.

    Only files the cache itself writes are removed — anything else in the directory, and the directory itself, is left alone.

    Параметры

    ИмяТипОписаниеПо умолчанию
    cache_dirstr | Path

    The cache directory — see cache_stats().

    DEFAULT_CACHE_DIR
    older_thanfloat | None

    If given, only remove entries written more than this many seconds ago, plus any corrupted entry. None (the default) removes every entry.

    None

    Возвращает

    ТипОписание
    CacheStats

    The number of entries removed and the bytes they took.

    Исключения

    ТипОписание
    ValueError

    If older_than is negative.

    ИСХОДНИК ↗

    mangalib.CacheStats

    класс
    CacheStats(entries: int, bytes: int)

    How many cache entries there are (or were removed), and their total size on disk.

    ИСХОДНИК ↗