fastapi-architect — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited fastapi-architect (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Targets FastAPI 0.136 on Python 3.14. Companion to python-architect and sql-architect (data access via psycopg + .sql files). Implementation skeletons in RECIPES.md; pinned deps in STACK.md.
One folder per bounded context. Each feature owns its router, service, repo, schemas, and SQL files. Full tree in RECIPES.md.
service.py; never reaches into repo.py directly./v1/users, /v1/orders. Mount each version's routers under a v1_router = APIRouter(prefix="/v1"). Deprecate by mounting /v2 alongside, never by mutating /v1.main.py.tags=["users"]) — drives OpenAPI grouping.user_id: UUID) — FastAPI validates and parses for free.response_model=UserResponse) — sets the contract and trims extra fields automatically.status_code=status.HTTP_201_CREATED).Three shapes per resource: <Resource>Create (POST body), <Resource>Update (PATCH partial), <Resource>Response (response body). Example in RECIPES.md.
@field_validator for per-field, @model_validator(mode="after") for cross-field invariants.async def get_db() -> AsyncIterator[AsyncConnection]: ....get_current_user depends on decode_token depends on get_settings. FastAPI resolves the graph and caches per-request.Lifespan context is the only place to open/close shared resources (DB pool, HTTP client, cache, message bus). Never in module-level code or @app.on_event (deprecated). Settings loaded at startup, validated once via pydantic-settings. Skeleton in RECIPES.md.
Patterns (in-house JWT vs external IdP, Argon2id, JWT lifetimes, JWKS verification, switching criterion) live in rest-api-architect/AUTH_PATTERNS.md. FastAPI-specific implementation:
OAuth2PasswordBearer + pyjwt + argon2-cffi. Dependency skeleton in RECIPES.md.pyjwt's PyJWKClient for JWKS verification; cache via @lru_cache. Verify aud and iss explicitly.dependencies=[Depends(require_scope("users:delete"))] on the route. Skeleton in RECIPES.md.Every error returns application/problem+json with a standardised shape (per rest-api-architect §7). Handler skeleton in RECIPES.md.
HTTPException and your custom exceptions return different shapes.RequestValidationError) get their own handler that maps Pydantic's error list into Problem.detail.detail. Log them server-side with a correlation id; reference the id in the response.Order matters — outermost middleware sees the request first.
CORSMiddleware) — first, so preflights short-circuit before auth.GZipMiddleware, min_size=1000).task-queue-architect skill. BackgroundTasks is not a queue.app.dependency_overrides[get_db] = .... Reset after the test.assert app.openapi() == json.load(open("tests/openapi.snapshot.json")). Catches accidental contract changes.401, 403, 404, 422).app.openapi() to add info.contact, servers, securitySchemes — these aren't FastAPI defaults.asyncio.get_event_loop().slow_callback_duration = 0.1 in dev.await asyncio.to_thread(blocking_fn, args).lifespan (see §5); never psycopg.connect() per request.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.