Skip to main content

Fulla Python Client

Typed Python SDK for Fulla — the embeddable C++ OAuth2/OIDC authorization server.

  • Distribution name: fulla-oauth2 (the shorter fulla name on PyPI belongs to an unrelated project)
  • Import name: fulla
  • API surface: generated from the server's single-source OpenAPI spec (apps/server/openapi.yaml) with openapi-python-client 0.29.0 — 78 operations, fully typed (py.typed), attrs-based models over httpx
  • Auth layer: handwritten (token lifecycle is too sensitive to template — see the design doc)
pip install fulla-oauth2

Published to PyPI since v1.3.0 (release pipeline's sdk-python job). Prefer the released wheel; a checkout install (pip install clients/python) still works for development.

Quickstart: machine-to-machine (client_credentials)

from fulla import m2m_client
from fulla.generated.api.o_auth_2 import post_oauth2_introspect
from fulla.generated.models.post_oauth_2_introspect_body import PostOauth2IntrospectBody

client = m2m_client(
    "http://localhost:5555",
    client_id="backend-svc",
    client_secret="…",
    scopes=["tokens:read"],
)

# Every request carries a valid Bearer token: fetched lazily, cached,
# refreshed 30 s before expiry, force-refreshed once on a 401.
result = post_oauth2_introspect.sync(
    client=client, body=PostOauth2IntrospectBody(token=some_access_token)
)
print(result.active)

# When done: closes BOTH the API client and the auth layer's token pool
# (closing the generated client alone leaks the token connection pool).
from fulla import close_m2m_client
close_m2m_client(client)

Async is symmetric:

from fulla import async_m2m_client

client = async_m2m_client("http://localhost:5555", "backend-svc", "…", scopes=["tokens:read"])
result = await post_oauth2_introspect.asyncio(client=client, body=body)

One-shot token fetch (scripts, benchmarks):

from fulla import fetch_client_credentials_token

token, expires_in = fetch_client_credentials_token(
    "http://localhost:5555", "backend-svc", "…", ["tokens:read"]
)

Introspect / revoke (client Basic authentication)

/oauth2/introspect and /oauth2/revoke authenticate the calling client, not a user bearer token (RFC 7662 §2.1). Use a client whose every request carries HTTP Basic — confidential clients must use Basic; the server rejects credentials in the body (F-017):

from fulla import basic_auth_client

client = basic_auth_client("http://localhost:5555", "backend-svc", "…")
result = post_oauth2_introspect.sync(client=client, body=PostOauth2IntrospectBody(token=tok))

Authorization-code flow (web apps, with PKCE)

from fulla import AuthorizationCodeFlow, PkcePair

flow = AuthorizationCodeFlow(
    "http://localhost:5555", "my-client", "my-secret",
    redirect_uri="https://my.app/callback", scopes=["openid", "profile"],
)
pkce = PkcePair.generate()
authorize_url = flow.build_authorize_url(state=session_csrf, pkce=pkce)
# → send the user's browser to authorize_url; Fulla redirects back with ?code=…&state=…
# → VERIFY state, then:
tokens = flow.exchange_code(code, pkce.verifier)
# … later; Fulla rotates refresh tokens on every use (V008):
tokens = flow.refresh(tokens.refresh_token)

Generated API modules

Everything under fulla.generated is the typed surface of the whole server API:

from fulla.generated.api.open_id_connect import get_well_known_openid_configuration
from fulla.generated.api.o_auth_2 import get_oauth2_userinfo, post_oauth2_token
from fulla.generated.models.token_request import TokenRequest

Each endpoint module offers sync, sync_detailed, asyncio, asyncio_detailed. The *_detailed variants return status code + raw response alongside the parsed model.

Development

cd clients/python
pip install -e ".[dev]"
pytest                       # unit tests (in-process MockTransport, no server needed)

# integration tests (needs a running full stack, see tests/integration/)
FULLA_BASE_URL=http://127.0.0.1:5555 pytest tests/integration

Regenerating the committed src/fulla/generated/ tree after an openapi.yaml change:

pip install openapi-python-client==0.29.0
python tools/clients/regen_clients.py            # from the repo root

CI (.github/workflows/clients-sdk.yml) re-generates and diffs on every PR touching clients/** or the spec — committed generated code can never go stale.

Versioning

The package version is locked to the server's cmake/Version.cmake (enforced by tools/clients/regen_clients.py --version-only at release time). Breaking HTTP API changes require a major bump on both sides (guarded by the openapi-governance oasdiff workflow).

Local network note

If go/module proxies are unreachable from your network, the Go generator download mentioned in the regen docs needs a GOPROXY mirror (e.g. GOPROXY=https://goproxy.cn,direct). This only affects regenerating clients/go — installing and using this Python package is unaffected.

Metadata

Release files for fulla-oauth2 1.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fulla-oauth2 1.4.0
File Size Uploaded
fulla_oauth2-1.4.0.tar.gz 91.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fulla-oauth2 1.4.0
File Interpreter ABI Platform
fulla_oauth2-1.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 401.7 kB

Release files / fulla_oauth2-1.4.0.tar.gz

Download URL fulla_oauth2-1.4.0.tar.gz
Size 91.7 kB
Tags Source
SHA-256 checksum
How to use checksums
43951e17544feb3eb32cac678f0bb83d7e7ce57a894ee87ac5836b1f0b259747
BLAKE2b-256 checksum
How to use checksums
20da1f84743a2f78637892a982d108e93b771b352dfc45c7a4a7a80f29964e07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release files / fulla_oauth2-1.4.0-py3-none-any.whl

Download URL fulla_oauth2-1.4.0-py3-none-any.whl
Size 310.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
520061c47571e5cba5b5ebec21cb61f0445fad96d47211f7cb1246d73c5ac7c6
BLAKE2b-256 checksum
How to use checksums
7af64f16bc4ba497d794cfeae2f85350d1847bcb4606f9ac5ec52f633ec2f07c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.15

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page