https://blog.stackademic.com/best-practices-for-structuring-your-fastapi-projects-e66482b27d02

Best Practices for Structuring Your FastAPI Projects | by Joël-Steve N. | Stackademic

A Guide to Organizing Folders and Files —————————————

[

Joël-Steve N.

](https://jnikenoueba.medium.com/?source=post_page—byline–e66482b27d02——————————–)

[

Stackademic

](https://blog.stackademic.com/?source=post_page—byline–e66482b27d02——————————–)

Properly structuring a FastAPI project is crucial for maintaining clean, understandable, and scalable code. A well-organized project structure facilitates collaboration among developers and reduces the time needed to add new features or debug issues. In this article, we’ll explore best practices for structuring your FastAPI projects with code examples to help you effectively organize your folders and files.

1. Basic Structure of a FastAPI Project

The basic structure of a FastAPI project can be simplified as follows:

my_project/
├── app/
│   ├── main.py
│   ├── api/
│   │   ├── __init__.py
│   │   └── controllers/
│   │       ├── __init__.py
│   │       └── items.py
│   ├── core/
│   │   ├── __init__.py
│   │   └── config.py
│   ├── models/
│   │   ├── __init__.py
│   │   └── item.py
│   ├── schemas/
│   │   ├── __init__.py
│   │   └── item.py
│   ├── crud/
│   │   ├── __init__.py
│   │   └── item.py
│   ├── db/
│   │   ├── __init__.py
│   │   └── session.py
│   └── tests/
│       ├── __init__.py
│       └── test_items.py
├── .env
├── requirements.txt
└── README.md

2. Details of Folder Structure

2.1 main.py

The **main.py** file is the entry point of your FastAPI application. It initializes the app and includes the routes.

Example: **main.py**

from fastapi import FastAPI
from app.api.controllers import items
app = FastAPI()
app.include_router(items.router)
@app.get("/")
def read_root():
    return {"message": "Welcome to FastAPI"}

2.2 api/

The **api/** folder contains all the API endpoints. It is divided into subfolders for each specific entity or feature of your application.

Example: **items.py** in **api/controllers**

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.schemas.item import Item
from app.crud.item import get_item, create_item
from app.db.session import get_db
router = APIRouter()
@router.post("/items/", response_model=Item)
def create_new_item(item: Item, db: Session = Depends(get_db)):
    db_item = get_item(db, item_id=item.id)
    if db_item:
        raise HTTPException(status_code=400, detail="Item already exists")
    return create_item(db=db, item=item)

2.3 core/

The **core/** folder contains the configurations and settings of the application, such as database settings, secret keys, etc.

Example: **config.py** in **core/**

import os
from dotenv import load_dotenv
load_dotenv()
class Settings:
    PROJECT_NAME: str = "FastAPI Project"
    SQLALCHEMY_DATABASE_URI: str = os.getenv("DATABASE_URL")
settings = Settings()

2.4 models/

The **models/** folder contains the database model definitions. Each model represents a table in the database.

Example: **item.py** in **models/**

from sqlalchemy import Column, Integer, String
from app.db.session import Base
class Item(Base):
    __tablename__ = "items"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    description = Column(String, index=True)

2.5 schemas/

The **schemas/** folder contains Pydantic schemas used for validating incoming and outgoing data.

Example: **item.py** in **schemas/**

from pydantic import BaseModel
class Item(BaseModel):
    id: int
    name: str
    description: str
    class Config:
        orm_mode = True

2.6 crud/

The **crud/** folder contains the CRUD (Create, Read, Update, Delete) operations to interact with the database.

Example: **item.py** in **crud/**

from sqlalchemy.orm import Session
from app.models.item import Item as ItemModel
from app.schemas.item import Item as ItemSchema
def get_item(db: Session, item_id: int):
    return db.query(ItemModel).filter(ItemModel.id == item_id).first()
def create_item(db: Session, item: ItemSchema):
    db_item = ItemModel(id=item.id, name=item.name, description=item.description)
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item

2.7 db/

The **db/** folder contains the database configurations, including the database session and initialization files.

Example: **session.py** in **db/**

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from app.core.config import settings
SQLALCHEMY_DATABASE_URL = settings.SQLALCHEMY_DATABASE_URI
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

2.8 tests/

The **tests/** folder contains unit and integration tests for your application. Testing your code is crucial to ensure its reliability and stability.

Example: **test_items.py** in **tests/**

from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_create_item():
    response = client.post("/items/", json={"id": 1, "name": "Item 1", "description": "A sample item"})
    assert response.status_code == 200
    assert response.json()["name"] == "Item 1"

3. Conclusion

A good project structure is essential for maintaining clean and scalable code. By following these best practices, you can ensure that your FastAPI project is well-organized, making development, debugging, and collaboration easier.

Want to stay updated on FastAPI best practices and tutorials? Subscribe to our newsletter for more insights, tips, and exclusive content.

Subscribe now and enhance your FastAPI projects!

Stackademic 🎓

Thank you for reading until the end. Before you go: