skills/oimiragieo/agent-studio/python-backend-expert

python-backend-expert

SKILL.md

Python Backend Expert

alembic database migrations

When reviewing or writing code, apply these guidelines:

  • Use alembic for database migrations.

django class based views for htmx

When reviewing or writing code, apply these guidelines:

  • Use Django's class-based views for HTMX responses

django form handling

When reviewing or writing code, apply these guidelines:

  • Implement Django forms for form handling
  • Use Django's form validation for HTMX requests

django forms

When reviewing or writing code, apply these guidelines:

  • Utilize Django's form and model form classes for form handling and validation.
  • Use Django's validation framework to validate form and model data.
  • Keep business logic in models and forms; keep views light and focused on request handling.

django framework rules

When reviewing or writing code, apply these guidelines:

  • You always use the latest stable version of Django, and you are familiar with the latest features and best practices.

django middleware

When reviewing or writing code, apply these guidelines:

  • Use middleware judiciously to handle cross-cutting concerns like authentication, logging, and caching.
  • Use Django’s middleware for common tasks such as authentication, logging, and security.

django middleware for request response

When reviewing or writing code, apply these guidelines:

  • Utilize Django's middleware for request/response processing

django models

When reviewing or writing code, apply these guidelines:

  • Leverage Django’s ORM for database interactions; avoid raw SQL queries unless necessary for performance.
  • Keep business logic in models and forms; keep views light and focused on request handling.

django orm for database operations

When reviewing or writing code, apply these guidelines:

  • Implement Django ORM for database operations

django rest framework

When reviewing or writing code, apply these guidelines:

  • Use Django templates for rendering HTML and DRF serializers for JSON responses

django 5.x features (2025+)

When reviewing or writing code, apply these guidelines:

  • Django 5.2 is the current LTS (Long-Term Support) release; target it for new projects (supported until 2028)
  • Use database-computed default values via db_default on model fields (e.g., db_default=Now()) instead of Python-side defaults where the database should own the value
  • Use facet filters in the Django admin (ModelAdmin.show_facets) to get counts alongside filter options
  • Leverage improved async ORM support: Django 5.x expands async-native queryset methods — prefer await qs.acount(), await qs.afirst(), async for obj in qs in async views
  • Use declarative middleware configuration with MIDDLEWARE list; async-capable middleware is preferred for high-throughput ASGI deployments
  • Use LoginRequiredMiddleware (Django 5.1+) instead of decorating every view when all views require authentication
  • Use GeneratedField for database-generated columns (computed from other columns at the DB level)

fastapi patterns (2025+)

When reviewing or writing code, apply these guidelines:

  • Use the lifespan context manager (not deprecated @app.on_event) for startup/shutdown resource management:

    from contextlib import asynccontextmanager
    from fastapi import FastAPI
    
    @asynccontextmanager
    async def lifespan(app: FastAPI):
        # startup: initialize DB pool, HTTP clients, caches
        app.state.db_pool = await create_pool()
        yield
        # shutdown: close resources
        await app.state.db_pool.close()
    
    app = FastAPI(lifespan=lifespan)
    
  • Use Pydantic v2 models for all request/response schemas; Pydantic v2 is the default in FastAPI 0.100+. Use model_config = ConfigDict(...) instead of the inner class Config

  • Use pydantic-settings (BaseSettings) with lru_cache for config management:

    from functools import lru_cache
    from pydantic_settings import BaseSettings
    
    class Settings(BaseSettings):
        database_url: str
        model_config = ConfigDict(env_prefix="APP_")
    
    @lru_cache
    def get_settings() -> Settings:
        return Settings()
    
  • Scope dependencies correctly: per-request (DB sessions, auth), router-level (audit logging, namespace caches), application lifespan (Kafka producers, feature flag SDKs, tracing exporters)

  • Use Annotated type hints with Depends for cleaner dependency signatures:

    from typing import Annotated
    from fastapi import Depends
    
    DbSession = Annotated[AsyncSession, Depends(get_db)]
    CurrentUser = Annotated[User, Depends(get_current_user)]
    
  • Structure projects by domain: routers/, services/, repositories/, schemas/, models/ — avoid flat single-file apps beyond prototypes

  • Prefer async def path operations for I/O-bound routes; use def (sync) only for CPU-bound work that should run in a thread pool

  • Use APIRouter with prefix, tags, and dependencies to group related routes and apply shared middleware

sqlalchemy 2.0 async patterns (2025+)

