Library / SDK guide

This is the complete guide to the Nyora library (pip install nyora, import nyora). It covers the two client paths, every service method with its signature and return type, context-manager usage, error handling, and the model dataclasses.

Note

The library and the nyora-cli terminal tool are separate. This guide is about the importable nyora package only.

Two client paths

Nyora ships two distinct clients. Pick based on whether you want an in-process runtime or want to talk to an external Nyora helper.

Client

Import

Backend

Use when

nyora.Nyora (a.k.a. nyora.direct.Nyora)

from nyora import Nyora

Embedded QuickJS parser runtime, in-process

Default. You want a self-contained SDK with no external process.

nyora.NyoraHelper (a.k.a. nyora.client.Nyora)

from nyora import NyoraHelper

REST over HTTP to a running Nyora helper

You already have a Nyora app/helper running and want its full library, downloads, history, and sync features.

nyora.AsyncNyora

from nyora import AsyncNyora

Async REST to a running helper

You need async/await read access to a helper.

The direct client and the helper client expose different capabilities. The direct client is read-and-browse over the bundled parsers; the helper client adds the user’s library, downloads, history, backup, and cloud sync (because those live in the helper, not in the parsers).


The default client: nyora.direct.Nyora

from nyora import Nyora

client = Nyora(timeout=60.0)

Nyora(*, timeout=60.0) constructs the client and its embedded nyora.runtime.ParserRuntime. timeout is the per-call runtime timeout in seconds.

Context-manager usage

The embedded runtime holds resources (the QuickJS context). Always close it. The context manager is the idiomatic way:

with Nyora() as client:
    sources = client.sources.list()
# runtime is closed here

Equivalently, call client.close() yourself:

client = Nyora()
try:
    sources = client.sources.list()
finally:
    client.close()

Attributes

  • client.ota — the nyora.ota.OtaManager backing over-the-air updates.

  • client.sources — a DirectSourcesService.

  • client.manga — a DirectMangaService.

Top-level methods

update(*, force=False) -> OtaUpdateResult

Fetch the latest OTA parser bundle, then reload the embedded runtime so new parsers are live in the same process. Pass force=True to re-download even when already current. Returns an nyora.ota.OtaUpdateResult.

with Nyora() as client:
    result = client.update()
    print(result.updated, result.version, result.bundle_path)

check_update() -> tuple[bool, int | None, int | None]

Check whether a newer bundle is available without applying it. Returns (available, installed_version, latest_version); versions are None when unknown.

with Nyora() as client:
    available, installed, latest = client.check_update()

Nyora.helper(base_url=None, *, timeout=60.0) -> nyora.client.Nyora

Classmethod. Attach to an already-running external helper and return a nyora.client.Nyora REST client (see the “The helper client” section below). base_url is auto-discovered from NYORA_BASE_URL or the helper port file when None.

helper = Nyora.helper()
print(helper.health())
helper.close()

Nyora.managed_helper(jar_path, *, timeout=60.0, launch_timeout=20.0) -> nyora.client.Nyora

Classmethod. Launch a JVM helper from jar_path and return a nyora.client.Nyora client bound to the managed process. The process is stopped when the client is closed.

close() -> None

Close the embedded runtime and release its resources. Called automatically on context-manager exit.

client.sourcesDirectSourcesService

Operates over the bundled source catalog (no network needed to list).

list() -> list[Source]

List every bundled source.

with Nyora() as client:
    for source in client.sources.list():
        print(source.id, source.name, source.lang)

Returns a list of Source.

find(query: str) -> Source

Return the first bundled source whose id or name contains query (case-insensitive). Raises LookupError if none match.

with Nyora() as client:
    source = client.sources.find("mangadex")

client.mangaDirectMangaService

Drives the parser runtime to browse, search, and read.

latest(source_id: str, page: int = 1) -> SearchPage

A page of the latest-updated manga. Same shape as popular.

search(source_id: str, query: str, page: int = 1) -> SearchPage

Search a source for query.

results = client.manga.search(source.id, "berserk", page=1)

Returns a SearchPage.

details(source_id: str, manga_url: str, *, title: str = "") -> MangaDetails

Full metadata plus the chapter list for one manga. title is an optional known title passed through to help the parser resolve the entry.

