Skip to content

Recipes

Bite-sized "I want to wire X" walkthroughs. Each page starts with what problem it solves, when to reach for it, and a complete code example you can copy verbatim.

Start here

  • Brand-new service? Follow the Tutorial » — linear, builds the Users feature step by step.
  • Just need a signature? Jump to the Reference ».
  • Wiring a specific piece? You're in the right place — the tour below is the map, and the index takes you to the full recipe.
  • Want to see it all working together? Head to the complete examples.
  • Prefer studying a guided project? See the Learning projects ».

SDK tour — one example per block

A walk through everything the tempest-fastapi-sdk offers: each block has the concept in one line, a minimal runnable example, and a link to the full recipe. Read top to bottom for the mental map, or jump to what you need — install only the extras you use (uv add "tempest-fastapi-sdk[auth,cache,queue]>=0.171.0").

Foundation

BaseAppSettings and AsyncDatabaseManager come from the SDK. The create_app() factory and run() belong to your service, not to the package: tempest new writes both (src/api/app.py and src/server.py, whose run() delegates to run_server).

from tempest_fastapi_sdk import AsyncDatabaseManager, BaseAppSettings


class Settings(BaseAppSettings):
    DATABASE_URL: str = "sqlite+aiosqlite:///./app.db"


settings = Settings()
db = AsyncDatabaseManager(settings.DATABASE_URL)

See the Tutorial and the Database recipe.

Schemas and validated fields

BaseSchema + self-describing Annotated types (money, %, slug, lat/long, and Brazilian ones: CPF/CNPJ/CEP/phone + Pix key).

from tempest_fastapi_sdk import BaseSchema
from tempest_fastapi_sdk.utils import CentsField, PixKeyField, SlugField


class ProductSchema(BaseSchema):
    slug: SlugField
    price_cents: CentsField          # int >= 0
    pix_key: PixKeyField             # CPF/CNPJ/email/phone/random

Recipes: Validated fields, Brazilian helpers.

Repository, Service, Controller

BaseRepository[Model] (CRUD + bulk ops), BaseService, BaseController with get_by_id/list/paginate/update/delete ready.

from sqlalchemy.ext.asyncio import AsyncSession

from tempest_fastapi_sdk import BaseRepository, BaseService

from src.db.models import UserModel
from src.schemas import UserResponseSchema


class UserRepository(BaseRepository[UserModel]):
    def __init__(self, session: AsyncSession) -> None:
        super().__init__(session, model=UserModel)


class UserService(BaseService[UserRepository, UserResponseSchema]):
    ...

Recipes: Tutorial, Database.

Pagination

Offset and cursor, with a Link header.

from tempest_fastapi_sdk import BasePaginationFilterSchema, CursorPaginationFilterSchema

Standardized exceptions

AppException + subclasses → the right HTTP status; register_exception_handlers(app).

from fastapi import FastAPI

from tempest_fastapi_sdk import NotFoundException, register_exception_handlers

app = FastAPI()


register_exception_handlers(app)
raise NotFoundException(message="user not found")   # -> standardized 404

Full authentication

Bundled flow: signup/activate/login/reset/email change and recovery/MFA + JWT deps (header/cookie/query).

from fastapi import FastAPI

from tempest_fastapi_sdk import UserAuthService, make_auth_router

from src.api.dependencies.resources import db
from src.core.settings import settings
from src.db.models import UserModel, UserTokenModel

app = FastAPI()


auth = UserAuthService(user_model=UserModel, token_model=UserTokenModel,
                       auth_settings=settings, jwt_settings=settings)
app.include_router(make_auth_router(auth, session_factory=db.session_dependency))

Recipes: Auth flow, MFA, Refresh tokens, Sessions.

Cache

AsyncRedisManager + @cached + CacheInvalidator (namespace/tag).

from tempest_fastapi_sdk.cache import AsyncRedisManager, cached

from src.core.settings import settings


redis = AsyncRedisManager(settings.REDIS_URL)


@cached(redis, ttl=300, namespace="products", tags=lambda a, k: [f"p:{k['pid']}"])
async def get_product(*, pid: str) -> dict: ...

Recipe: Cache.

Queues and background tasks

MessageBroker (FastStream pub/sub), TaskQueue (TaskIQ) + cron via enum/helpers, both hiding the underlying lib.

from tempest_fastapi_sdk.queue import MessageBroker
from tempest_fastapi_sdk.tasks import Cron, CronOffset, TaskQueue

from src.core.settings import settings
from src.queue import OrderPaid


mq = MessageBroker.rabbitmq(settings.RABBITMQ_URL)
tq = TaskQueue.rabbitmq(settings.TASKIQ_BROKER_URL)


@mq.on("orders.paid")
async def on_paid(event: OrderPaid) -> None: ...


@tq.cron(Cron.EVERY_WEEKDAY_9AM, cron_offset=CronOffset.BRASILIA)
async def digest() -> None: ...

Recipes: Queues and Tasks, Outbox.

Real time

SSE (EventStream/SSEBroker with backpressure), WebSocket router, Web Push.

import asyncio

from fastapi import FastAPI
from fastapi.responses import StreamingResponse

from tempest_fastapi_sdk import EventStream

app = FastAPI()


@app.get("/events")
async def events() -> StreamingResponse:
    """Stream one tick per second until the client disconnects.

    Returns:
        StreamingResponse: The SSE response. ``on_disconnect`` cancels the
        publisher, so it never outlives the connection.
    """
    stream = EventStream()

    async def pump() -> None:
        """Publish a tick every second."""
        while True:
            await stream.publish({"tick": True}, event="tick")
            await asyncio.sleep(1)

    task = asyncio.create_task(pump())
    return stream.response(on_disconnect=task.cancel)

Recipes: SSE, WebSocket, Web Push, Real time.

Observability

Structured logging + /logs, CPU/RAM/GPU metrics + Prometheus /metrics, request-id, OTel tracing, health + tool-spec.

from fastapi import FastAPI

from tempest_fastapi_sdk import RequestIDMiddleware, make_health_router

from src.api.dependencies.resources import db

app = FastAPI()


app.add_middleware(RequestIDMiddleware)
app.include_router(make_health_router(checks={"db": db.health_check}))

Recipes: Logging, Metrics, Observability.

HTTP hardening

Rate limit (sliding window), idempotency, CSRF, CORS, body-size limit, hardened static files.

from fastapi import FastAPI

from tempest_fastapi_sdk import IdempotencyMiddleware, RateLimitMiddleware

app = FastAPI()


app.add_middleware(RateLimitMiddleware, store=..., max_requests=100, window_seconds=60)
app.add_middleware(IdempotencyMiddleware, store=...)

Recipes: HTTP layer, Idempotency, Security.

Files

UploadUtils (local/MinIO), DownloadUtils, FileStoreUtils (facade), MinIO/S3 storage, presigned URLs.

import asyncio

from fastapi import UploadFile

from tempest_fastapi_sdk import FileStoreUtils

upload_file: UploadFile = ...  # comes from the endpoint signature


store = FileStoreUtils(source="./uploads")     # or an AsyncMinIOClient


async def main() -> None:
    """Run this example."""
    key = await store.save(upload_file)


asyncio.run(main())

Recipes: File store, Uploads, Downloads, Storage.

Domain extras

Feature flags, audit trail, multi-tenant, offline-first sync, server-side sessions, typed HTTP client, i18n error envelopes.

from tempest_fastapi_sdk import FeatureFlags, make_flag_dependency

Recipes: Feature flags, Audit trail, Multi-tenant, Offline sync, HTTP client.

Self-hosted generative AI

Hardware check, local LLM, embeddings, RAG (web + PDF) — all on your own hardware.

Installation

The core ships with tempest-fastapi-sdk. Self-hosted generative AI needs the [genai] extra — uv add "tempest-fastapi-sdk[genai]" (pulls in torch, transformers, accelerate, safetensors and huggingface-hub).

import asyncio

from tempest_fastapi_sdk.genai import can_run, TextGenerator
from tempest_fastapi_sdk.genai.rag import PdfReader, build_context


