Claude-skill-registry fastapi-setup
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.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/fastapi-setup" ~/.claude/skills/majiayu000-claude-skill-registry-fastapi-setup && rm -rf "$T"
manifest:
skills/data/fastapi-setup/SKILL.mdsource content
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:
-
starts successfullyuv run uvicorn src.main:app --reload - http://localhost:8000 returns JSON response
- http://localhost:8000/docs shows Swagger UI
- http://localhost:8000/health returns healthy status
-
runs and passesuv run pytest -
file exists and has DATABASE_URL.env - All init.py files created
- Alembic initialized successfully
Next Steps
After basic setup:
- Create database models in
src/models/ - Create API routers in
src/routers/ - Set up JWT authentication middleware
- Create first Alembic migration
- 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
instead of justuv run pythonpython
Database connection errors:
- Verify DATABASE_URL in .env
- Check Neon database is running
- Test connection with psql
References
- FastAPI: https://fastapi.tiangolo.com/
- UV: https://docs.astral.sh/uv/
- SQLModel: https://sqlmodel.tiangolo.com/
- Alembic: https://alembic.sqlalchemy.org/