details = client.manga.details(source.id, entry.url, title=entry.title)
print(details.manga.title, len(details.chapters))

Returns a MangaDetails.

pages(source_id: str, chapter_url: str, *, branch: str | None = None) -> list[MangaPage]

Resolve the readable image pages of one chapter. branch optionally selects a scanlation branch/translation.

pages = client.manga.pages(source.id, chapter.url)
for page in pages:
    print(page.url, page.headers)

Returns a list of MangaPage.


The helper client: nyora.client.Nyora

Use this when an external Nyora helper is running (a Nyora app, the JVM helper, or an embedded nyora.server.NyoraServer — see the server guide). It speaks the camelCase helper REST contract over HTTP and exposes the full feature set: library, downloads, backup, cloud sync, trackers.

from nyora import NyoraHelper  # this is nyora.client.Nyora

with NyoraHelper.attach() as client:
    for source in client.sources.list():
        print(source.id, source.name)

Construction and discovery

  • NyoraHelper(base_url=None, *, timeout=60.0, helper=None) — connect. When base_url is None, the URL is discovered from the NYORA_BASE_URL environment variable, then the helper port file. Raises nyora.HelperNotFoundError if nothing is found.

  • NyoraHelper.attach(base_url=None, *, timeout=60.0) — classmethod alias for attaching to an already-running helper.

  • NyoraHelper.managed(jar_path=None, *, java="java", timeout=60.0, launch_timeout=20.0) — classmethod that launches a helper jar (path or NYORA_HELPER_JAR) and binds a client to it. The process is owned and stopped on close().

Use it as a context manager; on exit it closes the HTTP connection and stops any managed helper.

Low-level HTTP and health

  • health() -> dict[str, Any] — the helper’s /health payload.

  • get(path, *, params=None) -> Any — raw GET; returns parsed JSON or text.

  • post(path, *, params=None, json=None, content=None) -> Any — raw POST.

  • delete(path, *, params=None) -> Any — raw DELETE.

All raise nyora.NyoraHTTPError on a 4xx/5xx response.

Service objects

The helper client attaches six services. Methods that return model objects reference nyora.models; methods documented as returning dict/list return the raw helper payload.

client.sourcesSourcesService

Method

Returns

list()

list[Source] — installed sources

catalog()

list[Source] — every catalog source

refresh()

list[Source] — after refreshing from the feed

install(source_id)

`Source

uninstall(source_id)

dict

pin(source_id)

dict

filters(source_id)

list[SourceFilter]

find(query)

Source (raises LookupError)

client.mangaMangaService

Method

Returns

popular(source_id, page=1)

SearchPage

latest(source_id, page=1)

SearchPage

search(source_id, query, page=1, *, filters=None)

SearchPage

global_search(query, *, limit_per_source=8)

list[GlobalSearchGroup]

details(source_id, manga_url, *, manga_id=None)

MangaDetails

pages(source_id, chapter_url, *, branch=None)

list[MangaPage]

alternatives(title)

list[dict]

suggestions()

list[Manga]

prefs(manga_id)

MangaPrefs

save_prefs(manga_id, *, reader_mode="", brightness=0.0, contrast=1.0, saturation=1.0, hue=0.0, palette="")

dict

clear_prefs(manga_id)

dict

Note: on the helper client, details takes manga_id (not title), unlike the direct client’s details.

client.libraryLibraryService

Method

Returns

history(limit=100)

list[HistoryEntry]

record_history(*, manga_id, chapter_id, page, percent)

dict

remove_history(manga_id, chapter_id=None)

dict

clear_history()

dict

favourites(category_id=None)

list[Manga]

toggle_favourite(manga_id)

dict

is_favourite(manga_id)

bool

bookmarks(manga_id=None)

list[dict]

add_bookmark(*, manga_id, chapter_id, page, title="")

dict

remove_bookmark(*, manga_id, chapter_id, page)

dict

categories()

list[Category]

create_category(title)

`Category

rename_category(category_id, title)

dict

delete_category(category_id)

dict

add_to_category(manga_id, category_id)

dict

remove_from_category(manga_id, category_id)

dict

updates()

list[dict]

refresh_updates()

dict

mark_update_seen(update_id)

dict

client.downloadsDownloadsService

Method

Returns

list()

list[Download]

start(*, source_id, manga_url, chapter_url, manga_title="", chapter_title="")

