Skip to content
Aabha AI Academy

Module 2 of 9 · Lesson 3 of 26

Validate API requests and responses

Work through validate API requests and responses using a runnable reference, a focused regression check and a local extension.

Read in any order. All lessons stay open, including after an unanswered or incorrect check.

In this lesson you will validate API requests and responses. Work with the Equipment Rental API in the downloadable lab. The reference is a complete solution with separate lesson checks, so you can inspect the answer, make a deliberate local change and verify its behavior.
A request model states what callers may send. EquipmentIn requires a name, a positive quantity and a nonnegative decimal daily rate. Unknown fields are forbidden: a misspelled field should not silently disappear. Decimal avoids treating money as an approximate binary float. Precision and scale limits align the request with the database numeric column, so an accepted payload is less likely to fail at persistence time.

A response model is a separate promise. EquipmentOut adds the id and condition that callers can read, and from_attributes allows conversion from a loaded database object. Returning an ORM object without thinking about the response can expose internal fields or trigger hidden I/O. RentalOut is another deliberate view of a rental; password_hash is absent. PATCH also needs care: an omitted value means leave it alone, while explicit null is an attempted change. The service uses exclude_unset and rejects null for fields that cannot be cleared. Validation errors describe invalid input; database uniqueness still needs a conflict response.
Worked source: equipment/schemas.py, EquipmentIn.

Open schemas.py and compare EquipmentIn, EquipmentOut and EquipmentPatch. Run the lesson03 check to accept a decimal rate and reject zero quantity, negative rate and an unknown field. Trace EquipmentOut.model_validate in create_equipment: it constructs the promised output before the transaction ends.
pythonCopyable
class EquipmentIn(BaseModel):
    model_config = ConfigDict(extra="forbid")
    name: str = Field(min_length=1, max_length=120)
    quantity: int = Field(ge=1, le=10000)
    daily_rate: Decimal = Field(ge=0, max_digits=10, decimal_places=2)
TerminalPython 3.13 virtual environment; Docker running; extracted lab directory
python run_checks.py -k lesson03

Expected result The selected lesson test passes against a new temporary PostgreSQL database; the container is removed afterward.

Keep for reference

Equipment Rental lab and lesson checks

ZIP containing Python source, real Alembic migrations, 26 lesson checks, a dependency lock and text instructions. Extract it before following the local exercise.

Download Equipment Rental lab and lesson checks

Practise locally

Add an optional public description field with a length limit to a copy of the request and response models. Write one test for a valid description and one for an overlong value. Then decide how the database would store it; do not pretend that changing a Pydantic model changes the schema. Separately test that a password hash never appears in the public user response.

The lesson check verifies the reference behavior. Add your own assertions for your change. Local practice is not uploaded or scored by this learning release.

Pause and reflect

What failure does this lesson prevent, and which assertion in lesson03 would expose it?

Use a concrete input, expected result and limitation from your local work. Saving a reflection does not certify the project.

Optional knowledge check

Why distinguish an omitted PATCH field from explicit null?

Use exclude_none so both omission and null disappear.

Try another answer. That loses the distinction needed to reject an explicit clearing request.

Omission preserves the value; null requests a deliberate clearing change.

Correct. exclude_unset preserves omission, while the service can reject disallowed clearing.

Both should automatically erase the stored value.

Try another answer. Erasing on omission would make a partial update change fields the caller never supplied.

This practice does not assess your project or award a certificate.

Your reading progress

Progress is saved in this browser when storage is available.

Sign in to save across devices · Create an optional account