Skip to content
Back to skills

Best Practices Fastapi

ASecurity

FastAPI best practices for Python control-plane services, async eval APIs, Pydantic contracts, OpenAPI surfaces, security dependencies, deployment handoffs, and Flask fallback adapters. Use when building, reviewing, or converting FastAPI/Flask services, especially skill-backed cyber-safety eval control planes.

  • 6 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added September 11, 2026
devopspythongobashfastapiflaskkubernetesazureterraformgitapi

Works with

  • api
  • mcp

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned September 11, 2026

npx -y skills add grahama1970/agent-skills --skill best-practices-fastapi --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Best Practices Fastapi?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Best Practices Fastapi
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/grahama1970-best-practices-fastapi/badge)](https://www.skillsdirectory.com/skills/grahama1970-best-practices-fastapi)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: best-practices-fastapi
description: >
  FastAPI best practices for Python control-plane services, async eval APIs,
  Pydantic contracts, OpenAPI surfaces, security dependencies, deployment
  handoffs, and Flask fallback adapters. Use when building, reviewing, or
  converting FastAPI/Flask services, especially skill-backed cyber-safety eval
  control planes.
triggers:
  - best practices fastapi
  - best-practices-fast-api
  - fastapi service
  - fastapi control plane
  - fastapi deployment
  - flask fallback
  - convert fastapi to flask
  - pydantic api contract
provides:
  - fastapi-service-standards
  - pydantic-api-contracts
  - flask-fallback-adapter
  - deployment-question-contract
composes:
  - best-practices-python
  - best-practices-security
  - terraform
  - ops-terraform
  - agentic-evals
complies:
  - best-practices-skills
  - best-practices-python
  - best-practices-security
runtime_self_improvement: basic
taxonomy:
  - python
  - api
  - security
  - deployment
  - evaluation
disciplines:
  - engineering-standards
  - developer-tooling
  - compliance-security
---

# FastAPI Best Practices

Use this when building Python API services where the real product is a typed,
auditable control plane, not framework ceremony.

## Default architecture

Keep the core framework-neutral:

```text
contracts.py          # Pydantic request/response/receipt models
service.py            # business logic and skill orchestration
adapters/fastapi.py   # primary async HTTP adapter
adapters/flask.py     # fallback sync adapter over the same core
```

FastAPI is the primary adapter for async jobs, OpenAPI, dependency injection,
streaming status, and Pydantic validation. Flask is a fallback adapter only when
a team requires Flask.

## Required rules

- Pydantic models define every request, response, receipt, and error boundary.
- No loose `dict` contracts below the adapter layer.
- Endpoints call service functions; service functions do not import FastAPI.
- Async endpoints must not run blocking subprocess or network calls in the event
  loop; use a bounded worker, task queue, or explicit thread/process boundary.
- Auth is a dependency, not repeated route code. Start with API key for demos;
  upgrade to OAuth2 scopes when the environment requires it.
- Every external tool/skill call returns a receipt path or typed result object.
- Use `$memory` as the default persistence boundary for agent evidence, receipts,
  source packs, eval results, and retrieval state. That means writes go through
  `/memory` `/store` or `/upsert`; do not write raw AQL from the app, do not call
  Qdrant directly, and do not store embedding arrays in ArangoDB. ArangoDB holds
  canonical documents/edges; Qdrant holds vectors via Memory semantic sync.
- Do not add a second database for this demo. The point is to show Graham's
  Memory-native method, not a generic web-app storage pattern.
- Terraform stays outside the app: use `$terraform` for scaffold/plan/apply and
  `$ops-terraform` for detection/check/plan summaries. Never reimplement
  Terraform inside FastAPI.
- `/docs` is acceptable for an interview demo; lock it down or disable it for a
  production deployment.
- When `/docs` is the demo surface, make OpenAPI carry the story: concise
  Markdown `description`, purpose-named `openapi_tags`, route `summary` and
  `description`, reusable request examples, `tryItOutEnabled`, request duration
  display, and a real API-key security scheme so Swagger has one **Authorize**
  flow instead of repeated header fields.

## Swagger/OpenAPI as a demo harness

Use standard Swagger UI before building a custom frontend when the audience
needs to inspect and execute API contracts. The minimum useful layer is:

1. `FastAPI(description=...)` with a short mission, quickstart, skill chain, and
   explicit non-claims.
2. `openapi_tags` that group routes by user meaning, not default module names.
3. Route-level `summary` and `description` that state what skill boundary is
   crossed and what the endpoint deliberately does not prove.
4. `Body(..., openapi_examples={...})` for every non-trivial request body so a
   live demo uses named dropdown scenarios instead of hand-typed JSON.
5. `swagger_ui_parameters={"tryItOutEnabled": True, "displayRequestDuration": True,
   "docExpansion": "list"}` for low-friction interview walkthroughs.
6. A dependency-backed API-key scheme, such as `APIKeyHeader` plus `Security`, so
   Swagger exposes one **Authorize** button.
7. One optional zero-body readiness route, for example `/v1/eval/test-all`, only
   when it composes already-existing checks. Do not add a new backend subsystem
   just to make a demo button.
8. If a project agent must operate Swagger, inject stable `data-qid` attributes
   into the generated page and keep the injector tiny: authorize input/button,
   operation blocks, summaries, and the visible Execute/Try-it-out controls.
9. If a human must jump from Swagger to code, use FastAPI/OpenAPI's built-in
   `externalDocs` route metadata for a stable GitHub/source link.
10. If a project agent must jump from a route to local code, add
   `x-code-location` to each OpenAPI operation with `file`, `line`, `symbol`,
   and a `$debugger open ... --function ... --bridge` command.
11. If an endpoint returns a generated artifact such as SVG, HTML, JSON, or a
   report, also add `x-artifact-location` with the artifact file, line, source
   link, and `$debugger open ... --line ... --bridge` command. The endpoint
   handler and the returned artifact both need a local code jump.
12. If live editing matters, add a small `/docs` polling script that fetches
    `/openapi.json` with `cache: 'no-store'` and reloads only when that schema
    changes. Uvicorn reload restarts the server; it does not refresh an already
    open Swagger browser tab.

Do not build a bespoke dashboard until standard OpenAPI cannot answer the
interview question. The machine-facing contract is `/openapi.json`; Tau, MCP
bridges, OpenAI Actions, or other agent harnesses can consume that schema
directly. Swagger is for humans, OpenAPI is for agents.

## Cyber-safety eval control-plane slice

For an OpenAI-relevant prep artifact, v1 should do only this:

1. `POST /eval/batch` accepts a Pydantic batch request.
2. The service runs one authorized skill path, such as bounded `$hack` probe or
   Tau-owned model-review lane.
3. Each item returns request hash, response/finding, provider or skill identity,
   placement/deployment decision, status/error, timing, monitor events, and
   receipt/proof refs.
4. Durable artifacts are stored through `$memory`: ArangoDB for canonical
   documents/edges, Qdrant for semantic retrieval metadata managed by Memory.
5. At least one success and one forced failure both produce schema-valid
   receipts.
6. `$agentic-evals` retains the live-path proof.

Add extra endpoints only after that vertical slice works.

## Persistence boundary

For Graham's OpenAI prep artifact, the persistence answer is the existing
Memory stack:

- Authorization manifests, workload records, permits, monitor events, eval runs,
  and receipt envelopes are graph-shaped audit records. Store them as ArangoDB
  documents plus edge collections through `$memory`.
- Retrieval over prior evals, sources, findings, and interview prep should use
  `$memory recall`, which combines BM25, graph traversal, and Qdrant dense
  search.
- Qdrant is not the app database. It stores vectors and payload metadata through
  Memory semantic sync.
- Do not spend interview scope explaining or maintaining an unrelated relational
  datastore. Show the graph/evidence system Graham already uses.

## Deployment questions to ask first

Ask the team before writing infrastructure:

- Where should the service run: local, Azure Container Apps, AKS, internal
  Kubernetes, VM, or another platform?
- What network boundary is required: public, private ingress, VNet/VPC-only, or
  existing internal gateway?
- Which secrets store owns credentials?
- Is `/docs` allowed in the target environment?
- Who can submit eval jobs, read results, run `$hack`, and request deploy plans?
- Is deployment plan-only, human-approved apply, or handed to an internal
  platform team?

## Flask fallback / conversion feature

Do not rewrite business logic for Flask. Convert only the adapter:

```bash
./run.sh convert-to-flask fixtures/route_manifest.json --out /tmp/flask_app.py
```

The route manifest declares HTTP routes and Pydantic model names. The generated
Flask adapter imports the same `contracts.py` and `service.py`, validates input
with Pydantic, calls the same service function, and serializes the same response
model.

Use Flask fallback when:

- the team already standardizes on Flask;
- the service must fit a Flask monolith; or
- FastAPI is rejected for deployment policy reasons.

Do not promise full async parity in Flask. If the service function is async,
provide a deliberate sync facade or keep FastAPI.

## Interview wording

Say:

> I do not know your internal Astra architecture. I built this to show how I
> work: typed Python contracts, authorized cyber probes, governed model-review
> lanes, retained eval proof, and deployment kept as a Terraform handoff.

Do not say this matches OpenAI internals, evaluates Astra directly, or proves a
production deployment until those facts are verified in the target environment.

Files in this skill

  • SKILL.md9.2 KB
  • fixtures/agentic_eval.json7.2 KB
  • fixtures/invalid_route_manifest.json264 B
  • fixtures/route_manifest.json357 B
  • run.sh502 B
  • sanity.sh1.8 KB
  • scripts/convert_to_flask.py4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.