async def main() -> None:
    """Run this example."""
    if can_run(model_id="Qwen/Qwen2.5-7B-Instruct").fits:
        gen = TextGenerator("Qwen/Qwen2.5-7B-Instruct", quantization="int4")
        chunks = PdfReader().chunks("/kb/manual.pdf")
        answer = await gen.generate(build_context("how to refund?", chunks))


asyncio.run(main())

Recipe: Self-hosted generative AI.

Long work, with status and cancellable

JobStore gives the work a row the screen reads; run_cancellable actually interrupts it when the user gives up. StageMap covers the case where the stages decorate a record the screen already fetches.

import asyncio
from uuid import UUID

from tempest_fastapi_sdk.db import AsyncDatabaseManager
from tempest_fastapi_sdk.tasks import (
    BaseJobModel,
    JobStore,
    StageInterruptedError,
    run_cancellable,
)


class JobModel(BaseJobModel):
    """A unit of long-running work."""

    __tablename__ = "jobs"


db = AsyncDatabaseManager("sqlite+aiosqlite:///./app.db")
store: JobStore[JobModel] = JobStore(db, model=JobModel)


async def transcribe(path: str) -> str:
    """Long, cancellable work (async I/O).

    Args:
        path (str): The file to process.

    Returns:
        str: The text.
    """
    await asyncio.sleep(0)
    return path


async def run(job_id: UUID) -> None:
    """Run the job, giving up if it is cancelled midway.

    Args:
        job_id (UUID): The job to run.
    """
    if await store.claim(job_id) is None:
        return
    try:
        text: str = await run_cancellable(
            transcribe("audio.wav"),
            interrupted=store.cancellation_watch(job_id),
        )
    except StageInterruptedError:
        return
    await store.succeed(job_id)
    print(text)

Recipe: Jobs (long work with status).

Hosted AI, and what it cost

OpenAICompatGenerator speaks any /chat/completions (DeepSeek, Groq, OpenRouter, vLLM, Azure); AIUsageStore keeps one row per paid call, for the "which account spent what" question.

import asyncio
from uuid import uuid4

from tempest_fastapi_sdk.db import AsyncDatabaseManager
from tempest_fastapi_sdk.genai import (
    AIUsageStore,
    BaseAIUsageModel,
    OpenAICompatGenerator,
    TokenUsage,
)


class AIUsageModel(BaseAIUsageModel):
    """One billed AI call."""

    __tablename__ = "ai_usage"


db = AsyncDatabaseManager("sqlite+aiosqlite:///./app.db")
gen = OpenAICompatGenerator(
    "deepseek-flash",
    api_key="sk-...",
    base_url="https://api.deepseek.com",
)
store: AIUsageStore[AIUsageModel] = AIUsageStore(
    db, model=AIUsageModel, price_input_per_1k=0.00014
)


async def main() -> None:
    """Run this example."""
    text: str
    usage: TokenUsage | None
    text, usage = await gen.generate_with_usage("Summarize this.")
    await store.record(subject_id=uuid4(), service="summary", usage=usage)
    print(text)


asyncio.run(main())

Recipe: Self-hosted generative AI.

Admin panel

AdminSite + AdminModel + make_admin_router (Jinja+HTMX, themes, actions, upload, filters).

Recipe: Admin panel.

SSR and vision

Typed SSR (Page/html_response) over tempestweb; computer vision (Detector/Classifier/Segmenter) via ort-vision-sdk.

Recipes: SSR, Vision.

CLI and deploy

tempest new (scaffold), tempest db (migrations), tempest user, tempest secrets, quality gates; safe deploy (migrations + graceful shutdown).

tempest new my_service && cd my_service
tempest db init && tempest db upgrade
tempest check          # ruff + mypy + tests

Recipes: CLI, Safe deploy.

Recap

The SDK covers the whole lifecycle of a FastAPI service: typed foundation → persistence → auth → cache → background → real time → observability → hardening → files → AI → admin → CLI/deploy. Each section above points at the recipe with the full guide. Start from the Tutorial and come back here to plug in each capability as you need it.

Recipe index

