Skip to main content

Synchronous and asynchronous OAuth2/OIDC clients for the Verys auth service.

Project description

Verys Python Client

Synchronous and asynchronous OAuth2/OIDC clients for the Verys auth service.

Features

  • VerysClient (sync) and AsyncVerysClient (async) with identical APIs
  • Authorization code flow, with PKCE automatically used for public clients
  • Refresh token and token-exchange grants
  • Federated external token retrieval
  • Typed, documented public surface with a clear exception hierarchy

Installation

uv add verys-py-client
# or
pip install verys-py-client

Requires Python 3.14+.

Quickstart

Confidential client (with a client secret)

from verys_py_client import VerysClient

client = VerysClient(
    host="https://app.example.com",
    base_url="https://auth.verys.example.com",
    client_id="your-client-id",
    client_secret="your-client-secret",
    scopes=["openid", "profile", "email"],
)

# 1. Redirect the user to the authorization URL.
url, state, nonce, code_verifier = client.create_auth_url()
# Persist `state`, `nonce` (and `code_verifier` for public clients) in the session,
# then redirect the user to `url`.

# 2. Handle the callback (e.g. in a Starlette/FastAPI route).
state, code = VerysClient.handle_callback(request)

# 3. Exchange the code for tokens.
id_token, access_token, refresh_token = client.token_by_code(code, nonce)

Public client (no secret — PKCE)

Construct the client with client_secret=None. create_auth_url() then attaches a PKCE code_challenge and returns a code_verifier you must persist and pass back to token_by_code:

client = VerysClient(
    host="https://app.example.com",
    base_url="https://auth.verys.example.com",
    client_id="your-public-client-id",
    client_secret=None,
    scopes=["openid", "profile"],
)

url, state, nonce, code_verifier = client.create_auth_url()
# ... redirect, then on callback:
id_token, access_token, refresh_token = client.token_by_code(code, nonce, code_verifier)

Other grants

# Refresh an access token.
access_token, refresh_token = client.refresh_access_token(refresh_token)

# Exchange a token for one scoped to another audience.
exchanged = client.token_by_exchange(access_token, audience="https://api.other.example")

# Retrieve federated external tokens.
tokens = client.get_external_tokens(access_token)
one = client.get_external_tokens(access_token, token_id="github")

Async usage

AsyncVerysClient mirrors the sync API; methods are awaitable:

from verys_py_client import AsyncVerysClient

client = AsyncVerysClient(
    host="https://app.example.com",
    base_url="https://auth.verys.example.com",
    client_id="your-client-id",
    client_secret="your-client-secret",
    scopes=["openid", "profile"],
)

id_token, access_token, refresh_token = await client.token_by_code(code, nonce)

Error handling

All errors derive from Exception; most application-level failures subclass VerysError, while JWKS/public-key failures form a separate JwksError branch.

Exception Raised when
VerysError Base class for client errors
CallbackError The authorization callback reports an error
MissingCodeError / MissingStateError The callback is missing code / state
TokenError A token request fails or a returned token is invalid
NonceError The ID token's nonce does not match
ExternalReauthError A federated token requires re-authorization (401)
JwksError The JWKS document cannot be retrieved
PublicKeyNotFoundError No EdDSA signing key is present in the JWKS
from verys_py_client import TokenError, NonceError

try:
    id_token, access_token, refresh_token = client.token_by_code(code, nonce)
except NonceError:
    ...  # possible replay / mismatched session
except TokenError as e:
    ...  # token request failed

Documentation

API reference is generated with MkDocs + mkdocstrings:

uv run mkdocs serve   # live preview at http://127.0.0.1:8000
uv run mkdocs build   # render static site to ./site

Development

uv sync             # install dependencies (including dev tools)
uv run ruff check . # lint

License

MIT © 2026 Reis McMillan

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

verys_py_client-0.1.0.tar.gz (35.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

verys_py_client-0.1.0-py3-none-any.whl (8.9 kB view details)

Uploaded Python 3

File details

Details for the file verys_py_client-0.1.0.tar.gz.

File metadata

  • Download URL: verys_py_client-0.1.0.tar.gz
  • Upload date:
  • Size: 35.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for verys_py_client-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0f1edf3db0dcd467b2847d01b11300cea6811bdd6acbdd30659171321817e23d
MD5 52d4d8a26b6d73ceefb5cfd57c37f336
BLAKE2b-256 6cb4f16823b0576ba503549ee5286c6d4fb1afc2b28173f736e6c5bd2570a355

See more details on using hashes here.

Provenance

The following attestation bundles were made for verys_py_client-0.1.0.tar.gz:

Publisher: publish.yml on Reis-McMillan/verys-py-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file verys_py_client-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for verys_py_client-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4afc71d0c9c4053508a38c053c6d0d25e4ce234b3bc29aa0b7b7b9f7308fcd62
MD5 d8f922b5448b671096a500f35f06d5b9
BLAKE2b-256 daa2692d888a333374094f78f9d8d3874f6bea0293593b11921ee6f66179914f

See more details on using hashes here.

Provenance

The following attestation bundles were made for verys_py_client-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Reis-McMillan/verys-py-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page