diff --git a/AGENTS.md b/AGENTS.md index 0a1d091..2505689 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,13 +6,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co `modern-di-fastapi` is the FastAPI integration for [`modern-di`](https://github.com/modern-python/modern-di); [`CONTEXT.md`](CONTEXT.md) opens with -what it does and owns the vocabulary — read it before naming a concept in code, a test name, or an +what it does and owns the vocabulary. Read it before naming a concept in code, a test name, or an issue title. It is one of that project's integrations, each of which lives in a separate repository and ships as a separate PyPI package. ## Commands -`just` (task runner) and `uv` (package manager). The [`justfile`](justfile) is the source of truth — +`just` (task runner) and `uv` (package manager). The [`justfile`](justfile) is the source of truth: `just --list`, or read it. ## Architecture @@ -24,7 +24,7 @@ All implementation is `modern_di_fastapi/main.py`, short enough to read whole. R `tests/dependencies.py` is the model every test builds on: one `Group` spanning four scopes, plus two factories that read the live `Request` / `WebSocket` to exercise the context providers. Routes are declared **inside the test body**, decorating the `app` fixture after `client` has already built -its `TestClient` — FastAPI picks them up, and it keeps each test's route next to its assertions. +its `TestClient`. FastAPI picks them up, and it keeps each test's route next to its assertions. ## Workflow diff --git a/CONTEXT.md b/CONTEXT.md index f9ae9d5..c1e0071 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -10,13 +10,13 @@ A term is listed only when there is a synonym to reject, or a meaning subtle eno docs must agree on it. General programming vocabulary does not belong here, however heavily this package uses it. -The domain terms are `modern-di`'s — `Container` (root and child), `Provider`, `Group`, `Scope`, +The domain terms are `modern-di`'s: `Container` (root and child), `Provider`, `Group`, `Scope`, `Resolution`, `Override`, `Connection`. That project's `CONTEXT.md` is the authority for all of them; nothing here redefines one. FastAPI's are FastAPI's: dependency, `Depends`, router, request, WebSocket. The two below are this package's own. **Per-connection container**: -The child container `build_di_container` opens for one connection and closes when it ends — +The child container `build_di_container` opens for one connection and closes when it ends: `REQUEST`-scoped for a `fastapi.Request`, `SESSION`-scoped for a `fastapi.WebSocket`. Every `FromDI` parameter in one handler resolves from the same one. _Avoid_: per-request container, request container. A WebSocket's is `SESSION`-scoped, so "request" @@ -30,7 +30,7 @@ finalizers run last. The original's yielded state passes through untouched. It a called `setup_di`, since Starlette never runs a mounted app's lifespan. An app whose `setup_di` got `manage_lifespan=False` keeps its root out of the composed lifespan, whether it is the outer app or a mounted one; the user opens and closes that root. -_Avoid_: merged lifespan — "merge" is FastAPI's own word for the private helper this package +_Avoid_: merged lifespan. "Merge" is FastAPI's own word for the private helper this package deliberately does not use, which also merges the two yielded states ([ADR-0001](docs/adr/0001-own-the-lifespan-composition.md)). Also avoid appended lifespan: the app's lifespan runs *inside* the container's open/close.