from fastapi import FastAPI, HTTPException, Path, Query, status from pydantic import BaseModel, Field from typing import List, Optional app = FastAPI( title="User Service API", description="Simple CRUD API to demonstrate Code First OpenAPI generation with FastAPI", version="1.0.0" ) # -------------------- # Models # -------------------- class UserBase(BaseModel): name: str = Field(..., example="Alice") age: int = Field(..., example="22") email: str = Field(..., example="alice@example.com") class UserCreate(UserBase): pass class User(UserBase): id: int = Field(..., example=1) # -------------------- # Fake database # -------------------- users_db: dict[int, User] = {} # -------------------- # CRUD Endpoints # -------------------- @app.post( "/users", response_model=User, status_code=status.HTTP_201_CREATED, summary="Create a new user", description="Creates a new user and returns the created resource", tags=["Users"] ) def create_user(user: UserCreate): user_id = len(users_db) + 1 new_user = User(id=user_id, **user.dict()) users_db[user_id] = new_user return new_user @app.get( "/users", response_model=List[User], summary="List all users", description="Returns a list of all users", tags=["Users"] ) def list_users( limit: int = Query(10, ge=1, le=100, description="Maximum number of users to return") ): return list(users_db.values())[:limit] @app.get( "/users/{user_id}", response_model=User, summary="Get user by ID", description="Returns a single user by its ID", tags=["Users"] ) def get_user( user_id: int = Path(..., ge=1, description="The ID of the user") ): user = users_db.get(user_id) if not user: raise HTTPException(status_code=404, detail="User not found") return user @app.put( "/users/{user_id}", response_model=User, summary="Update a user", description="Updates an existing user", tags=["Users"] ) def update_user( user_id: int = Path(..., ge=1, description="The ID of the user"), user: UserCreate = ... ): if user_id not in users_db: raise HTTPException(status_code=404, detail="User not found") updated_user = User(id=user_id, **user.dict()) users_db[user_id] = updated_user return updated_user @app.delete( "/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT, summary="Delete a user", description="Deletes a user by its ID", tags=["Users"] ) def delete_user( user_id: int = Path(..., ge=1, description="The ID of the user") ): if user_id not in users_db: raise HTTPException(status_code=404, detail="User not found") del users_db[user_id]