- What is FastAPI?
- Project Structure Overview
- Core Concepts
- Hands-on Learning Path
- Advanced Topics
- Best Practices
FastAPI is a modern, fast web framework for building APIs with Python based on standard Python type hints. It's designed to be:
- Fast: High performance, on par with NodeJS and Go
- Easy: Simple to learn and use
- Robust: Production-ready code with automatic interactive documentation
Your project follows a well-organized structure that separates concerns:
fastapi-aws/
├── api/
│ ├── __init__.py
│ ├── main.py # Main application entry point
│ ├── models.py # Database models (SQLAlchemy)
│ ├── dependencies/
│ │ └── deps.py # Shared dependencies (auth, database)
│ └── routers/
│ ├── auth.py # Authentication endpoints
│ ├── dogs.py # Dog-related endpoints
│ ├── comments.py # Comment endpoints
│ └── posts.py # Post endpoints
├── requirements.txt # Python dependencies
├── .env-sample # Environment variables template
└── Procfile # Deployment configuration
from fastapi import FastAPI
app = FastAPI() # This creates your API applicationKey Learning Points:
- The
FastAPI()instance is your entire application - CORS middleware handles cross-origin requests
- Routers are included to organize endpoints
FastAPI uses decorators to define endpoints:
@app.get("/") # GET request
@app.post("/dogs") # POST request
@app.put("/dogs/{id}") # PUT request
@app.delete("/dogs/{id}") # DELETE requestPydantic models define the structure and validation of your data:
class DogCreateRequest(BaseModel):
name: str
breed: str
age: intWhy this matters:
- Automatic validation of incoming data
- Auto-generated API documentation
- Type safety
Dependencies are reusable components that can be injected into your endpoints:
# From deps.py
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# Usage in endpoint
@router.get("/dogs")
def get_dogs(db: db_dependency): # db_dependency = Annotated[Session, Depends(get_db)]
return db.query(Dog).all()Learning Goals: Understand app creation, middleware, and routing
Exercise:
- Look at how the FastAPI app is created
- Notice the CORS middleware configuration
- See how routers are included
Key Code to Study:
app = FastAPI()
app.add_middleware(CORSMiddleware, ...)
app.include_router(auth.router)Learning Goals: Basic CRUD operations
Start with these endpoints:
@router.get("/userdogs") # Read user's dogs
@router.post("/") # Create a dog
@router.delete("/{dog_id}") # Delete a dogExercise:
- Trace how a GET request flows through the code
- Understand how user authentication is checked
- See how database operations work
Learning Goals: Database integration with SQLAlchemy
Key Concepts:
- Table definitions using SQLAlchemy ORM
- Relationships between tables (User → Dogs, Posts, etc.)
- Database engine and session management
Learning Goals: JWT authentication, password hashing
Study Flow:
- User registration → Password hashing with bcrypt
- User login → JWT token generation
- Protected endpoints → Token validation
Key Code:
def authenticate_user(username: str, password: str, db):
# Password verification logic
def create_access_token(username: str, user_id: int, expires_delta: timedelta):
# JWT token creationLearning Goals: Dependency injection patterns
Important Dependencies:
get_db(): Database session managementget_current_user(): User authenticationbcrypt_context: Password hashing
Learning Goals: Advanced database operations, pagination
Study the posts endpoint:
- Joining multiple tables
- Counting related records
- Pagination implementation
- Time formatting logic
Learning Goals: API response structuring
In posts.py, notice different response models:
PostUserResponse: For list viewsPostSchema: For detailed views with nested data
Pattern used throughout:
if not item:
raise HTTPException(status_code=404, detail="Item not found")Study how the models relate:
- User has many Dogs
- User has many Posts
- Post has many Comments
- User has one Image
Create a simple health check endpoint:
@app.get("/health")
async def health_check():
return {"status": "healthy", "timestamp": datetime.now()}Create a "Like" system for posts:
- Add a
Likemodel inmodels.py - Create a
likes.pyrouter - Add endpoints to like/unlike posts
- Update post responses to include like counts
Add validation to the DogCreateRequest:
- Age must be between 0 and 25
- Name must be at least 2 characters
- Breed from a predefined list
Some endpoints use async def - this enables handling multiple requests concurrently:
async def get_current_user(token: oauth2_bearer_dependency):
# Async function for better performanceCORS middleware in your project handles cross-origin requests:
app.add_middleware(
CORSMiddleware,
allow_origins=[os.getenv("API_URL")],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)Using .env files for configuration:
load_dotenv()
SECRET_KEY = os.getenv("AUTH_SECRET_KEY")The dependency pattern ensures database connections are properly managed:
def get_db():
db = SessionLocal()
try:
yield db # Provides database session
finally:
db.close() # Always closes connection- Models in
models.py - Business logic in routers
- Shared functionality in
dependencies/
Every function uses proper type hints:
def create_dog(db: db_dependency, user: user_dependency, dog: DogCreateRequest):All input/output data is validated using Pydantic models
- JWT tokens for authentication
- Password hashing with bcrypt
- User authorization checks
- Proper session management
- Relationship definitions
- Connection pooling
-
Run the Project Locally
- Set up a virtual environment
- Install requirements:
pip install -r requirements.txt - Create a
.envfile from.env-sample - Run:
uvicorn api.main:app --reload
-
Explore the API Documentation
- Visit
http://localhost:8000/docsfor interactive Swagger docs - Try out different endpoints
- Visit
-
Modify and Experiment
- Add new fields to existing models
- Create new endpoints
- Implement new features
-
Study Real-World Patterns
- Look at how pagination is implemented
- Understand the authentication flow
- See how related data is fetched efficiently
router = APIRouter(prefix='/dogs', tags=['Dogs'])def endpoint(db: db_dependency, user: user_dependency):@router.get("/", response_model=List[PostSchema])if not item:
raise HTTPException(status_code=404, detail="Not found")This project is an excellent example of a production-ready FastAPI application. Take your time with each phase, experiment with the code, and don't hesitate to break things – that's how you learn best!# fastapi-aws