From qe-framework
Builds high-performance async Python APIs with FastAPI and Pydantic V2, including REST endpoints, JWT auth, WebSocket endpoints, and async SQLAlchemy operations.
How this skill is triggered — by the user, by Claude, or both
Slash command
/qe-framework:Qfastapi-expertThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Deep expertise in async Python, Pydantic V2, and production-grade API development with FastAPI.
Deep expertise in async Python, Pydantic V2, and production-grade API development with FastAPI.
pytest after each endpoint group; verify /docs before proceedingBasic: Route with Pydantic Model + Docstring
@router.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, db: DbDep) -> UserResponse:
"""Retrieve a user by ID. Returns 404 if not found."""
user = await crud.get_user(db, user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
Error Handling: Custom Exception + HTTPException
class DuplicateEmailError(Exception):
pass
@router.exception_handler(DuplicateEmailError)
async def duplicate_email_handler(req, exc):
return JSONResponse(status_code=409, content={"detail": "Email already exists"})
Advanced: Dependency Injection + Async SQLAlchemy
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)], db: DbDep) -> User:
"""Verify JWT and return authenticated user."""
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user = await crud.get_user(db, int(payload["sub"]))
if not user:
raise HTTPException(status_code=401, detail="Invalid token")
return user
Use Google-style Python docstrings:
def process_payment(amount: float, user_id: int) -> dict[str, str]:
"""Process a payment transaction.
Args:
amount: Payment amount in USD.
user_id: ID of the user making payment.
Returns:
Transaction confirmation with status and ID.
Raises:
ValueError: If amount is negative.
HTTPException: If user not found (status 404).
"""
Apply in order:
ruff check .mypy . --strictblack .Config in pyproject.toml:
[tool.ruff]
line-length = 100
[tool.mypy]
strict = true
plugins = ["pydantic.mypy"]
allow_origins=["*"] with credentialsexclude_fields| Wrong | Correct |
|---|---|
def get_user(db: Session) (sync) | async def get_user(db: AsyncSession) |
No validation: email: str | Pydantic validation: email: EmailStr |
Global state: DB = create_engine() | Dependency injection: Depends(get_db) |
| Fat route: 50-line endpoint logic | Extract to service layer: await UserService.create(...) |
Manual parsing: try/except json | Pydantic auto-validation + auto-docs |
Load detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Pydantic V2 | references/pydantic-v2.md | Creating schemas, validation, model_config |
| SQLAlchemy | references/async-sqlalchemy.md | Async database, models, CRUD operations |
| Endpoints | references/endpoints-routing.md | APIRouter, dependencies, routing |
| Authentication | references/authentication.md | JWT, OAuth2, get_current_user |
| Testing | references/testing-async.md | pytest-asyncio, httpx, fixtures |
| Django Migration | references/migration-from-django.md | Migrating from Django/DRF to FastAPI |
field_validator, model_validator, model_config)Annotated pattern for dependency injectionX | None instead of Optional[X]@validator, class Config)When implementing FastAPI features, provide:
FastAPI, Pydantic V2, async SQLAlchemy, Alembic migrations, JWT/OAuth2, pytest-asyncio, httpx, BackgroundTasks, WebSockets, dependency injection, OpenAPI/Swagger
npx claudepluginhub inho-team/qe-framework --plugin qe-frameworkCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.