askill
fastapi-setup

fastapi-setupSafety 95Repository

Initialize FastAPI backend projects with UV package manager, configure project structure, install dependencies, and set up basic FastAPI application. Use when setting up a new FastAPI backend or initializing the backend directory for Phase 2.

0 stars
1.2k downloads
Updated 2/5/2026

Package Files

Loading files...
SKILL.md

FastAPI Project Setup

Quick reference for initializing FastAPI backend projects with modern tooling (UV, SQLModel, pytest).

Quick Start

1. Initialize Backend with UV

cd backend

# Initialize Python project with UV
uv init --name backend --python 3.13

# Create project structure
mkdir -p src/models src/routers src/services src/middleware src/schemas src/utils tests alembic

# Create __init__.py files
touch src/__init__.py
touch src/models/__init__.py
touch src/routers/__init__.py
touch src/services/__init__.py
touch src/middleware/__init__.py
touch src/schemas/__init__.py
touch src/utils/__init__.py
touch tests/__init__.py

2. Install Dependencies

# Core dependencies
uv add fastapi[all]
uv add sqlmodel
uv add psycopg2-binary
uv add python-jose[cryptography]
uv add passlib[bcrypt]
uv add python-dotenv
uv add alembic

# Development dependencies
uv add --dev pytest
uv add --dev pytest-cov
uv add --dev httpx
uv add --dev pytest-asyncio

3. Create Basic FastAPI App

Create src/main.py:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import os
from dotenv import load_dotenv

load_dotenv()

app = FastAPI(
    title="Todo API",
    description="RESTful API for Todo Web Application - Phase 2",
    version="1.0.0"
)

# CORS configuration
origins = [
    os.getenv("FRONTEND_URL", "http://localhost:3000"),
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
async def root():
    return {"message": "Todo API is running", "version": "1.0.0"}

@app.get("/health")
async def health_check():
    return {"status": "healthy"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

4. Create Configuration

Create src/config.py:

from pydantic_settings import BaseSettings
from functools import lru_cache

class Settings(BaseSettings):
    # Database
    DATABASE_URL: str

    # Authentication
    BETTER_AUTH_SECRET: str
    JWT_ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_DAYS: int = 7

    # CORS
    FRONTEND_URL: str = "http://localhost:3000"

    # Environment
    ENVIRONMENT: str = "development"

    class Config:
        env_file = ".env"
        case_sensitive = True

@lru_cache()
def get_settings():
    return Settings()

settings = get_settings()

5. Create Environment Variables Template

Create .env.example:

# Database
DATABASE_URL=postgresql://user:password@localhost:5432/dbname

# Authentication
BETTER_AUTH_SECRET=your-secret-key-here-min-32-characters

# CORS
FRONTEND_URL=http://localhost:3000

# Environment
ENVIRONMENT=development

Create actual .env file:

cp .env.example .env
# Edit .env with actual values

6. Set Up Database Connection

Create src/database.py:

from sqlmodel import create_engine, Session, SQLModel
from sqlalchemy.pool import NullPool
from src.config import settings

engine = create_engine(
    settings.DATABASE_URL,
    echo=settings.ENVIRONMENT == "development",
    poolclass=NullPool,  # Let Neon handle pooling
    connect_args={
        "connect_timeout": 10,
        "options": "-c timezone=utc"
    }
)

def create_db_and_tables():
    """Create all database tables"""
    SQLModel.metadata.create_all(engine)

def get_session():
    """FastAPI dependency for database sessions"""
    with Session(engine) as session:
        yield session

7. Initialize Alembic for Migrations

# Initialize Alembic
alembic init alembic

# Edit alembic.ini - comment out the sqlalchemy.url line
# It will be set from environment variable

# Edit alembic/env.py

Update alembic/env.py:

from logging.config import fileConfig
from sqlmodel import SQLModel
from sqlalchemy import engine_from_config, pool
from alembic import context
import os
from dotenv import load_dotenv

# Load environment variables
load_dotenv()

# Import all models so Alembic can detect them
from src.models.task import Task  # Import as you create models

# Alembic Config object
config = context.config

# Set DATABASE_URL from environment
config.set_main_option("sqlalchemy.url", os.getenv("DATABASE_URL"))

# Interpret the config file for Python logging
if config.config_file_name is not None:
    fileConfig(config.config_file_name)

# Set target metadata for autogenerate
target_metadata = SQLModel.metadata

# ... rest of env.py (keep default functions)

8. Create Basic Test Setup

Create tests/conftest.py:

import pytest
from fastapi.testclient import TestClient
from sqlmodel import Session, create_engine, SQLModel
from sqlmodel.pool import StaticPool

from src.main import app
from src.database import get_session

@pytest.fixture(name="session")
def session_fixture():
    engine = create_engine(
        "sqlite:///:memory:",
        connect_args={"check_same_thread": False},
        poolclass=StaticPool,
    )
    SQLModel.metadata.create_all(engine)
    with Session(engine) as session:
        yield session

@pytest.fixture(name="client")
def client_fixture(session: Session):
    def get_session_override():
        return session

    app.dependency_overrides[get_session] = get_session_override
    client = TestClient(app)
    yield client
    app.dependency_overrides.clear()

Create tests/test_main.py:

def test_root(client):
    response = client.get("/")
    assert response.status_code == 200
    assert "message" in response.json()

def test_health_check(client):
    response = client.get("/health")
    assert response.status_code == 200
    assert response.json()["status"] == "healthy"

9. Create pyproject.toml

Create or update pyproject.toml:

[project]
name = "backend"
version = "1.0.0"
description = "Todo API Backend - Phase 2"
requires-python = ">=3.13"
dependencies = [
    "fastapi[all]>=0.115.0",
    "sqlmodel>=0.0.24",
    "psycopg2-binary>=2.9.9",
    "python-jose[cryptography]>=3.3.0",
    "passlib[bcrypt]>=1.7.4",
    "python-dotenv>=1.0.0",
    "alembic>=1.13.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0.0",
    "pytest-cov>=4.1.0",
    "httpx>=0.26.0",
    "pytest-asyncio>=0.23.0",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = "-v --cov=src --cov-report=term-missing"

10. Test the Setup

# Run the FastAPI server
cd backend
uv run uvicorn src.main:app --reload --port 8000

# In another terminal, run tests
uv run pytest

# Check code coverage
uv run pytest --cov=src --cov-report=html

Verification Checklist

After setup, verify:

Next Steps

After basic setup:

  1. Create database models in src/models/
  2. Create API routers in src/routers/
  3. Set up JWT authentication middleware
  4. Create first Alembic migration
  5. Write comprehensive tests

Troubleshooting

UV not found:

curl -LsSf https://astral.sh/uv/install.sh | sh

Import errors:

  • Ensure all init.py files exist
  • Check PYTHONPATH includes src directory
  • Use uv run python instead of just python

Database connection errors:

  • Verify DATABASE_URL in .env
  • Check Neon database is running
  • Test connection with psql

References

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

95/100Analyzed 2/10/2026

An exceptionally detailed and actionable guide for initializing a FastAPI project with modern tools like UV and SQLModel, including testing and migration setups.

95
100
90
100
100

Metadata

Licenseunknown
Version-
Updated2/5/2026
Publishermajiayu000

Tags

apici-cddatabaseobservabilitysecuritytesting