tezvyn:

Access raw request bytes in FastAPI for webhook verification

AI-drafted, machine-checkedSource: fastapi.tiangolo.comadvanced

Tests FastAPI's Starlette integration and stream semantics. Outline: inject Request and await request.body, but the stream is single-use so JSON parsing later fails and docs are lost. Red flag: suggesting a Pydantic model still works after consuming the body.

WHAT THIS TESTS: Whether you understand that FastAPI is built on Starlette and that HTTP request bodies are streaming byte streams rather than in-memory buffers that can be read repeatedly. The interviewer wants to see if you know how to drop down to the framework level when automatic JSON parsing is insufficient, and if you grasp the trade-offs around validation, documentation, and stream consumption.

A GOOD ANSWER COVERS: First, import Request from starlette.requests and declare it as a parameter in your path operation function. Second, read raw bytes with await request.body inside an async handler. Third, explain that the underlying body is an async stream that can only be consumed once, so calling request.body means FastAPI will not be able to populate a Pydantic model from the same request later in that handler. Fourth, note that using Request directly bypasses FastAPI's automatic request validation, type conversion, and OpenAPI schema generation for the body, so you lose docs and validation unless you rebuild them manually.

COMMON WRONG ANSWERS: Claiming you can simply add a Pydantic model parameter alongside the Request parameter in the same endpoint and expect both to work, since the body stream would already be exhausted. Suggesting request.json instead of request.body without acknowledging that request.json also consumes the stream and still skips FastAPI model validation. Proposing to read the body in middleware without explaining how to cache it or attach it to scope for downstream use. Forgetting to mention that direct Request usage removes the request body from the generated OpenAPI documentation.

LIKELY FOLLOW-UPS: How would you validate the webhook signature and still return a parsed Pydantic model? The expected path is to manually parse the bytes with json.loads and instantiate the model yourself, or to use a custom middleware or APIRoute that caches the body before the path operation runs. What happens to OpenAPI documentation when you use Request directly? You must document the expected payload manually or accept that the schema will not show the body structure. How would you handle this for a large file upload instead of a small JSON payload? You might discuss using request.stream to avoid loading everything into memory.

ONE CONCRETE EXAMPLE: Imagine a Stripe webhook endpoint. You define async def webhook(request: Request), then body = await request.body(). You compute an HMAC signature over body using a secret key and compare it to a header. If valid, you parse the JSON with json.loads(body) and pass it into a Pydantic model manually. If you had instead declared a Pydantic parameter first, FastAPI would have consumed the stream to build the model, leaving you unable to access the exact raw bytes needed for the signature check, since JSON whitespace or key ordering might differ from the original payload.

Read the original → fastapi.tiangolo.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.