When reviewing or writing code, apply these guidelines:

  • Use create_async_engine + async_sessionmaker (not the deprecated AsyncSession factory directly); create one engine per service at application startup

  • Use the new Mapped + mapped_column declarative style (SQLAlchemy 2.0+) instead of the legacy Column style:

    from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
    from sqlalchemy import String
    
    class Base(DeclarativeBase):
        pass
    
    class User(Base):
        __tablename__ = "users"
        id: Mapped[int] = mapped_column(primary_key=True)
        email: Mapped[str] = mapped_column(String(255), unique=True)
        is_active: Mapped[bool] = mapped_column(default=True)
    
  • Provide the DB session via FastAPI dependency injection using async with session scope:

    from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
    
    async_session = async_sessionmaker(engine, expire_on_commit=False)
    
    async def get_db() -> AsyncGenerator[AsyncSession, None]:
        async with async_session() as session:
            yield session
    
  • Use select() (not the legacy session.query()) for all queries in SQLAlchemy 2.0+

  • Use selectinload / joinedload explicitly to avoid implicit lazy-load I/O in async contexts (lazy loading raises MissingGreenlet in async)

  • For upserts, use insert().on_conflict_do_update() (PostgreSQL) or the dialect-specific equivalent rather than separate select + update round trips

  • Use connection pool sizing appropriate for async: async drivers (asyncpg, aiomysql) need smaller pools than sync drivers; pool_size=5, max_overflow=10 is a safe default for moderate load

python 3.13 / 3.14 features (2025+)

When reviewing or writing code, apply these guidelines:

  • Python 3.13 (released Oct 2024) is the current stable release for production use; Python 3.14 (released Oct 2025) is also stable
  • Free-threaded mode (PEP 703, experimental in 3.13, maturing in 3.14): The GIL can be disabled with python3.13t (free-threaded build). Avoid assuming GIL protection for shared mutable state in new code targeting 3.13+; use explicit locks or thread-safe data structures. Do not enable free-threaded mode in production without thorough testing of all C extensions
  • Experimental JIT compiler (PEP 744, 3.13+): Opt-in with PYTHON_JIT=1. Provides measurable speedups for tight loops and numeric code. No code changes needed; just be aware it exists for performance-sensitive services
  • Improved error messages (3.13+): Tracebacks are now syntax-highlighted in color by default. Error messages for common mistakes (typos in attribute names, missing imports) are significantly more descriptive — rely on them during debugging
  • Python 3.14 — Template strings / T-strings (PEP 750): New t"..." string literals that defer interpolation, useful for safe SQL/HTML construction without injection risk. Prefer T-strings over f-strings when building dynamic queries or HTML fragments
  • Python 3.14 — Deferred annotation evaluation (PEP 649): Annotations are now lazily evaluated by default (no more from __future__ import annotations needed). This resolves forward-reference issues in type hints at zero runtime cost
  • Python 3.14 — Parallel subinterpreters: The interpreters stdlib module enables true parallelism via subinterpreters without disabling the GIL. Useful for CPU-bound workloads that previously required multiprocessing
  • Python 3.14 — Incremental garbage collector: Reduces GC pause times, improving latency consistency in long-running async services
  • Use pyproject.toml (not setup.py / requirements.txt alone) for all new projects; use uv or pip with pyproject.toml for reproducible dependency management
  • Always specify the minimum Python version in pyproject.toml requires-python field

Consolidated Skills

This expert skill consolidates 1 individual skills:

  • python-backend-expert

Iron Laws

  1. ALWAYS use the lifespan context manager for FastAPI startup/shutdown resource management — @app.on_event is deprecated and will be removed in a future release.
  2. NEVER use session.query() in SQLAlchemy 2.0+ — use select() with the 2.0-style API; legacy query API will be removed.
  3. ALWAYS use parameterized queries or the ORM for all database operations — never construct SQL with string interpolation or f-strings (SQL injection vector).
  4. NEVER perform blocking I/O in async FastAPI routes — use async def with awaitable drivers or run_in_executor for blocking operations to avoid event loop starvation.
  5. ALWAYS validate all request data at the boundary using Pydantic v2 models — never pass raw request dicts into business logic layers.

Anti-Patterns

Anti-Pattern Why It Fails Correct Approach
Using @app.on_event for startup/shutdown Deprecated in FastAPI; will break on version upgrade Use @asynccontextmanager with lifespan parameter
Using session.query() in SQLAlchemy 2.0+ Legacy query API is deprecated and will be removed Use select() statements with session.execute()
Building SQL strings with f-strings or % formatting SQL injection vulnerability; critical security flaw Use parameterized queries via ORM or text() with bound params
Calling blocking I/O directly in async def routes Blocks the entire event loop; causes cascading latency Use awaitable async drivers; loop.run_in_executor() for sync code
Putting business logic in FastAPI path functions Couples routing to logic; makes unit testing impossible Extract logic to service/repository layer; inject via Depends()

Memory Protocol (MANDATORY)

Before starting:

cat .claude/context/memory/learnings.md

After completing: Record any new patterns or exceptions discovered.

ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.

Weekly Installs
61
GitHub Stars
16
First Seen
Jan 27, 2026
Installed on
github-copilot60
cursor59
gemini-cli58
opencode58
codex57
kimi-cli57