Module-scoped config — Each module can have its own {module}_config.py.
Error codes for frontend — AppException(status, message, error_code).
Gotchas
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.
AsyncSession.refresh() does not load relationships. After commit, re-query with .options(selectinload(...)) if you need related objects.
Pydantic V2 uses model_validator not validator. The @validator decorator is V1 and will break silently or raise deprecation warnings.
Depends() in FastAPI creates a NEW instance per request — don't store state in dependency return values expecting it to persist.
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.
Alembic --autogenerate misses: table renames (generates drop+create), index changes on existing columns, and Enum type modifications in PostgreSQL. Always review generated migrations.
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).
HTTPException from FastAPI and HTTPException from Starlette are different classes. Importing the wrong one causes middleware to miss exception handlers.
SQLAlchemy's lazy="selectin" on relationships causes N+1 queries in async sessions. Use explicit selectinload() in queries instead.
Optional[str] = None in query params makes the field optional. str = None also works but loses type information — prefer the explicit Optional form.
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.
1---2name: avibebuilder-claude-prime-claude-prime3description: Backend FastAPI Python4---56# Backend FastAPI Python78Project-specific conventions for FastAPI with SQLModel, pydantic-settings, and async SQLAlchemy.910## Architecture Decisions11121. **Services are stateless functions** — Not classes. First param is `db: AsyncSession`.132. **Generic response wrapper** — Always use `ApiResponse[T]` for consistency.143. **Dependencies chain** — `get_current_user` -> `require_auth` -> `require_admin`.154. **Module-scoped config** — Each module can have its own `{module}_config.py`.165. **Error codes for frontend** — `AppException(status, message, error_code)`.1718## Gotchas1920- 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.21- `AsyncSession.refresh()` does not load relationships. After commit, re-query with `.options(selectinload(...))` if you need related objects.22- Pydantic V2 uses `model_validator` not `validator`. The `@validator` decorator is V1 and will break silently or raise deprecation warnings.23- `Depends()` in FastAPI creates a NEW instance per request — don't store state in dependency return values expecting it to persist.24- 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.25- Alembic `--autogenerate` misses: table renames (generates drop+create), index changes on existing columns, and `Enum` type modifications in PostgreSQL. Always review generated migrations.26- `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).27- `HTTPException` from FastAPI and `HTTPException` from Starlette are different classes. Importing the wrong one causes middleware to miss exception handlers.28- SQLAlchemy's `lazy="selectin"` on relationships causes N+1 queries in async sessions. Use explicit `selectinload()` in queries instead.29- `Optional[str] = None` in query params makes the field optional. `str = None` also works but loses type information — prefer the explicit `Optional` form.30- 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.3132## References3334| When you need... | Read |35|------------------|------|36| Directory layout | [file-structure.md](./references/file-structure.md) |37| Settings and env vars | [configuration.md](./references/configuration.md) |38| Database sessions and connections | [database.md](./references/database.md) |39| ORM models | [models.md](./references/models.md) |40| Request/response schemas | [schemas.md](./references/schemas.md) |41| Router and endpoint patterns | [routing.md](./references/routing.md) |42| Service layer patterns | [services.md](./references/services.md) |43| Dependency injection | [dependencies.md](./references/dependencies.md) |44| Middleware setup | [middleware.md](./references/middleware.md) |45| Error handling | [error-handling.md](./references/error-handling.md) |46| Auth flow example | [auth.md](./references/auth.md) |4748---49> Source: [avibebuilder/claude-prime](https://github.com/avibebuilder/claude-prime) — distributed by [TomeVault](https://tomevault.io).50<!-- tomevault:4.0:skill_md:2026-06-18 -->
Run npx skillmds@latest add tomevault-io/avibebuilder-claude-prime-claude-prime in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Backend FastAPI Python It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
tomevault-io (@tomevault-io) published this skill. Their other Agent Skills are listed on their SkillMD profile.