$npx -y skills add avibebuilder/claude-prime --skill backend-fastapi-pythonUse this skill for any Python backend work in this project: building FastAPI endpoints, writing service functions, defining Pydantic/SQLModel schemas, running Alembic migrations, or debugging 422 errors. Essential for authentication and authorization patterns — setting up get_cur
| 1 | # Backend FastAPI Python |
| 2 | |
| 3 | Project-specific conventions for FastAPI with SQLModel, pydantic-settings, and async SQLAlchemy. |
| 4 | |
| 5 | ## Architecture Decisions |
| 6 | |
| 7 | 1. **Services are stateless functions** — Not classes. First param is `db: AsyncSession`. |
| 8 | 2. **Generic response wrapper** — Always use `ApiResponse[T]` for consistency. |
| 9 | 3. **Dependencies chain** — `get_current_user` -> `require_auth` -> `require_admin`. |
| 10 | 4. **Module-scoped config** — Each module can have its own `{module}_config.py`. |
| 11 | 5. **Error codes for frontend** — `AppException(status, message, error_code)`. |
| 12 | |
| 13 | ## Gotchas |
| 14 | |
| 15 | - SQLModel `Relationship()` fields are NOT included in API responses by default. You must explicitly add them to `model_config` or use a separate response schema with those fields. |
| 16 | - `AsyncSession.refresh()` does not load relationships. After commit, re-query with `.options(selectinload(...))` if you need related objects. |
| 17 | - Pydantic V2 uses `model_validator` not `validator`. The `@validator` decorator is V1 and will break silently or raise deprecation warnings. |
| 18 | - `Depends()` in FastAPI creates a NEW instance per request — don't store state in dependency return values expecting it to persist. |
| 19 | - Background tasks (`BackgroundTasks`) run AFTER the response is sent. If they fail, the client already got a 200. Use proper task queues (Celery, ARQ) for anything that must not silently fail. |
| 20 | - Alembic `--autogenerate` misses: table renames (generates drop+create), index changes on existing columns, and `Enum` type modifications in PostgreSQL. Always review generated migrations. |
| 21 | - `async def` endpoints block the event loop if you call sync I/O inside them. Use `run_in_executor` for sync libraries or define the endpoint as `def` (FastAPI runs sync endpoints in a threadpool). |
| 22 | - `HTTPException` from FastAPI and `HTTPException` from Starlette are different classes. Importing the wrong one causes middleware to miss exception handlers. |
| 23 | - SQLAlchemy's `lazy="selectin"` on relationships causes N+1 queries in async sessions. Use explicit `selectinload()` in queries instead. |
| 24 | - `Optional[str] = None` in query params makes the field optional. `str = None` also works but loses type information — prefer the explicit `Optional` form. |
| 25 | - When using `response_model`, FastAPI filters OUT any fields not in the model. If your response is missing data, check that the response model includes all fields, not just the ORM model. |
| 26 | |
| 27 | ## References |
| 28 | |
| 29 | | When you need... | Read | |
| 30 | |------------------|------| |
| 31 | | Directory layout | [file-structure.md](./references/file-structure.md) | |
| 32 | | Settings and env vars | [configuration.md](./references/configuration.md) | |
| 33 | | Database sessions and connections | [database.md](./references/database.md) | |
| 34 | | ORM models | [models.md](./references/models.md) | |
| 35 | | Request/response schemas | [schemas.md](./references/schemas.md) | |
| 36 | | Router and endpoint patterns | [routing.md](./references/routing.md) | |
| 37 | | Service layer patterns | [services.md](./references/services.md) | |
| 38 | | Dependency injection | [dependencies.md](./references/dependencies.md) | |
| 39 | | Middleware setup | [middleware.md](./references/middleware.md) | |
| 40 | | Error handling | [error-handling.md](./references/error-handling.md) | |
| 41 | | Auth flow example | [auth.md](./references/auth.md) | |