Stack Knowledge
This skill provides stack-specific patterns for agents making architectural and implementation decisions.
FastAPI
- Async route handlers by default — use
async def for all endpoints
- Dependency injection with
Depends() for database sessions, auth, shared logic
- Pydantic V2 models for all request/response schemas — never return raw dicts
- Use
lifespan context manager for startup/shutdown (DB connections, ML model loading)
- Router organization:
src/api/routes/ with one router per domain
- Error handling:
HTTPException for expected errors, exception handlers for unexpected
- Consistent error shape:
{ "error": str, "message": str, "details": dict }
- Background tasks with
BackgroundTasks for non-blocking operations
PostgreSQL + SQLAlchemy
- SQLAlchemy 2.0 style — use
select(), insert(), update(), delete() statements
- Async engine with
create_async_engine() and async_sessionmaker()
- Connection string via
DATABASE_URL env var
- Models in
src/models/ with one file per entity
- Use
mapped_column() with explicit types — no implicit column inference
- Index every column used in WHERE, JOIN, or ORDER BY
- Relationship loading: use
selectinload() for collections, joinedload() for single relations
- Session management: request-scoped sessions via
Depends(get_db)
Alembic Migrations
- Config in
alembic.ini, env in alembic/env.py
- Development:
alembic revision --autogenerate -m "description"
- Production: manually reviewed migrations, never autogenerate blindly
- Always test migrations both up and down (rollback)
- One migration per logical change — don't batch unrelated schema changes
PyTorch / ML
- Models in
src/models/ml/ — separate from SQLAlchemy ORM models
- Training scripts in
src/training/
- Inference endpoints load models at startup via lifespan, not per-request
- Reproducibility: set seeds (
torch.manual_seed, numpy.random.seed), log hyperparameters
- Model versioning: save checkpoints with metadata (epoch, metrics, config)
- Data pipelines in
src/pipelines/ — pandas for ETL, torch DataLoaders for training
pandas / Data Processing
- Use
pandas for data loading, cleaning, transformation
- Prefer vectorized operations over iterrows — never loop over DataFrame rows
- Type hints with
pd.DataFrame and column schemas documented
- For large datasets: chunked reading with
chunksize, or use polars for performance-critical paths
- CSV/Parquet I/O: explicit dtypes on read, compression on write
Testing (pytest)
- Test structure mirrors source:
tests/api/, tests/models/, tests/pipelines/
- Use
httpx.AsyncClient with ASGITransport for API tests
- Fixtures in
conftest.py for database sessions, test client, sample data
- Use
pytest-asyncio for async test support
- Factory fixtures for test data — never hard-code test objects across files
- ML tests: test model forward pass shapes, loss convergence on tiny datasets
Project Structure
src/
├── api/
│ ├── routes/ # FastAPI routers (one per domain)
│ ├── deps.py # Shared dependencies (get_db, get_current_user)
│ └── middleware.py # CORS, auth, logging middleware
├── models/
│ ├── db/ # SQLAlchemy ORM models
│ └── ml/ # PyTorch model definitions
├── schemas/ # Pydantic request/response schemas
├── pipelines/ # Data processing pipelines
├── training/ # ML training scripts
├── services/ # Business logic layer
├── config.py # Settings via pydantic-settings
└── main.py # FastAPI app factory
alembic/ # Database migrations
tests/ # Mirror of src/ structure
1---2name: stack-knowledge-23description: Project technology stack patterns for FastAPI + PostgreSQL + SQLAlchemy + Alembic + PyTorch + pandas4---56# Stack Knowledge78This skill provides stack-specific patterns for agents making architectural and implementation decisions.910## FastAPI1112- Async route handlers by default — use `async def` for all endpoints13- Dependency injection with `Depends()` for database sessions, auth, shared logic14- Pydantic V2 models for all request/response schemas — never return raw dicts15- Use `lifespan` context manager for startup/shutdown (DB connections, ML model loading)16- Router organization: `src/api/routes/` with one router per domain17- Error handling: `HTTPException` for expected errors, exception handlers for unexpected18- Consistent error shape: `{ "error": str, "message": str, "details": dict }`19- Background tasks with `BackgroundTasks` for non-blocking operations2021## PostgreSQL + SQLAlchemy2223- SQLAlchemy 2.0 style — use `select()`, `insert()`, `update()`, `delete()` statements24- Async engine with `create_async_engine()` and `async_sessionmaker()`25- Connection string via `DATABASE_URL` env var26- Models in `src/models/` with one file per entity27- Use `mapped_column()` with explicit types — no implicit column inference28- Index every column used in WHERE, JOIN, or ORDER BY29- Relationship loading: use `selectinload()` for collections, `joinedload()` for single relations30- Session management: request-scoped sessions via `Depends(get_db)`3132## Alembic Migrations3334- Config in `alembic.ini`, env in `alembic/env.py`35- Development: `alembic revision --autogenerate -m "description"`36- Production: manually reviewed migrations, never autogenerate blindly37- Always test migrations both up and down (rollback)38- One migration per logical change — don't batch unrelated schema changes3940## PyTorch / ML4142- Models in `src/models/ml/` — separate from SQLAlchemy ORM models43- Training scripts in `src/training/`44- Inference endpoints load models at startup via lifespan, not per-request45- Reproducibility: set seeds (`torch.manual_seed`, `numpy.random.seed`), log hyperparameters46- Model versioning: save checkpoints with metadata (epoch, metrics, config)47- Data pipelines in `src/pipelines/` — pandas for ETL, torch DataLoaders for training4849## pandas / Data Processing5051- Use `pandas` for data loading, cleaning, transformation52- Prefer vectorized operations over iterrows — never loop over DataFrame rows53- Type hints with `pd.DataFrame` and column schemas documented54- For large datasets: chunked reading with `chunksize`, or use `polars` for performance-critical paths55- CSV/Parquet I/O: explicit dtypes on read, compression on write5657## Testing (pytest)5859- Test structure mirrors source: `tests/api/`, `tests/models/`, `tests/pipelines/`60- Use `httpx.AsyncClient` with `ASGITransport` for API tests61- Fixtures in `conftest.py` for database sessions, test client, sample data62- Use `pytest-asyncio` for async test support63- Factory fixtures for test data — never hard-code test objects across files64- ML tests: test model forward pass shapes, loss convergence on tiny datasets6566## Project Structure6768```69src/70├── api/71│ ├── routes/ # FastAPI routers (one per domain)72│ ├── deps.py # Shared dependencies (get_db, get_current_user)73│ └── middleware.py # CORS, auth, logging middleware74├── models/75│ ├── db/ # SQLAlchemy ORM models76│ └── ml/ # PyTorch model definitions77├── schemas/ # Pydantic request/response schemas78├── pipelines/ # Data processing pipelines79├── training/ # ML training scripts80├── services/ # Business logic layer81├── config.py # Settings via pydantic-settings82└── main.py # FastAPI app factory83alembic/ # Database migrations84tests/ # Mirror of src/ structure85```