animedex.backends.mangadex._auth

MangaDex OAuth2 helper.

MangaDex’s authenticated endpoints sit behind a Keycloak-fronted OAuth2 password grant (the client_credentials flow is not enabled for personal API clients). Every call needs:

  • client_id / client_secret from the caller’s https://mangadex.org/settings → API Clients page;

  • username / password for the caller’s MangaDex account.

This module exchanges those four for a short-lived access_token (15 min lifetime) and caches the result in process memory so a session of authenticated calls does not re-hit the auth endpoint per request. The cache is keyed on client_id; calling code never sees the password again after the first exchange.

The token endpoint is a different host (auth.mangadex.org) than the API host (api.mangadex.org); it’s hit directly via requests rather than through the project dispatcher to keep the auth flow off the api-host’s rate limit bucket.

MangaDexCredentials

class animedex.backends.mangadex._auth.MangaDexCredentials(client_id: str, client_secret: str, username: str, password: str)[source]

Bases: object

The four-tuple needed for OAuth2 password grant.

Variables:
  • client_id (str) – Personal API client identifier.

  • client_secret (str) – Personal API client secret.

  • username (str) – MangaDex account username.

  • password (str) – MangaDex account password.

client_id: str
client_secret: str
username: str
password: str
__repr__() str[source]

Return a representation that does not leak secrets.

classmethod from_string(raw: str) MangaDexCredentials[source]

Parse the colon-separated quad client_id:client_secret:username:password.

Parameters:

raw (str) – The packed credential string.

Returns:

Parsed credentials.

Return type:

MangaDexCredentials

Raises:

ApiError – When the string does not have exactly four colon-separated parts.

resolve_credentials

animedex.backends.mangadex._auth.resolve_credentials(creds: object | None = None, *, config: Config | None = None) MangaDexCredentials[source]

Locate a usable MangaDexCredentials quad.

creds accepts either a pre-built MangaDexCredentials instance or the same colon-separated string the env var uses (client_id:client_secret:username:password). The CLI threads --creds through as a string.

Resolution order (first hit wins):

  1. The explicit creds argument.

  2. The ANIMEDEX_MANGADEX_CREDS environment variable.

  3. The TokenStore attached to config (looked up under the key "mangadex").

Parameters:
Returns:

Resolved credentials.

Return type:

MangaDexCredentials

Raises:

ApiError – When none of the three sources yield a value.

get_bearer_token

animedex.backends.mangadex._auth.get_bearer_token(creds: object | None = None, *, config: Config | None = None, force_refresh: bool = False) str[source]

Return a usable Bearer access token, exchanging credentials for a fresh one when the cache is empty or stale.

Parameters:
  • creds (MangaDexCredentials or None) – Explicit credentials (overrides env / store).

  • config (Config or None) – Optional Config used to resolve credentials from the token store.

  • force_refresh (bool) – When True, ignore the in-memory cache and run the OAuth exchange again.

Returns:

Bearer access token (no Bearer prefix).

Return type:

str

Raises:

ApiErrorauth-required when no credentials resolve; upstream-error on Keycloak failures; upstream-decode on a malformed response.

selftest

animedex.backends.mangadex._auth.selftest() bool[source]

Smoke-test the credential parser. The OAuth exchange is not triggered because it requires a network round-trip; the helper is exercised by the per-endpoint live capture / replay path.

Returns:

True on success; raises on schema drift.

Return type:

bool