Download

enqueue(*, source_id, manga_url, chapters, manga_title="")

list[Download]

cancel(download_id)

dict

settings()

DownloadSettings

save_settings(*, max_concurrent=None, format=None)

DownloadSettings

client.backupBackupService

Method

Returns

export()

backup payload (Any)

import_(backup_json)

BackupImportResult

client.systemSystemService

Composes three sub-services: client.system.sync, client.system.local, client.system.tracker.

Method

Returns

stats()

Stats

network_settings()

dict

save_network_settings(**settings)

dict

ota_status()

dict

ota_check()

dict

sync.status()

dict

sync.sign_in(id_token)

dict

sync.sign_out()

dict

sync.sync()

dict

sync.restore_from_cloud()

dict

sync.has_local_data()

bool

local.scan(folder)

list[dict]

local.chapter(cbz)

dict

tracker.anilist_search(query)

dict

tracker.anilist_scrobble(*, token, media_id, progress)

dict

nyora.AsyncNyora

A lightweight async helper client for read-style requests:

from nyora import AsyncNyora

async def main():
    async with AsyncNyora.attach() as client:
        payload = await client.get("/sources")
        health = await client.health()

It exposes attach, get(path, *, params=None), health(), and close().


Error handling

The full exception hierarchy lives in nyora.errors and is re-exported from the top-level package. All SDK errors derive from NyoraError, so catching it catches everything.

Exception

Raised when

NyoraError

Base class for all SDK failures (also OTA and runtime errors).

HelperNotFoundError

No running helper could be discovered for a helper client.

HelperLaunchError

A managed helper process failed to start.

NyoraHTTPError

The helper returned a 4xx/5xx. Has .status_code and .body.

ParserRuntimeError (in nyora.runtime, also a NyoraError) surfaces parser runtime failures from the direct client.

from nyora import Nyora, NyoraError, NyoraHTTPError

try:
    with Nyora() as client:
        page = client.manga.popular("mangadex")
except NyoraHTTPError as exc:
    print("HTTP", exc.status_code, exc.body)
except NyoraError as exc:
    print("Nyora error:", exc)

sources.find(...) raises the standard library LookupError (not a NyoraError) when nothing matches.


Model dataclasses

All models live in nyora.models and are slotted dataclasses with a tolerant from_json classmethod that coerces raw camelCase payloads defensively — missing or malformed fields fall back to sensible defaults rather than raising. Fields below use the Python (snake_case) names.

Source

A content source (site). Fields: id, name, lang, base_url, engine, content_type, is_installed, is_pinned, is_nsfw, is_obsolete, icon_url, version, notes, can_uninstall.

SourceFilter

A search filter advertised by a source. Fields: name, type_name, values.

Manga

A manga entry as returned in listings and details. Fields: id, title, alt_titles, url, public_url, rating (-1.0 when unknown), is_nsfw, content_rating, cover_url, large_cover_url, state, authors, source, source_id, description, tags, chapters, unread, progress.

MangaChapter

A chapter belonging to a manga. Fields: id, title, number (may be fractional), volume, url, scanlator, upload_date (epoch ms), branch, pages, index.

MangaPage

A readable image page. Fields: url, headers (request headers required to fetch the image, e.g. Referer). MangaPage.from_json also accepts a bare string URL.

SearchPage

One page of results. Fields: entries (a list[Manga]), has_next_page.

MangaDetails

Full metadata plus chapters. Fields: manga (a Manga), chapters (a list[MangaChapter]).

Helper-only models

These appear in responses from the helper client:

  • HistoryEntrymanga, chapter_id, page, percent, updated_at.

  • Categoryid, title, manga_count.

  • Downloadid, source_id, manga_title, chapter_title, chapter_url, status, total_pages, completed_pages, failed_pages, file_path, error.

  • DownloadSettingsmax_concurrent_downloads, format.

  • MangaPrefsmanga_id, reader_mode, brightness, contrast, saturation, hue, palette, present.

  • GlobalSearchGroupsource_id, source_name, entries, error.

  • Statstotal_chapters, distinct_manga, favourites_count, longest_streak_days, top_sources.

  • BackupImportResultok, imported_favourites, imported_history.

See the API reference for the full autodoc, including every field default and from_json behavior.