Category: python
Introduction to FastAPI Project Structure
Published on 22 Aug 2026
Explanation
A good FastAPI project structure separates application responsibilities into different modules and folders. Instead of putting all routes, database logic, models, and business logic inside a single main.py file, a structured project keeps each responsibility separate. This makes the application easier to understand, test, maintain, and scale. A typical FastAPI application contains folders for routes, models, schemas, services, database configuration, and tests.
Code:
fastapi-project/ │ ├── app/ │ ├── __init__.py │ ├── main.py │ ├── database.py │ ├── models.py │ ├── schemas.py │ ├── services.py │ └── routes/ │ ├── __init__.py │ ├── users.py │ └── products.py │ ├── tests/ │ ├── __init__.py │ ├── test_users.py │ └── test_products.py │ ├── requirements.txt ├── .env ├── .gitignore └── README.md
Explanation
The main.py file is commonly used as the entry point of a FastAPI application. It creates the FastAPI application object and includes routers from different modules. Keeping route definitions outside main.py prevents the main application file from becoming too large. The application can then be started using Uvicorn. The title and description can also be configured when creating the FastAPI application.
Code:
from fastapi import FastAPI
from app.routes import users, products
app = FastAPI(
title='Employee Management API',
description='FastAPI REST API Example',
version='1.0.0'
)
app.include_router(users.router)
app.include_router(products.router)
@app.get('/')
def root():
return {'message': 'FastAPI application running'}
# Run:
# uvicorn app.main:app --reload
Explanation
FastAPI provides APIRouter to organize related API endpoints into separate modules. For example, all user-related endpoints can be placed in users.py and all product-related endpoints can be placed in products.py. The router is then registered with the main FastAPI application using include_router(). This approach makes the API modular and easier to maintain as the number of endpoints grows.
Code:
# app/routes/users.py
from fastapi import APIRouter
router = APIRouter(
prefix='/users',
tags=['Users']
)
@router.get('/')
def get_users():
return [
{'id': 1, 'name': 'John'},
{'id': 2, 'name': 'Alice'}
]
@router.get('/{user_id}')
def get_user(user_id: int):
return {
'id': user_id,
'name': 'John'
}
# main.py
# app.include_router(users.router)
Explanation
FastAPI applications commonly separate database models, request/response schemas, and business logic. Models represent database tables when using an ORM such as SQLAlchemy. Pydantic schemas define the structure and validation rules for API request and response data. Service modules contain business logic so that route functions remain simple. This separation follows the principle of separation of concerns and makes the application easier to test and extend.
Code:
# app/schemas.py
from pydantic import BaseModel
class UserCreate(BaseModel):
name: str
email: str
class UserResponse(BaseModel):
id: int
name: str
email: str
# app/services.py
def create_user(user):
# Business logic goes here
return {
'id': 1,
'name': user.name,
'email': user.email
}
Explanation
Production FastAPI applications usually keep database configuration and environment-specific settings separate from application logic. The database.py module can manage database connections or SQLAlchemy sessions, while environment variables can store sensitive configuration such as database URLs and secret keys. Tests should be placed in a separate tests directory. This structure makes it easier to run automated tests and deploy the same application across development, testing, and production environments.
Code:
# app/database.py
from sqlalchemy import create_engine
DATABASE_URL = 'postgresql://postgres:password@localhost/company'
engine = create_engine(DATABASE_URL)
# .env
# DATABASE_URL=postgresql://postgres:password@localhost/company
# SECRET_KEY=your-secret-key
# tests/test_users.py
def test_user_name():
user = {
'id': 1,
'name': 'John'
}
assert user['name'] == 'John'
# requirements.txt
# fastapi
# uvicorn
# sqlalchemy
# psycopg
# pydantic