Q1EP2a Refactor Your API with Python Type Hints, Annotated & Pydantic

Published: 17 February 2026
on channel: Voyager Quests
35
0

Quest 1 Ep. 2 a: Instructions

🎯 Objective

Now that your API is functional, it’s time to refactor it to fully leverage Python type hints, typing.Annotated, and Pydantic.

Watch the Mastering Python Type Hints video and apply the concepts to improve type safety, validation, and documentation across your codebase. You’ll also begin adding proper structure and tests as described below.

Your goal is to clearly separate concerns between the API (delivery layer) and the inner layers of your application (use-cases and domain logic), while enforcing constraints consistently at runtime and in generated documentation. Outer layers must not interact directly with inner layers.

📋 Requirements

1️⃣ Type Hints & Annotated Types

Use Python type hints throughout the entire codebase.

Use typing.Annotated to describe:

Field constraints (e.g., minimum and maximum values)

Field descriptions (human-readable documentation)

2️⃣ Pydantic Models & Validation

Use Pydantic models for all Data Transfer Objects (DTOs).

Enforce the following constraints at runtime:

health must be an integer between 1 and 100.

attributes values must be integers between 1 and 100.

Validation must work both:

When requests are sent through the API.

When domain logic is called directly (outside FastAPI).

Domain rules must not rely on FastAPI to enforce correctness.

3️⃣ API Documentation

The generated API documentation must:

Display all field descriptions.

Display validation constraints (e.g., min/max values).

Display example schemas of what data you should send and what you will receive.

Be automatically derived from type hints and Annotated metadata.

No manual documentation duplication.

4️⃣ Data Transfer Objects (DTOs)

Implement explicit DTOs using Pydantic to transfer data:

From the delivery layer (api.py)

Into the application layer (application.py)

DTOs must clearly define the boundary between the delivery layer and the inner layers of your system.

5️⃣ Code Structure

Structure your code into the following source files:

api.py

FastAPI application

Route definitions

Mapping to and from DTOs

FastAPI code must only exist here

Inner layers must not know about FastAPI

domain.py

Domain types using Annotated types

Domain models and value objects

Domain rules and invariants

No FastAPI or CLI code

application.py

Application/use-case logic

Interacts with domain models and value objects

Receives DTOs from the API

Instantiates objects

Interacts with the repository

No FastAPI or CLI-specific code

dto.py

Data Transfer Object definitions

No FastAPI or CLI code

repository.py

Interacts with the JSON file

Retrieves and stores characters

No FastAPI or CLI code

No business rules

6️⃣ Add Some Tests

Use pytest to add tests that:

Validate domain constraints

Ensure invalid input is rejected

Test application behavior

Confirm logic works independently of FastAPI

⭐ Bonus Challenge

Create a command-line interface (CLI) that interacts directly with your domain logic using the same request and response DTOs.

The CLI should:

Interact with inner layers similarly to FastAPI.

Remain thin and framework-independent.

Let DTOs handle validation.

🧠 Learning Outcomes

By completing this quest, you will learn:

How to protect your functions and data using Python type hints and Pydantic.

How to use Annotated types to enrich models with constraints and metadata.

How Pydantic absorbs information from Annotated types to enforce validation.

How FastAPI generates OpenAPI documentation from type hints and annotations.

How to design a clean boundary between API, DTOs, and domain logic.

Why enforcing domain rules outside the web framework is critical for correctness.

How to experiment with writing tests.

✅ Success Criteria

Invalid input is rejected both via the API and via direct domain calls.

OpenAPI documentation clearly shows constraints and field descriptions.

api.py contains no business rules or domain logic.

Domain logic is reusable, testable, and framework-independent.


On this page of the site you can watch the video online Q1EP2a Refactor Your API with Python Type Hints, Annotated & Pydantic with a duration of hours minute second in good quality, which was uploaded by the user Voyager Quests 17 February 2026, share the link with friends and acquaintances, this video has already been watched 35 times on youtube and it was liked by 0 viewers. Enjoy your viewing!