From farm-stack
Use when building or scaffolding FastAPI + React + MongoDB (FARM stack) applications. Covers project structure, async MongoDB with Motor, Pydantic v2 models, config patterns, Docker setup, and testing conventions.
How this skill is triggered — by the user, by Claude, or both
Slash command
/farm-stack:farm-stackThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
| Task | Approach |
| Task | Approach |
|---|---|
| New project | Use /scaffold-farm or follow structure below |
| Add feature | Create model -> service -> route (one file per domain per layer) |
| Config | Dual-layer: env vars (priority) + YAML fallback |
| Database | Motor async client, never sync PyMongo in routes |
| Docker | Alpine-based, compose with MongoDB + backend |
| Frontend | Vite + React, proxy API in dev, static mount in prod |
| Testing | pytest + httpx async, 80%+ coverage target |
project-root/
├── main.py # FastAPI entry with lifespan
├── requirements.txt # Pinned dependencies
├── pyproject.toml # Tool config (ruff, pytest)
├── .env.example # Environment template
├── Dockerfile # python:3.13-alpine
├── docker-compose.yml # MongoDB + backend + optional frontend
├── Makefile # Dev commands (run, test, lint, build)
├── config/
│ ├── __init__.py
│ ├── secrets_parser.py # Env + YAML config loader, Motor client
│ ├── secrets.yml # Local dev config (git-ignored)
│ ├── secrets.yml.example # Template with placeholders
│ └── logging.py # Logging setup
├── models/ # Pydantic v2 data models
│ └── {domain}_models.py # Base -> Create -> Response per domain
├── routes/ # API endpoint handlers
│ └── {domain}_routes.py # APIRouter per domain
├── services/ # Business logic layer
│ └── {domain}_services.py # Async MongoDB operations
├── utils/ # Shared utilities
├── tests/ # pytest suite
│ └── test_{domain}.py # Per-domain tests
├── client/ # React + Vite frontend
│ ├── package.json
│ ├── vite.config.js
│ └── src/
└── client_build/ # Built frontend (served as static)
Domain files follow strict naming: {domain}_models.py, {domain}_services.py, {domain}_routes.py, test_{domain}.py.
Adding a "product" feature creates: product_models.py, product_services.py, product_routes.py, test_product.py.
Dual-layer precedence:
python-dotenvconfig/secrets.yml for local dev# config/secrets_parser.py
# 1. dotenv.load_dotenv()
# 2. Read secrets.yml as fallback defaults
# 3. Build MongoDB connection string
# 4. Create Motor async client
# 5. Export get_database(), get_collection()
MongoDB connection variations:
mongodb://localhost:27017/dbnamemongodb://user:pass@host:port/dbnamemongodb+srv://user:[email protected]/dbnameMONGODB_URL bypasses all YAML parsing# Database
MONGODB_HOST=localhost
MONGODB_PORT=27017
MONGODB_DATABASE=app_name
MONGODB_USERNAME=
MONGODB_PASSWORD=
# Server
API_HOST=0.0.0.0
API_PORT=8000
DEBUG=True
# CORS
CORS_ORIGINS=http://localhost:3000,http://localhost:5173
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup: init DB connections, caches
yield
# Shutdown: close connections
app = FastAPI(title="App Name", version="1.0.0", lifespan=lifespan)
# CORS from env (comma-separated origins)
cors_origins = os.getenv("CORS_ORIGINS", "http://localhost:3000").split(",")
app.add_middleware(CORSMiddleware,
allow_origins=cors_origins, allow_credentials=True,
allow_methods=["*"], allow_headers=["*"],
)
# Mount routers with versioned prefix
app.include_router(domain_router, prefix="/api/v1", tags=["domain"])
@app.get("/health")
async def health_check():
return {"status": "healthy"}
# Serve built frontend in production
if os.path.exists("client_build"):
app.mount("/", StaticFiles(directory="client_build", html=True))
Three-tier: Base (shared fields) -> Create (input extras) -> Response (id + timestamps).
from pydantic import BaseModel, EmailStr
from datetime import datetime
class UserBase(BaseModel):
name: str
email: EmailStr
class UserCreate(UserBase):
password: str
class User(UserBase):
id: str
created_at: datetime
model_config = {"from_attributes": True}
from config.secrets_parser import get_database
class DomainService:
def __init__(self):
self.db = get_database()
self.collection = self.db.domain_name
async def get_all(self) -> list:
items = []
async for item in self.collection.find():
item["id"] = str(item["_id"])
del item["_id"]
items.append(item)
return items
async def create(self, data: DomainCreate) -> dict:
doc = data.model_dump()
doc["created_at"] = datetime.now(timezone.utc)
result = await self.collection.insert_one(doc)
doc["id"] = str(result.inserted_id)
return doc
Always convert _id (ObjectId) to string id when returning from MongoDB.
from fastapi import APIRouter, HTTPException
router = APIRouter()
service = DomainService()
@router.get("/items", response_model=list[Item])
async def get_items():
return await service.get_all()
@router.post("/items", response_model=Item, status_code=201)
async def create_item(data: ItemCreate):
return await service.create(data)
# Check latest stable: https://hub.docker.com/_/python
FROM python:3.13-alpine
WORKDIR /app
RUN adduser -D appuser
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
USER appuser
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compose.yml includes: MongoDB 8+ with persistent volume, backend with hot-reload, shared bridge network. Environment flows from .env to compose to containers.
Version numbers below are minimums as of early 2026 -- check PyPI for latest stable:
fastapi>=0.115.0
uvicorn[standard]>=0.34.0
motor>=3.7.0
pydantic[email]>=2.10.0
PyYAML>=6.0
python-dotenv>=1.0.0
passlib[bcrypt]>=1.7.4
python-multipart>=0.0.20
Dev: pytest, httpx, ruff, coverage
| Don't | Do Instead |
|---|---|
| Sync PyMongo in FastAPI routes | Motor async client |
| Hardcode CORS origins | Read from env var |
Commit config/secrets.yml | Only commit secrets.yml.example |
Use from_attributes without converting _id | Convert ObjectId to str first |
| Put business logic in routes | Use service layer |
Use class Config: in Pydantic v2 | Use model_config = {} dict |
| Run as root in Docker | Add non-root user |
npx claudepluginhub sagargupta16/claude-skills --plugin farm-stackGenerates production-ready FastAPI project structures with async patterns, dependency injection, middleware, error handling, and best practices for high-performance APIs.
Creates production-ready FastAPI projects with async patterns, dependency injection, middleware, and error handling. Use for new FastAPI apps, async REST APIs, or backend setups with PostgreSQL/MongoDB.
Generates production-ready FastAPI project structures with async patterns, dependency injection, middleware, and testing setup. Use when starting new FastAPI APIs or microservices.