Theme Covers
Admin site » AdminSite, AdminModel, make_admin_router, BaseUserModel
Admin SQL console » SqlShellService + SqlShellPolicy (capabilities, allowed/denied tables, row cap, require_where), real parsing via sqlglot, every attempt audited, opt-in admin page
AI agents » Agent (goal → trace + artifacts), AgentBudget (steps/time/calls), AgentTool + ready-made tools over image/vision/audio/RAG, InMemoryAgentRunSink / DbAgentRunSink, make_agent_router
AI agents (advanced) » typed structured output (run_structured), three memory layers (scratchpad_tools / fact_tools / recall_prompt), on-demand Skill, agent_tool delegation, run_until / refine
AI agents (architecture) » how to lay out a service with agents: the ai layer beside services, runtime with one generator per process, tools apart from agents, views and policy, the controller that seeds identity, and when to trade one agent for skills
AI agents (concepts) » the loop step by step, the transcript the model receives on each turn, the vocabulary (step, observation, artifact, budget, stop_reason), why the context grows and what that costs, and when to reach for a tool, a skill, delegation or a loop
AI agents (database) » a tool that queries the database: db.get_session_context() per call, the from_session convention, one AsyncDatabaseManager per process, and what AgentContext carries (state with who is asking, artifacts, deadline)
AI agents (prompts) » the src/ai/prompts/ folder (one file per agent + base.py), what the model actually receives (system, goal and specs via ScriptedBackend), anatomy of a prompt, DEFAULT_SYSTEM_PROMPT / skills_prompt / DEFAULT_CRITIC_PROMPT, per-request prompts with facts_prompt (measured cost of building the Agent) and how to test the prompt
AI agents (testing) » ScriptedBackend / replies / replies_with_tool to script the model's decisions, assert_completed / assert_used_tools / assert_artifact, FailingBackend, and the separate @model layer
AI agents (tools) » a tool that calls an API (the process's httpx.AsyncClient, a timeout below the budget, 4xx/5xx/timeouts becoming AgentToolError, tests with httpx.MockTransport), a tool that structures text (schema_of, final_answer_tool, ToolResult(final=True)), typed_tool over a bound method and text_tool
App error reports » make_app_error_model (nullable user FK, SET NULL, indexed created_at), AppErrorService (truncate-never-refuse), opt-in admin listing, half-open date range
Audit trail » BaseAuditLogModel, add_audited / update_audited / delete_audited, snapshot_model / diff_snapshots
Auth flow (signup/reset) » UserAuthService, make_auth_router — signup / activation / login / password reset, token delivery (bearer/cookie/both), BaseUserModel
Brazilian helpers » CPF / CNPJ / CEP / phone validation + normalization, including mobile-only (is_valid_mobile_phone_br, MobilePhoneBRField) and parse_phone_br (area code, number, E.164)
Cache » AsyncRedisManager (+ client_proxy, for stores built at import time), @cached decorator, CacheInvalidator (tag/namespace)
Chat (conversations + messages) » ChatService, make_chat_router, base tables + real-time fan-out via SSEBroker
Choosing a model » TextModel / EmbeddingModel / RerankerModel / VisionModel / ImageModel / SpeechToTextModel / TextToSpeechModel — named Hub ids and the use-case table behind each pick
CLI » tempest new / db (+ seed) / user / secrets rotate / lint / fix / format / type / test / check
Comments + ratings » ReviewService, make_reviews_router, 0–5 star scores with aggregation, threaded comments
Computer vision (ONNX) » Detector / Classifier / Segmenter + prediction schemas
Data subject export and erasure (LGPD) » SubjectGraph (the tables a subject's DELETE reaches by cascade, derived from MetaData), export without secret columns, violations + assert_subject_graph_valid as a CI guard, SubjectObjectStorage (per-subject prefix, batch delete_all)
Database » BaseModel, AsyncDatabaseManager, BaseRepository (CRUD + filters + bulk), offset/cursor pagination, mixins, AlembicHelper, SlowQueryLogger
Downloads » DownloadUtils — file_response, stream, build_content_disposition, path-traversal safe
Enum columns (safe on both databases) » Mapped[MyEnum] storing the value, native ENUM on PostgreSQL and a CHECK on SQLite, enum_column(), op.replace_enum + sync_enum_types for the migration autogenerate cannot see
Errors in OpenAPI (Swagger) » error_responses, @raises, TempestAPIRouter, ErrorResponseSchema, tempest openapi-errors --fix
Face recognition » FaceRecognizer (detect / embed / compare), compare_faces, 16 MB or 191 MB packs, no opencv and no torch
Fakes (no real provider) » FakePixProvider, FakeCardProvider, FakePayoutProvider, FakeTextBackend, FakeModerationBackend, FakePushDispatcher, FakeEmailUtils, FakeGeocodingBackend, FakeRoutingBackend, FakeWebSearchBackend, FakeObjectStorageClient — eleven seams with no credential and no network, steerable (advance, flag, fail_next) and inspectable
Feature flags » FeatureFlags, env/Redis/composite backends, make_flag_dependency
File store (unified) » FileStoreUtils — upload + download + presign over a single backend
Firebase auth (ID token) » FirebaseAuth, FirebaseIdentity, FirebaseUserResolver — verify the ID token a mobile app sends, idempotent initialization, one code per failure, [firebase] extra
Forms from Pydantic schemas » form_for / form_spec_for / render_form, parse_form + FormResult (per-field errors, input preserved), form_dependency (no Request in the route), hidden fields, UploadFile uploads, type-to-control mapping, json_schema_extra={"ui": ...}, form_stylesheet
Geolocation (distance + travel time) » haversine_km, estimate_travel, OSRMBackend, NominatimBackend, GeoPointMixin / GeoRepositoryMixin, CachedGeocodingBackend (pluggable geocoding cache)
Host control (files, commands, power) » HostBridge + HostBridgeConfig / HostBridgeSettings (power, files, PDFs, commands, native picker), make_hostbridge_router with required auth and an opt-in destructive side, sandboxed WSL/Windows paths
Hosted generative AI (Anthropic, OpenAI, DeepSeek) » AnthropicGenerator (Messages API) and OpenAICompatGenerator (OpenAI, DeepSeek) behind the same protocols as Ollama — generate/chat/stream, chat_with_tools, chat_structured; OpenAICompatEmbedder; HostedGenAISettings + *_kwargs(); typed errors (HostedAuthenticationError, HostedRateLimitError, HostedServerError)
HTTP client (outbound) » HTTPClient — typed httpx with retry/backoff, circuit-breaker, X-Request-ID; RetryPolicy, CircuitOpenError
HTTP layer » apply_cors, RequestIDMiddleware, RateLimitMiddleware (429 in the SDK error envelope), make_health_router, JWT / role / permission dependencies, webhook signature verifier, pagination Link headers, tool-spec router
Idempotency » IdempotencyMiddleware, MemoryIdempotencyStore / IdempotencyStore (Redis) — safe replay of POST/PUT/PATCH/DELETE
Image generation (local) » ImageGenerator (local diffusers — generate / edit img2img), ImageGenerationConfig, GeneratedImage carrying the reproducing seed, make_genai_router(image_generator=...) → POST /image
Integration client (OpenAPI) » tempest openapi-client — Pydantic schemas + a typed client from a third party's spec
Introspection auth (resource server) » IntrospectionAuth — validate an opaque bearer by asking the upstream identity provider
Jobs (long work with status) » BaseJobModel + JobStore — one row per unit of work, claim/succeed/fail, watch for the screen, reclaim_stale; cooperative cancellation (cancel + run_cancellable); StageMap for several stages on the record itself
Kestra (workflow orchestrator) » trigger a flow from the service (HTTPClient + webhook trigger or execution API, tenant path measured), a flow calling a route protected by make_token_dependency, and outbox (OutboxRelay) + WebhookInbox for guaranteed delivery; run against Kestra 2.0.6
Logging » LogUtils, structured JSON logging, request-ID propagation
Management commands (tempest <cmd>) » register your own commands on the project's tempest CLI
Mercado Pago (Pix, cards, boleto) » MercadoPagoClient (132 operations generated from the provider's own OpenAPI, without the discontinued Payments API), MercadoPagoPixProvider + MercadoPagoCardProvider (Pix and card through the Orders API, a card decline as a result, authorize and capture, partial refunds), make_mercado_pago_webhook_delivery_dependency (a webhook that re-reads the order), AuthenticatedUser, to_cents / from_cents (reais, not cents), make_mercado_pago_webhook_dependency, MercadoPagoSettings, x_idempotency_key per call
Mercado Pago (test accounts and credentials) » step by step to create a test seller and find the right token (Checkout Transparente / Orders API), what the payer needs, test cards, and the table of errors each detour produces
Mercado Pago (testing webhooks) » a local signed simulation with sign_manifest re-reading a real sandbox order (no public URL), the four cases the route must get right, the dashboard's simulation and a real delivery through a tunnel
Metrics » MetricsUtils — CPU / RAM / disk / GPU snapshots
MFA (TOTP / 2FA) » MFAMixin, TOTPHelper, enroll/confirm/verify/disable endpoints on make_auth_router, recovery codes
Migrations » AlembicHelper.sync_schema() / adopt() / base_revision() / has_existing_schema() — how the schema comes into being, adopting a pre-Alembic database, and why create_tables() + stamp("head") breaks silently
Model weights (Hub lifecycle) » ModelRef (revision / local_files_only / trust_remote_code), resolve_revision, download_model with a disk preflight, list_cached_models / remove_cached_model, tempest model pull / cache-list / cache-rm
Modelops (export, bench, quantization) » benchmark_onnx (latency/RAM/GPU/energy), export_onnx_to_ort, quantize_onnx_dynamic, quantize_hf_onnx, rank + Pareto frontier, tempest model
Multi-tenant » TenantScopedRepository — tenant_id isolation on every query
n8n (workflow automation) » call the Webhook node with HTTPClient + Header Auth (immediate response or Respond to Webhook, test vs production URL), the HTTP Request node calling a route protected by make_token_dependency, and outbox + WebhookInbox; run against n8n 2.43.7
Object-level permissions » permission (rule decorator), has_perm / check_permission, PermissionRegistry, make_permission_checker, PermissionMixin
Observability (tracing) » setup_tracing (OpenTelemetry), SlowQueryLogger
Offline-first sync (delta) » BaseRepository.changes_since, SyncFilterSchema, SyncPaginationSchema, cursor deltas + soft-delete
OpenPix (Pix via Woovi) » Layered architecture, opening a charge, verified webhook + API read-back, reconciliation, refunds, OpenPixEnvironment, to_cents
OpenPix (subscriptions and plans) » SubscriptionPayload, RECURRENT vs PIX_RECURRING (Pix Automático), lifecycle and instalments, the plan that lives in your database
PDF generation » PdfRenderer, five bundled documents (receipt/quote/report/contract/voucher) with Pydantic schemas, make_pdf_router, tempest pdf render, asset policy
Permission guards (@requires) » @requires plus (user) -> user guards (with an optional meta: dict[str, Any] via meta= / include_args=), TempestPermissionError, GuardContractWarning, tempest permissions --check
Pix protocol (one contract, many providers) » PixProvider (Protocol: create / get / cancel / parse_webhook), PixCharge / PixChargeRequest / PixPayer field by field, canonical PaymentStatus beside the raw provider_status, the six PixEventTypes, OpenPixPixProvider and MercadoPagoPixProvider, PixProviderRouter to migrate provider by slices of orders, confirm_pix_payment + claim_once to release an order only after reading the charge back, and only once — plus how to write your own adapter, with an in-memory fake for testing without a network
Push (web + mobile) » DeviceService, PushDispatcher, WebPushTransport / FCMTransport, BaseDeviceTokenModel, make_push_router — one call for browsers and phones, with unified pruning of dead devices
Query plans (EXPLAIN) » explain_queries() captures the block and explains on exit, EXPLAIN ANALYZE on PostgreSQL / EXPLAIN QUERY PLAN on SQLite, writes never re-executed, report.slowest
Queue & Tasks » FastStream (AsyncBrokerManager), TaskIQ (AsyncTaskBrokerManager), AsyncTaskScheduler, transactional outbox
React SPA on FastAPI » make_spa_router — serve the Vite build from the same process, with history fallback
Real-time » Overview — when to choose SSE, WebSocket or Web Push
Receiving WhatsApp messages (zap-api) » make_zap_webhook_dependency — HMAC over the raw body, ZapWebhookDelivery with inbound / status already parsed by event, enums (ZapWebhookEvent, ZapInboundMediaType, ZapJidServer, ZapOutboundKind) to dispatch without loose strings, a full model → repository → service → controller → router layer, is_forward_transition against out-of-order callbacks, media via get_message_media
Refresh tokens (rotation/revocation) » BaseUserRefreshTokenModel, make_user_refresh_token_model, issue_token_pair, rotation + family reuse detection
RevenueCat (in-app subscriptions) » make_revenuecat_webhook_router (Authorization header + optional HMAC, empty secret refuses all, records once), WebhookInbox + BaseWebhookEventModel (idempotent inbox for any provider: claim, effect and mark in one transaction, max_attempts → FAILED), normalize → SubscriptionSnapshot over all 21 documented event types, RevenueCatClient.get_subscriber, RevenueCatSettings, FakeRevenueCatClient
Safe deploys » AlembicHelper.safe_upgrade (blocks DROPs), GracefulShutdownMiddleware
Security » AttemptThrottle, opaque-token helpers, HardenedStaticFiles, security headers
Self-hosted generative AI » probe_hardware / can_run, TextGenerator, Embedder, RAG (web + PDF), audio (STT/TTS + batching), make_genai_router; hosted backend (OpenAICompatGenerator, any /chat/completions) with TokenUsage, cached prefix included; list output (parse_structured_list, retry at a rising temperature) and object output (extract_json_object); per-user usage accounting (AIUsageStore)
Server-Sent Events (SSE) » EventStream, sse_response, ServerSentEvent, SSEBroker (per-channel fan-out, Redis bridge)
Server-side sessions » SessionMiddleware, SessionAuth, make_session_router, MemorySessionStore / RedisSessionStore
Social login (OAuth2/OIDC) » AUTH_OAUTH_ENABLED + oauth_clients= (four /auth/oauth/* routes), OAuthSettings, make_user_oauth_account_model, NameMixin, GoogleOAuthClient, GitHubOAuthClient, OIDCProvider, OAuthUser, OAuthClient, generate_oauth_state
Spreadsheets (.xlsx) » SheetWriter (row cursor), Column (width/mask/alignment), SheetStyle as plain data, BR_* formats pinned to pt-BR, new_workbook / workbook_to_bytes; reading .xlsx with typed cells (read_xlsx_as, read_xlsx_sheets) and a public Google Sheet validated into a schema (read_google_sheet_as, or the whole workbook with read_google_sheet_xlsx)
SSR (typed pages) » Page, html_response, make_htmx_router, hosting a tempestweb build
SSR actions (confirmation, flash, redirect back) » form_for(..., confirm=...) / confirm() without inline JS, FlashMiddleware + flash / get_flashes + FlashMessages (signed read-once cookie), redirect_back against open redirects, register_html_error_handlers (error page on GET, flash + 303 on POST, JSON for the API)
Storage (MinIO/S3) » AsyncMinIOClient, MinIOUploadStorage, presigned_get_url / presigned_put_url, list_objects
Stored file (service mixin) » StoredFileServiceMixin — set_file / replace / clear_file over UploadUtils
Stripe (cards + subscriptions) » StripeClient, stripe_http_client, to_minor_units / from_minor_units, make_stripe_webhook_dependency, StripeEvent — form-encoded writes, idempotency by default, zero-decimal currencies
System checks (check-config) » run_system_checks, @check, CheckMessage, tempest check-config — validate settings before serving
tempestweb frontend + SDK » tempestweb frontend calling the SDK backend: tempestweb.native.http, Idempotency-Key + IdempotencyMiddleware, retry, same origin vs CORS
Testing » make_test_session, make_test_database, in-memory SQLite, pytest fixtures
Text search (LIKE + full-text) » portable search() (escaped ILIKE, AND across words), full_text_search() with websearch_to_tsquery + ts_rank on PostgreSQL, TextSearchLanguage / TextSearchWeight / TokenMatch, conditions that feed where=
Transactional email » EmailUtils — SMTP, text/HTML body, attachments, Jinja2 templates
Transactional outbox » BaseOutboxModel, OutboxRelay, save_with_outbox — reliable events
Transactions (commit and savepoint) » session-shared transaction(), commit() / flush() / rollback() on the repository, autocommit=False, savepoint() for the recoverable step
Transcription pipeline (audio → summary) » the three stages stitched together: StageMap on the record itself, cancelling a running transcription from inside on_progress, generate_with_usage + AIUsageStore to know who paid, generate_structured_list for the stage that returns a list
Typed CSS (stylesheet and tokens) » StyleSheet / Rule / Media, ThemeTokens (tempest_core tokens as CSS variables, light and dark), make_css_router with ETag/304 and a versioned URL (sheet.url(), immutable cache), the font family as a token, app_stylesheet, a cls() that rejects an unknown class
Typing (static + runtime) » strict_types / typed / require_annotations, [tool.tempest] typing_strictness knob, ruff ANN
UI layer (pages and components) » the src/ui/ layer (pages, layout, components, styles), Page + inherited shell(), Card / Alert / DataTable (with TableColumn for a link/form in a cell) / Pagination / EmptyState / NavBar, Shell (including width="full") / Grid, scaffolding with tempest new --extras "ssr"
Uploads (backends) » UploadUtils, extension/MIME validation (sniff_mime), local / MinIO backends
Utilities » utcnow/to_utc, modify_dict, get_client_ip, opaque tokens (generate_opaque_token)
Validated fields (ready-made types) » Annotated Pydantic types — PositiveIntField / CentsField / PriceField / SlugField / HexColorField / CPFField / UFField
Versioned artifacts (models) » ArtifactRegistry, ArtifactVersionMixin, build_manifest_entries, file_digest — swap the active version without a redeploy
Wallet and Pix payouts » WalletService (credit, debit and withdrawal in a single UPDATE, hold inside the debit), WalletBalanceMixin, BaseWalletEntryModel, claim_once, split_net / openpix_fee_cents in basis points, OpenPixPayoutProvider, make_wallet_router
Web Push » WebPushDispatcher, VAPID schemas, broadcast with pruning
WebAuthn / passkeys » WebAuthnService, make_web_authn_credential_model, registration + passwordless login, memory/Redis challenge store
WebSocket client (AsyncAPI) » tempest asyncapi-client — a typed socket client from an AsyncAPI 3 document
WebSocket router » WebSocketHub, make_websocket_router, broadcast / send_to, heartbeat, bearer auth
WhatsApp (zap-api) » ZapClient over the in-house gateway — 27 generated operations, asynchronous send (202 + enqueued row), one idempotency_key per message, session and pairing QR

Complete examples

The recipes show one piece at a time. These pages combine several into a flow that runs end to end — read them when you want the integration decisions, not the isolated API.

Example What it combines
Full store admin » audit history + FK autocomplete + inlines + business cards + CSV import + granular RBAC + lenses
Fullstack web (SSR, WASM, server) » the three ways to talk to tempestweb: SSR + HTMX, WASM SPA and server-mode
GenAI flows » hardware capacity → local LLM → embeddings/RAG → audio, self-hosted end to end
Neighborhood marketplace » geo (nearby sellers, distance/time) + real-time chat + live notifications + star ratings
Pix checkout » JWT auth + validated fields (PixKeyField) + cache + transactional outbox + MessageBroker + TaskQueue + SSE + Web Push

Anatomy of a recipe

Every recipe follows the same four-section shape so you can skim:

  1. What it solves — one paragraph in plain language.
  2. When to use it — bullet list of situations + when not to.
  3. The code — complete, runnable, with # 1. setup / # 2. wire / # 3. test annotations.
  4. Gotchas — production caveats, security defaults, scaling notes.

If you spot a recipe that doesn't follow this shape, open an issue — we treat docs regressions like code regressions.