Skip to content

Route auth schemes

The DHIS2 Route API proxies requests to upstream services. Its own auth is one of five discriminated variants. The union is typed end-to-end via AuthScheme + AuthSchemeAdapter.

auth_schemes

Typed DHIS2 Route auth schemes — re-exports from generated v42 OAS models.

DHIS2's /api/routes and /api/webhooks objects carry an auth block describing how DHIS2 talks to upstream targets. OpenAPI defines the five leaf schemas — HttpBasicAuthScheme, ApiTokenAuthScheme, ... — but historically dropped the Jackson type discriminator (BUGS.md #14).

The codegen emitter patches the spec at build time (see dhis2w_codegen.spec_patches) to synthesise the discriminator block + add a type: Literal["<tag>"] field to each variant. This module then re-exports the generated leaves + the discriminated Union + a TypeAdapter helper so callers have one import path.

Subtypes (every one DHIS2 v42 accepts):

  • http-basic -> HttpBasicAuthScheme - RFC 7617 Basic auth (user + password).
  • api-token -> ApiTokenAuthScheme - DHIS2-flavour static token.
  • api-headers -> ApiHeadersAuthScheme - arbitrary custom headers.
  • api-query-params -> ApiQueryParamsAuthScheme - auth via query-string params.
  • oauth2-client-credentials -> OAuth2ClientCredentialsAuthScheme - upstream OAuth2 client-credentials flow.

Attributes

AuthScheme = Annotated[HttpBasicAuthScheme | ApiTokenAuthScheme | ApiHeadersAuthScheme | ApiQueryParamsAuthScheme | OAuth2ClientCredentialsAuthScheme, Field(discriminator='type')] module-attribute

Discriminated union for the 5 DHIS2 Route auth variants. Validate via AuthSchemeAdapter.

AuthSchemeAdapter = TypeAdapter(AuthScheme) module-attribute

Classes

ApiHeadersAuthScheme

Bases: BaseModel

OpenAPI schema ApiHeadersAuthScheme.

Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/api_headers_auth_scheme.py
class ApiHeadersAuthScheme(_BaseModel):
    """OpenAPI schema `ApiHeadersAuthScheme`."""

    model_config = _ConfigDict(extra="allow", populate_by_name=True, defer_build=True)

    headers: dict[str, str] | None = None
    type: Literal["api-headers"] = "api-headers"

ApiQueryParamsAuthScheme

Bases: BaseModel

OpenAPI schema ApiQueryParamsAuthScheme.

Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/api_query_params_auth_scheme.py
class ApiQueryParamsAuthScheme(_BaseModel):
    """OpenAPI schema `ApiQueryParamsAuthScheme`."""

    model_config = _ConfigDict(extra="allow", populate_by_name=True, defer_build=True)

    queryParams: dict[str, str] | None = None
    type: Literal["api-query-params"] = "api-query-params"

ApiTokenAuthScheme

Bases: BaseModel

OpenAPI schema ApiTokenAuthScheme.

Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/api_token_auth_scheme.py
class ApiTokenAuthScheme(_BaseModel):
    """OpenAPI schema `ApiTokenAuthScheme`."""

    model_config = _ConfigDict(extra="allow", populate_by_name=True, defer_build=True)

    token: str | None = None
    type: Literal["api-token"] = "api-token"

HttpBasicAuthScheme

Bases: BaseModel

OpenAPI schema HttpBasicAuthScheme.

Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/http_basic_auth_scheme.py
class HttpBasicAuthScheme(_BaseModel):
    """OpenAPI schema `HttpBasicAuthScheme`."""

    model_config = _ConfigDict(extra="allow", populate_by_name=True, defer_build=True)

    password: str | None = None
    type: Literal["http-basic"] = "http-basic"
    username: str | None = None

OAuth2ClientCredentialsAuthScheme

Bases: BaseModel

OpenAPI schema OAuth2ClientCredentialsAuthScheme.

Source code in packages/dhis2w-client/src/dhis2w_client/generated/v42/oas/o_auth2_client_credentials_auth_scheme.py
class OAuth2ClientCredentialsAuthScheme(_BaseModel):
    """OpenAPI schema `OAuth2ClientCredentialsAuthScheme`."""

    model_config = _ConfigDict(extra="allow", populate_by_name=True, defer_build=True)

    clientId: str | None = None
    clientSecret: str | None = None
    scopes: str | None = None
    tokenUri: str | None = None
    type: Literal["oauth2-client-credentials"] = "oauth2-client-credentials"

Functions

auth_scheme_from_route(route)

Parse a Route's auth field into the typed discriminated union.

Since the codegen spec-patches sweep Route.auth is already the discriminated Union; this helper exists for legacy callers that pass in a raw dict (e.g. loaded from JSON or from a pre-patched spec).

Example

route = await client.resources.routes.get("abc123") scheme = auth_scheme_from_route(route) match scheme: ... case HttpBasicAuthScheme(username=u): ... print(f"basic auth as {u}") ... case OAuth2ClientCredentialsAuthScheme(tokenUri=uri): ... print(f"oauth2 against {uri}")

Source code in packages/dhis2w-client/src/dhis2w_client/auth_schemes.py
def auth_scheme_from_route(route: Any) -> AuthScheme | None:
    """Parse a `Route`'s `auth` field into the typed discriminated union.

    Since the codegen spec-patches sweep `Route.auth` is already the
    discriminated Union; this helper exists for legacy callers that pass
    in a raw dict (e.g. loaded from JSON or from a pre-patched spec).

    Example:
        >>> route = await client.resources.routes.get("abc123")
        >>> scheme = auth_scheme_from_route(route)
        >>> match scheme:
        ...     case HttpBasicAuthScheme(username=u):
        ...         print(f"basic auth as {u}")
        ...     case OAuth2ClientCredentialsAuthScheme(tokenUri=uri):
        ...         print(f"oauth2 against {uri}")
    """
    raw = getattr(route, "auth", None)
    if raw is None:
        return None
    if isinstance(raw, BaseModel):
        raw = raw.model_dump()
    if not isinstance(raw, dict) or "type" not in raw:
        return None
    return AuthSchemeAdapter.validate_python(raw)