Spartan-ai-toolkit python-api-endpoint-creator
Creates FastAPI endpoints with layered architecture (Router → Service → Repository). Use when creating new API endpoints, CRUD operations, or scaffolding a new domain module in a FastAPI project.
git clone https://github.com/c0x12c/ai-toolkit
T=$(mktemp -d) && git clone --depth=1 https://github.com/c0x12c/ai-toolkit "$T" && mkdir -p ~/.claude/skills && cp -r "$T/toolkit/skills/python-api-endpoint-creator" ~/.claude/skills/spartan-stratos-spartan-ai-toolkit-python-api-endpoint-creator && rm -rf "$T"
toolkit/skills/python-api-endpoint-creator/SKILL.mdPython API Endpoint Creator
Creates complete FastAPI endpoints following strict layered architecture patterns.
When to Use
- Creating a new REST API endpoint from scratch
- Adding CRUD operations for a new domain entity
- Setting up the full stack: Router → Service → Repository → Tests
- Scaffolding a new domain module
Process
- Pydantic Schemas — Create/Update/Response in
schemas.py - SQLAlchemy Model — with SoftDeleteMixin in
models.py - Repository — async CRUD with soft delete in
repository.py - Service — business logic, HTTPException for errors in
service.py - Dependencies —
,get_db
inget_servicedependencies.py - Router — thin endpoints, Depends() for everything in
router.py - Tests — httpx AsyncClient tests in
tests/
See code-patterns.md for complete templates for each file.
Architecture
Router (APIRouter) → Service → Repository → Database ↓ ↓ ↓ Depends() Business logic SQLAlchemy Pydantic schemas HTTPException AsyncSession Status codes Validation Soft delete
Hard Rules
- POST for all mutations — GET for reads, POST for create/update/delete
- Query params for IDs —
, never path params?id=xxx/{id} - Routers are thin — just delegation, no business logic
- Services raise HTTPException — for expected errors (404, 409, 422)
- Repositories handle soft delete — filter
in all queriesdeleted_at.is_(None)
for all endpoints — unless CPU-boundasync def
Gotchas
-
Forgetting
makes your API leak internal fields. Always setresponse_model
on endpoints. Without it, FastAPI serializes the raw return value, which may includeresponse_model=YourSchema
,hashed_password
, or other internal fields from your SQLAlchemy model.deleted_at -
creates a new instance per request — not a singleton. If your service holds state, it will be lost between requests. Services should be stateless. If you need shared state, use app state or a cache.Depends() -
in the dependency, not in the repository. Theawait db.commit()
dependency handles commit/rollback. If you also commit inside the repository, you get double-commit bugs or premature commits before all operations complete.get_db -
422 errors from Pydantic are opaque by default. Override the
handler to return field-level errors. The default just says "validation error" with no useful detail for the frontend.RequestValidationError -
Missing
on create endpoints. FastAPI defaults to 200. Explicitly setstatus_code=201
on POST create routes andstatus_code=status.HTTP_201_CREATED
on delete routes.status_code=status.HTTP_204_NO_CONTENT