4.1 KiB
4.1 KiB
FastAPI Users source notes
Repo: fastapi-users/fastapi-users
Local checkout: /home/ubuntu/repos/rodin-sources/fastapi-users
Why this repo was chosen
- This repo shows how a substantial FastAPI ecosystem package composes auth/user flows as routers plus dependency factories, rather than bespoke checks inside each endpoint.
- It is especially useful for identifying patterns around router composition, auth dependencies, and the behavior differences between strict and optional auth gates.
Repeated patterns
1) Feature slices are delivered as routers and assembled centrally
examples/beanie-oauth/app/app.py:28-57builds oneFastAPI(lifespan=...)app and includes router factories for JWT auth, registration, password reset, verification, users, and OAuth.tests/test_fastapi_users.py:24-42repeats the same assembly pattern in tests, including multiple auth-related routers plus a users router.
Why chosen:
- The example app and the test app use the same composition model, which makes this a repeated package convention rather than demo-only structure.
Implication for synthesis:
- Strong evidence for composing auth/account features as routers, not implementing login/register/verify flows endpoint by endpoint.
2) Auth is expressed as dependency factories with explicit policy flags
examples/beanie-oauth/app/app.py:60-62protects a route withDepends(current_active_user).tests/test_fastapi_users.py:44-114shows the broader pattern:fastapi_users.current_user(...)generates dependencies for current, active, verified, superuser, and optional variants.fastapi_users/router/oauth.py:235-237derivesget_current_active_userfromauthenticator.current_user(active=True, verified=requires_verification)and then injects it into the OAuth association route atfastapi_users/router/oauth.py:257-262.
Why chosen:
- This is stronger than a single protected-route example: policy is parameterized and reused as dependency wiring.
Implication for synthesis:
- Recommend expressing auth requirements in dependency declarations (
active=True,verified=True,superuser=True,optional=True) rather than hidden role checks inside handlers.
3) Optional auth dependencies deliberately change failure behavior
tests/test_fastapi_users.py:156-203shows non-optionalcurrent_user/current_user(active=True)endpoints returning401for missing or invalid tokens.tests/test_fastapi_users.py:320-412shows optional variants returning200withnullwhen the token is missing, invalid, or does not satisfy the extra policy.tests/test_fastapi_users.py:219-315also distinguishes authorization outcomes: verified/superuser constraints return403when a valid user lacks the required property.
Why chosen:
- This is exactly the kind of subtle behavior shift that future synthesis could easily flatten incorrectly.
Caveat / counterexample:
optional=Trueis not just "same dependency, but maybe absent." It changes endpoint semantics from auth failure to nullable user context.
Implication for synthesis:
- If optional auth appears in synthesized guidance, call out the semantic shift explicitly and avoid presenting it as a drop-in default.
4) Lifespan owns startup resources here too
examples/beanie-oauth/app/app.py:17-28initializes Beanie in an@asynccontextmanagerlifespan and passes it toFastAPI(lifespan=...).
Why chosen:
- Confirms that ecosystem packages/examples align with the Starlette/FastAPI lifespan pattern rather than using import-time initialization.
Strong citation candidates
- Router-factory composition in app assembly:
examples/beanie-oauth/app/app.py:28-57 - Dependency-factory auth policies:
tests/test_fastapi_users.py:44-114 - Optional auth returns
200+nullinstead of401/403:tests/test_fastapi_users.py:320-412 - OAuth route derives auth dependency from policy flags:
fastapi_users/router/oauth.py:235-262
Pattern candidates supported by this repo
- compose auth/account feature areas as routers
- declare auth policy in dependencies rather than inline endpoint checks
- distinguish required auth from optional nullable-user contexts
- initialize backing resources in lifespan