Files
fastapi-conventions/sources/fastapi-users.md
T
2026-06-01 21:42:05 +00:00

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-57 builds one FastAPI(lifespan=...) app and includes router factories for JWT auth, registration, password reset, verification, users, and OAuth.
  • tests/test_fastapi_users.py:24-42 repeats 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-62 protects a route with Depends(current_active_user).
  • tests/test_fastapi_users.py:44-114 shows the broader pattern: fastapi_users.current_user(...) generates dependencies for current, active, verified, superuser, and optional variants.
  • fastapi_users/router/oauth.py:235-237 derives get_current_active_user from authenticator.current_user(active=True, verified=requires_verification) and then injects it into the OAuth association route at fastapi_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-203 shows non-optional current_user / current_user(active=True) endpoints returning 401 for missing or invalid tokens.
  • tests/test_fastapi_users.py:320-412 shows optional variants returning 200 with null when the token is missing, invalid, or does not satisfy the extra policy.
  • tests/test_fastapi_users.py:219-315 also distinguishes authorization outcomes: verified/superuser constraints return 403 when 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=True is 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-28 initializes Beanie in an @asynccontextmanager lifespan and passes it to FastAPI(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 + null instead of 401/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