Python development. Use for Python, FastAPI, Pydantic, asyncpg, pytest, pandas, SQLAlchemy.
Installation
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
pre-commit run --files <touched> — full hook chain (ruff + ruff-format + check-toml/yaml/merge-conflict + commitizen)
Phase 3 Tier B additional MCP verifications:
PostgreSQL MCP → Query DB state before/after
Legacy DB MCP → Query legacy databases for data verification
Implementation Rules (Phase 3)
Model structure — Domain-driven app/model/<domain>/{models.py, requests.py, responses.py}; cross-cutting types in model/common/. Separate *Request from *Response; never merge. When a response carries both DB-mapped fields AND computed/Python-only fields, split into a *DbRow base (SELECT columns only) + a *Model subclass that adds enrichment and @computed_field properties. Query builders and aggregation utilities receive the DB-row base. Composition over deep inheritance.
Settings — BaseSettings hierarchy, SecretStr for sensitive values, @lru_cache(maxsize=1) on the get_settings accessor. Tests that mutate env call get_settings.cache_clear().
Error handling — One global Exception handler in create_app + a per-domain-error handler in app/exception_handlers.py. Domain errors raised straight from service/repository; never wrapped in HTTPException. Handler detail strings hardcoded — never str(exc).
Async hygiene — except asyncio.CancelledError: raise separately from except Exception. Bounded asyncio.Queue for background work. asyncio.gather for independent queries. Heavy SDK clients constructed once at lifespan; blocking calls wrapped in asyncio.to_thread at adapter seams.
Minimize complexity — generators for large data, dict lookups over list scans, function length ~50-60 lines (soft guide; extract a helper past that).
Staff Review Configuration (Phase 4)
Patterns file path: Path to this skill's patterns.md
Python-Specific Rules
Type hints are mandatory — use Pydantic and strict typing per patterns.md.
All imports at module top — never inside a function or method.
Tests are required during implementation, not after — RED → GREEN → REFACTOR for every behavior.
No positive claim without running pytest tests/ -x -q.
Pydantic model fields with non-trivial types, defaults, or validators MUST have WHY comments explaining the rationale (data source format, business rule, cross-system constraint).
One global FastAPI Exception handler in create_app; never per-endpoint try / except → HTTPException.
TestClient(app, raise_server_exceptions=False) for any test that exercises the global handler.
Domain metadata (schema names, plant codes, environment-specific strings) lives on an Enum property — never hardcoded in N places.
Quality Checklist (Python-Specific)
Add these to the shared workflow's verification checklist:
Python 3.14 (built-in list[str] / dict[str, int], PEP 604 str | None; no from __future__ import annotations)
No from typing import List, Dict, Optional — use built-ins
Pydantic for all structured data; BaseSettings for configuration; SecretStr for sensitive values
Request/Response Pydantic models separated; *DbRow base + *Model subclass where DB-mapped and computed fields coexist
json_schema_extra used ONLY for OpenAPI examples — never for internal flags
One global Exception handler + per-domain handlers in app/exception_handlers.py; routes/services raise domain errors, never HTTPException
Sanitized 500 detail — never leak str(exc) to clients
except asyncio.CancelledError re-raised; never swallowed in except BaseException
Middleware order declared in one list and pinned by a test
@lru_cache(maxsize=1) on get_settings; tests call cache_clear() after env mutations
Heavy SDK clients constructed once at lifespan; blocking calls wrapped in asyncio.to_thread at adapter seams
Repository returns typed Pydantic models, not raw asyncpg.Record
Parameterized SQL ($1, $2) — no f-string interpolation of user input
Independent DB queries run concurrently (asyncio.gather)
No fetch-then-filter — JOIN or IN (subquery) in one round trip
asyncio_mode="auto" in pyproject.toml; markers golden, e2e, integration
TestClient(app, raise_server_exceptions=False) for tests that exercise the global handler
MagicMock(spec=Class) + AsyncMock for async methods; autouse fixture clears app.dependency_overrides