-
Create a virtual environment:
python -m venv .venv
Activate the virtual environment:
- On macOS/Linux:
source .venv/bin/activate- On Windows use
.venv\Scripts\activate
-
Install FastAPI and Uvicorn:
pip install fastapi uvicorn
-
Create a simple FastAPI app with the following structure:
module3_request_response/ ├── main.py ├── requirements.txt ├── config.py ├── models/ │ ├── item.py │ └── user.py └── routes/ ├── items.py └── users.py -
Run the application:
uvicorn main:app --reload
- Objective: Create Pydantic models to represent both full and partial views of an Item.
- Instructions:
-
In
models/item.py, define:-
Item: with fieldsid,name,description(optional), andprice. -
Item_Response: returns onlyidandname.
-
-
Use type hints and default values where needed.
-
- Objective: Create two endpoints to retrieve item(s).
- Instructions:
- In
routes/items.py:- Implement GET
/items/: Return a list of all available items. - Implement GET
/items/{id}: Return an item by its ID using a path parameter.- If not found, return 404 using HTTPException.
- Use
response_model=Item_Responseto hide sensitive data.
- Implement GET
- In
- Objective: Define a robust Pydantic model for users.
- Instructions:
- In
models/user.py:-
Create
Userwith:- Validated
username(3–50 chars) - Validated
email(regex pattern) - Optional
full_name(max 100 chars) - Default
is_active=True
- Validated
-
Define
User_Responseto include onlyidandfull_name.
-
- In
- Objective: Create RESTful routes for user management.
- Instructions:
- In
routers/users.py:-
GET
/users/: Return all users. -
POST
/users/: Create a user.- Return 400 if the id already exists.
- Respond with a
User_Response.
-
GET
/users/{id}: Return a full user by ID or raise 404. -
DELETE
/users/{id}: Remove user by ID or raise 404.
-
- In
- Objective: Build a modular FastAPI app with multiple routers.
- Instructions:
- In
main.py:- Create a FastAPI instance.
- Include:
users.routerunder/userswith tag "Users"items.routerunder/itemswith tag "Items"
- Add a root route
/that returns a welcome message.
- In
uvicorn main:app --reload- Test the following routes:
GET /
GET /items/, GET /items/{id}
GET /users/, POST /users/, GET /users/{id}, DELETE /users/{id}
-
Create models for items:
# models/item.py from typing import Optional from pydantic import BaseModel class Item(BaseModel): id: int name: str description: Optional[str] = None price: float class Item_Response(BaseModel): id: int name: str
-
Create routes for items:
routes/items.pyfrom fastapi import APIRouter, HTTPException from models.item import Item, Item_Response router = APIRouter() items = [ Item(id=1, name="Item1", description="Description of Item1", price=10.0), Item(id=2, name="Item2", description="Description of Item2", price=20.0), Item(id=3, name="Item3", description="Description of Item3", price=30.0), ] @router.get("/") def get_items(): return items @router.get("/{id}", response_model=Item_Response) def get_item(id: int): # return item from the items list based on the provided id for item in items: if item.id == id: return item raise HTTPException(status_code=404, detail="Item not found")
-
Create models for users:
models/user.pyfrom pydantic import BaseModel, Field class User(BaseModel): id: int = Field(..., description="The unique identifier for the user") username: str = Field(..., min_length=3, max_length=50, description="The username of the user") email: str = Field(..., pattern=r"^[\w\.-]+@[\w\.-]+\.\w+$", description="The email address of the user") full_name: str = Field(None, max_length=100, description="The full name of the user") is_active: bool = Field(True, description="Indicates if the user is active") class User_Response(BaseModel): id: int full_name: str
-
Create routes for users:
routers/users.pyfrom fastapi import APIRouter, HTTPException from models.user import User, User_Response router = APIRouter() users = [ User(id=1, username= "Alice", email= "alice@foo.com", full_name= "Alice Smith", is_active= True), User(id=2, username= "Bob", email= "boob@foo.com", full_name= "Bob Johnson", is_active= True) ] @router.get("/") def get_users(): return users @router.post("/", response_model=User_Response) def create_user(user: User): # Check if user with the same id already exists for existing_user in users: if existing_user.id == user.id: raise HTTPException(status_code=400, detail="User with this ID already exists") # Add the new user to the list users.append(user) return User_Response(id=user.id, full_name=user.full_name) @router.delete("/{id}", response_model=User_Response) def delete_user(id: int): for idx, user in enumerate(users): if user.id == id: removed_user = users.pop(idx) return removed_user raise HTTPException(status_code=404, detail="User not found") @router.get("/{id}", response_model=User) def get_user(id: int): # return user from the users list based on the provided id for user in users: if user.id == id: return user raise HTTPException(status_code=404, detail="User not found")
-
Create the main FastAPI app:
main.pyfrom fastapi import FastAPI from routers import users, items app = FastAPI() app.include_router(users.router, prefix="/users", tags=["Users"]) app.include_router(items.router, prefix="/items", tags=["Items"]) @app.get("/") def read_root(): return {"message": "Welcome to the FastAPI backend!"}
-
Run the FastAPI app:
uvicorn main:app --reload