Skip to main content

huudis (Python)

Official Python SDK for Huudis. Works with FastAPI, Flask, Django, or anything else that speaks WSGI/ASGI.

Install

pip install forjio-huudis

Quickstart

Set env vars (or pass them to the client):

HUUDIS_ISSUER=https://huudis.com
HUUDIS_AUDIENCE=oc_your_client_id
HUUDIS_CLIENT_ID=oc_your_client_id
HUUDIS_CLIENT_SECRET=cs_...   # omit for public clients (PKCE)

Verify an access token

from fastapi import FastAPI, Header, HTTPException
from huudis import verify_access_token, HuudisAuthError

app = FastAPI()

@app.get("/me")
def me(authorization: str = Header(...)):
    try:
        claims = verify_access_token(authorization)
    except HuudisAuthError as e:
        raise HTTPException(401, detail=e.message)
    return {"user_id": claims.sub, "email": claims.email}

OIDC sign-in flow

from huudis import HuudisClient

huudis = HuudisClient()

# Step 1: redirect the user
url = huudis.authorization_url(
    redirect_uri="https://yourapp.com/callback",
    state=session["state"],
    code_challenge=session["pkce_challenge"],
)

# Step 2: exchange the code
tokens = huudis.exchange_code(
    code=request.args["code"],
    redirect_uri="https://yourapp.com/callback",
    code_verifier=session["pkce_verifier"],
)
userinfo = huudis.userinfo(tokens["access_token"])

Authorization check

result = huudis.authz_check(
    access_token=token,
    principal={"type": "user", "id": claims.sub, "accountId": claims.account_id},
    action="plugipay:DeleteInvoice",
    resource="forjio:plugipay::acc_.../invoice/inv_9F8",
)
if not result["allow"]:
    raise HTTPException(403, detail=result.get("reason"))

Call the API — every route, with the right credential

client.api has one method per Huudis API route (generated from the API spec). Each call carries the credential its route group takes: a signed-in person's session bearer; else, for programs, an IAM access key (access_key_id + secret_access_key, or HUUDIS_ACCESS_KEY_ID + HUUDIS_SECRET_ACCESS_KEY), each request signed Huudis-HMAC-SHA256 and acting as the key's user within the user's IAM policies; and for /app/*, your OIDC app's client_id + client_secret (HTTP Basic).

from huudis import HuudisClient

huudis = HuudisClient(issuer="https://huudis.com", access_key_id="AKIA…", secret_access_key="…",
                      workspace_id="acc_…")  # workspace_id is optional
users = huudis.api.iam_users()
huudis.api.iam_create_groups(name="On call")

app = HuudisClient(issuer="https://huudis.com", client_id="oc_…", client_secret="cs_…")
signed_in = app.api.app_users(status="active")

Person-only routes (password, sessions, account deletion, creating keys, …) refuse a key with PERSON_ONLY. Members, invites, SSO identity providers and member password resets need the action named in the key's policy (no wildcard); owners are emailed an undo, or must approve first — the call returns approvalRequired and the same call runs once an owner approved it. See https://huudis.com/docs/api/authentication. sign_request(...) and AccessKeyAuth (an httpx.Auth) sign requests you build yourself.

Types

Name Description
verify_access_token(header_or_token, *, issuer=None, audience=None, require_mfa=False) Module-level convenience — reads HUUDIS_ISSUER / HUUDIS_AUDIENCE from env.
HuudisClient(issuer=..., client_id=..., client_secret=..., audience=..., api_base=...) Full surface. Use as a context manager (with HuudisClient() as huudis:) or call .close().
HuudisClaims Dataclass returned by verification — sub, email, account_id, scope, mfa_verified, etc.
HuudisAuthError Raised on any failure; carries .code + .message.

JWKS is cached in-process via PyJWT's PyJWKClient.

Docs

License

MIT

Metadata

Release files for forjio-huudis 0.8.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 forjio-huudis 0.8.0
File Size Uploaded
forjio_huudis-0.8.0.tar.gz 29.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for forjio-huudis 0.8.0
File Interpreter ABI Platform
forjio_huudis-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 59.0 kB

Release files / forjio_huudis-0.8.0.tar.gz

Download URL forjio_huudis-0.8.0.tar.gz
Size 29.5 kB
Tags Source
SHA-256 checksum
How to use checksums
033883a4b0e6fac238e2409db5311d71ce36fd73435d644ece5d33f3eaaa0e60
BLAKE2b-256 checksum
How to use checksums
fadcb37abfc25b323d30f84ef671bc39f00630d76945001d64453f3ce71ca57f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / forjio_huudis-0.8.0-py3-none-any.whl

Download URL forjio_huudis-0.8.0-py3-none-any.whl
Size 29.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5aaf973a27ba1ff865b12dc79ebc133fbabdabb21adcf727c5924930cf0420c3
BLAKE2b-256 checksum
How to use checksums
6a1299509c862011376aadb2dbf71914fc55ec9cb04643de17f022120264e68e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.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