Skip to main content

Add your description here

Project description

Tenauth

pre-commit Ruff isort Commitizen Gitleaks

Tenant-aware auth and database helpers for FastAPI services. Tenauth keeps JWT parsing, access context verification, and Postgres GUC management in one place so your routes can stay focused on business logic.

Highlights

  • Bearer token parsing into typed AuthContext models without wiring boilerplate.
  • FastAPI dependencies for locking requests to tenant and user scopes.
  • Async session helpers that apply and verify Postgres GUCs on every connection.
  • DSN utilities to inject tenant metadata for workers, migrations, or tooling.
  • Tight pytest coverage with ready-to-use JWT fixtures.

Installation

uv pip sync

If uv is not available:

python -m venv .venv
source .venv/bin/activate
pip install -e .[dev]

FastAPI Quickstart

from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from sqlmodel.ext.asyncio.session import AsyncSession

from tenauth.fastapi import build_access_scoped_session_dependency, require_auth
from tenauth.schemas import AuthContext

engine = create_async_engine("postgresql+psycopg://svc@db/app", echo=False)
sessionmaker = async_sessionmaker(engine, expire_on_commit=False)

app = FastAPI()

@asynccontextmanager
async def session_factory() -> AsyncIterator[AsyncSession]:
    session = sessionmaker()
    try:
        yield session
    finally:
        await session.close()

SessionDep = build_access_scoped_session_dependency(session_factory=session_factory)

@app.get("/me")
def read_profile(auth: AuthContext = Depends(require_auth)):
    return {"user_id": str(auth.sub), "tenant_id": str(auth.tid)}

@app.get("/widgets")
async def list_widgets(session: AsyncSession = Depends(SessionDep)):
    result = await session.execute("SELECT * FROM widgets LIMIT 20")
    return result.all()

The require_auth dependency validates Authorization: Bearer headers and returns an AuthContext. build_access_scoped_session_dependency binds tenant and user IDs to the session, verifies the applied GUCs, and resets them when the request completes.

Database Sessions & Background Tasks

from tenauth.schemas import AccessContext
from tenauth.session import access_scoped_session_ctx

async with access_scoped_session_ctx(
    session_factory=session_factory,
    access_context=AccessContext(tenant_id=tenant_uuid, user_id=user_uuid),
) as session:
    await session.execute(...)

For DSN-based tooling, inject tenant metadata directly:

from tenauth.tenancy import dsn_with_tenant

tenant_dsn = dsn_with_tenant(base_dsn, tenant_uuid)

Testing

uv run pytest

Use uv run pytest -k <keyword> during focused iterations. Async cases should be marked with pytest.mark.asyncio.

Development Workflow

  • Install the Git hooks via uv run pre-commit install and run uv run pre-commit run --all-files before pushing.
  • Ruff (ruff-format, ruff-check) and isort keep the codebase consistent; they run automatically through pre-commit.
  • gitleaks guards against committing secrets, and Commitizen enforces conventional commit messages (cz commit).
  • Review additional design notes and module guides under docs/.

To preview the documentation site locally:

uv run mkdocs serve

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

tenauth-0.2.0.tar.gz (10.4 kB view details)

Uploaded Source

Built Distribution

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

tenauth-0.2.0-py3-none-any.whl (8.1 kB view details)

Uploaded Python 3

File details

Details for the file tenauth-0.2.0.tar.gz.

File metadata

  • Download URL: tenauth-0.2.0.tar.gz
  • Upload date:
  • Size: 10.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.9

File hashes

Hashes for tenauth-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2da52bfedc4fb0119153ffb24af540c11f62edca8f24018d8383c220b71c554d
MD5 0fc15a9e03fe3aecbbbf6dd49f246452
BLAKE2b-256 c0f39e819bff95f332fd2fae9a77af2ed9b5c652d254a799141200ded03b720c

See more details on using hashes here.

File details

Details for the file tenauth-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: tenauth-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 8.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.9

File hashes

Hashes for tenauth-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b763363688d6d139cfbda9ac96cf8f292c849d9a45bc42445d1031a5f5c8e2e6
MD5 3c8f307eb23f69d0d50f3b79e93b2568
BLAKE2b-256 a846885c0565ae22bb371028164ac76ccc2bad256e3d40eab2af245067a6301a

See more details on using hashes here.

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