Initial extracted documentation set
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# Starlette source notes
|
||||
|
||||
Repo: `encode/starlette`
|
||||
Local checkout: `/home/ubuntu/repos/rodin-sources/starlette`
|
||||
|
||||
## Why this repo was chosen
|
||||
- FastAPI inherits key runtime behavior from Starlette. Starlette is the right source for conventions around app assembly, middleware ordering, lifespan, and request state.
|
||||
- Valuable here because it distinguishes framework guarantees from habits that only appear in sample apps.
|
||||
|
||||
## Repeated patterns
|
||||
|
||||
### 1) App construction keeps routing, middleware, exception handlers, and lifespan as separate inputs
|
||||
- `starlette/applications.py:22-55` defines the constructor with distinct parameters for routes, middleware, exception handlers, and lifespan.
|
||||
- `tests/test_applications.py:139-157` builds one app by explicitly passing routes, exception handlers, middleware, and lifespan together.
|
||||
|
||||
Why chosen:
|
||||
- This separation exists both in the public constructor and in the main integration-style test app.
|
||||
|
||||
Implication for synthesis:
|
||||
- Treat app assembly concerns as separate layers; do not blur middleware, routing, error handling, and startup resources into one module-level setup blob.
|
||||
|
||||
### 2) Middleware ordering is intentional and framework-enforced
|
||||
- `starlette/applications.py:35-40` documents that `ServerErrorMiddleware` is outermost and `ExceptionMiddleware` innermost.
|
||||
- `starlette/applications.py:68-77` shows the actual stack construction: framework error middleware, then user middleware, then framework exception middleware around the router.
|
||||
- `starlette/applications.py:98-101` forbids adding middleware after the application has started.
|
||||
|
||||
Why chosen:
|
||||
- This is stronger than a docs recommendation; it is constructor/runtime behavior.
|
||||
|
||||
Caveat / counterexample:
|
||||
- User middleware is not the whole stack. If a synthesized convention says "middleware runs in the order you add it," that is incomplete because Starlette wraps user middleware with framework-owned layers.
|
||||
|
||||
Implication for synthesis:
|
||||
- When discussing middleware order, mention Starlette's outer/inner framework layers explicitly.
|
||||
- Avoid recommendations that rely on mutating middleware after startup.
|
||||
|
||||
### 3) Lifespan is the preferred resource boundary, and `asynccontextmanager` is the clearest shape
|
||||
- `starlette/applications.py:46-48` says lifespan replaces `on_startup`/`on_shutdown`; use one style or the other, not both.
|
||||
- `tests/test_applications.py:394-409` shows the preferred shape: an `@asynccontextmanager` lifespan marks startup before `yield` and cleanup after `yield`, with both verified by entering/exiting the client context.
|
||||
- `tests/test_applications.py:108-114` defines lifespan state by yielding `{"count": 1}`.
|
||||
- `tests/test_applications.py:241-244` verifies request handlers can consume that state via `request.state`.
|
||||
|
||||
Why chosen:
|
||||
- This combines constructor guidance with working tests for startup/cleanup and state propagation.
|
||||
|
||||
Caveat / counterexample:
|
||||
- `tests/test_applications.py:421-459` still supports async/sync generator lifespan forms, but those tests are under a deprecation-warning filter. For future-facing synthesis, prefer `@asynccontextmanager`, not raw generator lifespans.
|
||||
|
||||
Implication for synthesis:
|
||||
- Recommend lifespan for DB pools, clients, caches, and other app resources.
|
||||
- Note that lifespan can yield structured state for handlers instead of relying on import-time globals.
|
||||
|
||||
## Strong citation candidates
|
||||
- Constructor-level separation of app assembly concerns: `starlette/applications.py:22-55`
|
||||
- Middleware stack ordering is framework-defined: `starlette/applications.py:68-77`
|
||||
- Cannot add middleware after startup: `starlette/applications.py:98-101`
|
||||
- Lifespan replaces startup/shutdown hooks: `starlette/applications.py:46-48`
|
||||
- Preferred `@asynccontextmanager` lifespan behavior: `tests/test_applications.py:394-409`
|
||||
|
||||
## Pattern candidates supported by this repo
|
||||
- separate routes, middleware, exception handlers, and lifespan at app assembly time
|
||||
- preserve middleware ordering intentionally, including framework-owned outer/inner layers
|
||||
- prefer lifespan over startup/shutdown hooks for resource management
|
||||
- use lifespan-yielded state instead of import-time globals for app-scoped data
|
||||
Reference in New Issue
Block a user