master
CI / lint · types · tests (push) Successful in 8s
Restructure the take-home into a small package with tests and fix the bugs that stopped it running: - app/ package: main, routes, models, documents (was json_load) - fix the search route — it built the Response envelope positionally and never actually returned; now returns ListResponse[Ok, DocumentId] - Literal domain types (Role, Department) so bad input is a 422 - load + validate docs.json in one TypeAdapter call - PEP 695 type aliases / generics; Annotated query params - pyproject: fix the [tool.ty.src] typo, drop the unfixable list that disabled every autofix, move ruff/ty to a dev group - add 5 end-to-end tests, wire pytest into CI, add MIT LICENSE, real README Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01BmZpbtmZGQw931W7wzFeLH
fastapi-rbac-search
A small, fully typed FastAPI service: keyword search over a document repository that only returns the documents the caller's role is allowed to see.
It is deliberately compact — a sample of how I structure a typed Python API, not a product.
What it shows
- Generic response envelopes —
Response[S, D]andListResponse[S, D](app/models.py) give every endpoint the same{ "status": ..., "data": ... }shape while keeping the payload type checked. Literaldomain types —RoleandDepartmentare closed sets, so an unknownroleis a422from FastAPI's request validation rather than a branch in the handler.- Pydantic v2 models with a camelCase alias generator for the wire format,
and a
TypeAdapterthat loads and validates the wholedocs.jsonin one call. - Tooling:
uvfor environments,rufffor lint + format,tyfor type checking,pytestfor the tests — all wired into CI.
Run it
uv run uvicorn app.main:app --reload
# docs: http://127.0.0.1:8000/docs
curl 'http://127.0.0.1:8000/documents?q=rollback&role=ops'
# {"status":"ok","data":["doc-001"]}
curl -i 'http://127.0.0.1:8000/documents?q=rollback&role=hr'
# 404 — "hr" is not on doc-001's permission list
Develop
uv sync
uv run ruff format --check && uv run ruff check
uv run ty check
uv run pytest
Layout
app/
main.py FastAPI app + router wiring
routes.py GET /documents — the role-filtered search
models.py response envelopes, Literal domain types, the Document model
documents.py loads + validates app/docs.json into a list[Document]
docs.json the sample repository (12 documents)
tests/ end-to-end tests against the app via TestClient
Description
Small, fully typed FastAPI service: document search that only returns what the caller's role may see
77 KiB
0 Stars
1 Watchers
0 Forks
Languages
Python
100%