Skip to course content
Free generative AI app course

Generative AI Application Development with Python

Unit 10.00: The smallest endpoint that does the job

The smallest endpoint that does the job is one request model, one handler, one response shape.

TestClient runs it with no server

A single POST endpoint with a Pydantic request model.

The code exercises it in-process.

from fastapi import FastAPI
from fastapi.testclient import TestClient
from pydantic import BaseModel

app = FastAPI()


class Ask(BaseModel):
    question: str


@app.post("/ask")
def ask(body: Ask):
    return {"answer": f"stub answer for: {body.question}", "request_id": "r-1"}


client = TestClient(app)
print(client.post("/ask", json={"question": "How long for a refund?"}).json())

bad = client.post("/ask", json={})
print(f"\nmissing field -> {bad.status_code} (validation, before any handler code)")

# One endpoint, one request model, one response shape. `TestClient` runs the
# whole thing in-process with no server and no network, which is what makes the
# tests in Module 11 possible.

The missing-field request is rejected before the handler runs, by the framework, using the model you declared. That is validation you did not have to write.

TestClient runs the whole application in-process with no server and no network, which is what makes Module 11's offline suite possible.

The mistake this prevents

The mistake is adding endpoints before the first one is tested. One endpoint with a request model, a response shape and a test is a better foundation than five that are only exercised by hand.

Takeaway

One request model, one handler, one response shape - and TestClient to exercise it with no server. Framework validation runs before your code.