Stage 1 · L03
Follow HTTP through Uvicorn, ASGI, FastAPI and routing
Core · original Session 1 plus essential local Git/Docker setup
HTTP is the wire-level request and response contract. Uvicorn accepts the TCP connection, parses HTTP and invokes the ASGI application. ASGI presents a scope describing the connection and receive/send callables for events. FastAPI builds on Starlette to match routes, validate declared input, invoke a handler and serialize a response. SQLAlchemy and PostgreSQL are not part of this first request yet.
Trace GET /equipment/1: the path matches /equipment/{equipment_id}; FastAPI converts the path text to the declared integer; get_equipment searches the synthetic catalogue; the returned mapping becomes JSON with status 200. GET /equipment/word matches the same route shape but fails input validation, so the handler never sees an integer. GET /missing matches no route and returns 404. POST /equipment matches an existing path with an unsupported method and returns 405.
Route order matters when shapes overlap. /equipment/search is registered before /equipment/{equipment_id}. If you register the parameter route first, the literal search can be consumed as equipment_id and fail validation. This is an observable 422, not a missing database record. Keep a fixed route ahead of the broad parameter route, or choose distinct path shapes.
Ordinary def handlers are run in FastAPI's worker-thread facility; async def handlers execute on the event loop and must not block it. The stage-01 handlers perform tiny in-memory operations, so ordinary def is clear and valid. Do not convert a blocking database call to async merely by changing the function keyword. Later lessons distinguish an async HTTP integration from an async database driver.
A package groups importable modules; equipment/__init__.py marks this package, and equipment/api.py is its api module. The dotted import equipment.api:app means load that module and obtain its app attribute. Import code executes once per process and must not unexpectedly create tables or make network calls. Run from the snapshot root so Python can find equipment; do not fix an import error by editing unrelated global paths.
APIRouter groups related operations with a prefix and documentation tags. Its @router.get path is relative to that prefix; /search under /equipment composes /equipment/search. app.include_router(router) copies those registered operations into the application. A router left unregistered is not served. The first checkpoint actually uses this grouping; it preserves static search before the integer parameter route.
Exercise the grouping before adding storage: inspect the registered OpenAPI paths, request search and a numeric ID, then temporarily omit include_router in a copied learner app and observe404. Restore it before the baseline. This changes routing registration only; it does not create a separate server or microservice.
Follow the running code
Focused lesson example; see the end-of-stage capstone for the cumulative app · stage 01
from fastapi import APIRouter, FastAPI
app = FastAPI()
router = APIRouter(prefix='/equipment', tags=['Equipment'])
@router.get('/search')
def search(name: str = ''):
return {'name': name}
@router.get('/{equipment_id}')
def read(equipment_id: int):
return {'id': equipment_id}
app.include_router(router)Predict and observe this focused example using the concepts explained above. Its boundary is stated in the focused answer.
Guided lab
- Read the explanation and predict the focused example’s outcome.
- Explain the composed path, then predict /equipment/search, /equipment/7 and /equipment/word. What happens if include_router is omitted?
- Compare the observed outcome with the focused answer and state its boundary.
Expected: The prefix and local path compose /equipment/search and /equipment/{equipment_id}. Search returns its declared query value; 7 becomes integer 7; word fails conversion with 422. Without include_router the router's operations are absent from the app and requests return 404. Register search first.
- Route-order experiment can turn search into 422; unknown item is a handler-level 404; unknown path is a router-level 404.
Focused exercise and answer
Complete this focused exercise before reading its answer. The full native transfer is introduced only at the end of the stage.
Your transfer task: Explain the composed path, then predict /equipment/search, /equipment/7 and /equipment/word. What happens if include_router is omitted?
- Explain the composed path, then predict /equipment/search, /equipment/7 and /equipment/word. What happens if include_router is omitted?
Inspect the matching answer
This answer addresses the focused exercise above; the cumulative implementation is shown only after the stage prerequisites.
The prefix and local path compose /equipment/search and /equipment/{equipment_id}. Search returns its declared query value; 7 becomes integer 7; word fails conversion with 422. Without include_router the router's operations are absent from the app and requests return 404. Register search first.Check your reasoning
Does ASGI make a blocking SQL query asynchronous?
Show the explanation
No. The handler declaration, driver and resource lifetime must support the chosen execution model.
Reading progress
54 lessons remain open to guests. Marking a lesson read records reading only; it does not award assessment credit or a certificate.
Device reading marks require browser storage. Reading is always available.
Sign in or create an account to save separate account progress. Your current page is kept.
Your earlier place on this device suggests these lessons. No new lesson is marked read.