
Python Backend Expert
- 109 installs
- 36 repo stars
- Updated July 14, 2026
- oimiragieo/agent-studio
Implement Python APIs, services, workers, and data layers with idiomatic patterns, error handling, typing, and production-ready structure for agent-studio backends.
About
Expert guidance for building Python backends in agent-studio: APIs, services, workers, persistence, typing, and production patterns so agents ship reliable server-side code.
- Python API and service design patterns
- Typed, maintainable backend module structure
- Error handling and production service conventions
- Agent-studio backend implementation guidance
- Integration-ready server-side foundations
Python Backend Expert by the numbers
- 109 all-time installs (skills.sh)
- +2 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #95 of 290 Python skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oimiragieo/agent-studio --skill python-backend-expertAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 109 |
|---|---|
| repo stars | ★ 36 |
| Last updated | July 14, 2026 |
| Repository | oimiragieo/agent-studio ↗ |
What it does
Implement Python APIs, services, workers, and data layers with idiomatic patterns, error handling, typing, and production-ready structure for agent-studio backends.
Files
Python Backend Expert
<identity> You are a python backend expert with deep knowledge of python backend expert including django, fastapi, flask, sqlalchemy, and async patterns. You help developers write better code by applying established guidelines and best practices. </identity>
<capabilities>
- Review code for best practice compliance
- Suggest improvements based on domain patterns
- Explain why certain approaches are preferred
- Help refactor code to meet standards
- Provide architecture guidance
</capabilities>
<instructions>
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_defaulton 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 — preferawait qs.acount(),await qs.afirst(),async for obj in qsin async views - Use declarative middleware configuration with
MIDDLEWARElist; 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
GeneratedFieldfor database-generated columns (computed from other columns at the DB level)
fastapi patterns (2025+)
When reviewing or writing code, apply these guidelines:
- Use the
lifespancontext 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 innerclass Config - Use
pydantic-settings(BaseSettings) withlru_cachefor 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
Annotatedtype hints withDependsfor 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 defpath operations for I/O-bound routes; usedef(sync) only for CPU-bound work that should run in a thread pool - Use
APIRouterwithprefix,tags, anddependenciesto 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 deprecatedAsyncSessionfactory directly); create one engine per service at application startup - Use the new
Mapped+mapped_columndeclarative style (SQLAlchemy 2.0+) instead of the legacyColumnstyle:
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 withsession 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 legacysession.query()) for all queries in SQLAlchemy 2.0+ - Use
selectinload/joinedloadexplicitly to avoid implicit lazy-load I/O in async contexts (lazy loading raisesMissingGreenletin 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=10is 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 annotationsneeded). This resolves forward-reference issues in type hints at zero runtime cost - Python 3.14 — Parallel subinterpreters: The
interpretersstdlib 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(notsetup.py/requirements.txtalone) for all new projects; useuvorpipwithpyproject.tomlfor reproducible dependency management - Always specify the minimum Python version in
pyproject.tomlrequires-pythonfield
</instructions>
<examples> Example usage:
User: "Review this code for python-backend best practices"
Agent: [Analyzes code against consolidated guidelines and provides specific feedback]</examples>
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.mdAfter completing: Record any new patterns or exceptions discovered.
ASSUME INTERRUPTION: Your context may reset. If it's not in memory, it didn't happen.
Invoke the python-backend-expert skill and follow it exactly as presented to you
'use strict';
function postExecute(_input = {}, result = {}) {
return result;
}
module.exports = { postExecute };
'use strict';
/**
* python-backend-expert pre-execute hook
* Validates inputs and warns about missing Python backend strategy details.
*/
function preExecute(input = {}) {
const warnings = [];
// Required field: task
if (!input.task || typeof input.task !== 'string' || input.task.trim() === '') {
return {
continue: false,
error: 'Input validation failed: "task" is required and must be a non-empty string.',
};
}
// Warn if no framework specified for non-trivial tasks
const validFrameworks = ['fastapi', 'django', 'flask', 'litestar', 'none'];
if (!input.framework) {
warnings.push(
'No "framework" specified. Defaulting to generic Python backend guidance. ' +
`Supported: ${validFrameworks.join(', ')}.`
);
} else if (!validFrameworks.includes(input.framework)) {
warnings.push(
`Unknown framework "${input.framework}". Supported: ${validFrameworks.join(', ')}.`
);
}
// Warn if no type hints strategy noted
if (!input.pythonVersion) {
warnings.push(
'No "pythonVersion" specified. Defaulting to 3.12+ patterns. ' +
'Set pythonVersion to "3.10", "3.12", or "3.13" for version-specific advice.'
);
}
// Warn about async mode for FastAPI
if (input.framework === 'fastapi' && input.asyncMode === false) {
warnings.push(
'asyncMode is set to false for FastAPI. FastAPI strongly prefers async def ' +
'for I/O-bound endpoint handlers. Consider setting asyncMode: true.'
);
}
// Warn if ORM specified without framework context
const validOrms = ['sqlalchemy', 'tortoise', 'django-orm', 'none'];
if (input.ormChoice && !validOrms.includes(input.ormChoice)) {
warnings.push(`Unknown ORM "${input.ormChoice}". Supported: ${validOrms.join(', ')}.`);
}
if (input.ormChoice === 'django-orm' && input.framework && input.framework !== 'django') {
warnings.push(
'django-orm is only compatible with Django. Consider sqlalchemy or tortoise for other frameworks.'
);
}
return {
continue: true,
warnings: warnings.length > 0 ? warnings : undefined,
};
}
module.exports = { preExecute };
python-backend-expert Research Requirements
Generated: 2026-02-28
Skill Description
Python backend expert including Django, FastAPI, Flask, SQLAlchemy, and async patterns
Research Areas
- Current best practices for python-backend-expert
- Industry standards and tooling
- Integration patterns
Source References
- To be populated by skill-updater research phase
python-backend-expert Rules
Purpose
Python backend expert including Django, FastAPI, Flask, SQLAlchemy, and async patterns
Best Practices
- Follow domain-specific conventions
- Apply patterns consistently
- Prioritize type safety and testing
Integration Points
See SKILL.md for complete documentation.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "python-backend-expertInput",
"description": "Input schema for Python backend expert including Django, FastAPI, Flask, SQLAlchemy, and async patterns",
"type": "object",
"additionalProperties": true,
"properties": {
"target": {
"type": "string",
"description": "Target file or path for the skill to operate on"
},
"options": {
"type": "object",
"description": "Additional options for skill execution",
"additionalProperties": true
}
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "python-backend-expertOutput",
"type": "object",
"additionalProperties": true,
"properties": {
"ok": {
"type": "boolean"
},
"summary": {
"type": "string"
}
}
}
#!/usr/bin/env node
/**
* python-backend-expert - Enterprise Bundle Script
* Domain: Python backend (FastAPI, Django, Flask, SQLAlchemy 2.0, async patterns)
*/
'use strict';
const fs = require('fs');
const path = require('path');
const args = process.argv.slice(2);
if (args.includes('--help')) {
console.log(`
python-backend-expert - Expert Skill CLI
Usage:
node main.cjs --validate <file> Check Python file for type annotation coverage and async patterns
node main.cjs --analyze <file> Detect framework, Python version, and key dependencies
node main.cjs --help Show this help
Description:
Python backend expert including FastAPI, Django, Flask, SQLAlchemy 2.0, and async patterns.
Covers modern toolchain (uv, ruff, mypy, pyproject.toml) and Python 3.12+ type hints (PEP 695).
Domain Rules:
- FastAPI: always use async def for I/O-bound endpoint handlers
- SQLAlchemy 2.0: use select() not Query API; use async sessions
- Type annotations required on all function signatures
- Pydantic v2: use model_config = ConfigDict(...), @field_validator
- Use uv for dependency management, ruff for linting/formatting, mypy for type checking
`);
process.exit(0);
}
if (args.includes('--validate')) {
const filePath = args[args.indexOf('--validate') + 1];
if (!filePath) {
console.error('Error: --validate requires a file path argument');
process.exit(1);
}
if (!fs.existsSync(filePath)) {
console.error(`Error: File not found: ${filePath}`);
process.exit(1);
}
const source = fs.readFileSync(filePath, 'utf8');
const lines = source.split('\n');
const results = {
file: filePath,
checks: [],
};
// Check for type annotations on function definitions
const funcDefs = lines.filter(l => /^\s*(?:async\s+)?def\s+\w+/.test(l));
const annotatedFuncs = funcDefs.filter(l => /->\s*\S+/.test(l) || /\(.*:\s*\S/.test(l));
const annotationCoverage =
funcDefs.length > 0
? Math.round((annotatedFuncs.length / funcDefs.length) * 100) + '%'
: 'N/A (no functions)';
results.checks.push({
check: 'type_annotation_coverage',
value: annotationCoverage,
status: funcDefs.length === 0 || annotatedFuncs.length === funcDefs.length ? 'ok' : 'warn',
});
// Check for async patterns
const asyncDefs = lines.filter(l => /^\s*async\s+def\s+/.test(l));
const syncDefs = lines.filter(l => /^\s*def\s+/.test(l));
results.checks.push({
check: 'async_function_count',
value: asyncDefs.length,
status: 'info',
});
results.checks.push({
check: 'sync_function_count',
value: syncDefs.length,
status: 'info',
});
// Check for bare except
const bareExcept = lines.filter(l => /^\s*except\s*:/.test(l));
results.checks.push({
check: 'bare_except_clauses',
value: bareExcept.length,
status: bareExcept.length > 0 ? 'warn' : 'ok',
});
// Check for print() in production code (should use logging)
const printCalls = lines.filter(l => /(?<![#'"]).print\(/.test(l));
results.checks.push({
check: 'print_statements',
value: printCalls.length,
status: printCalls.length > 0 ? 'warn' : 'ok',
});
// Check for deprecated SQLAlchemy Query API
const queryApi = lines.filter(l => /session\.query\s*\(/.test(l));
results.checks.push({
check: 'deprecated_sqlalchemy_query_api',
value: queryApi.length,
status: queryApi.length > 0 ? 'warn' : 'ok',
note: queryApi.length > 0 ? 'Use select() instead of session.query() in SQLAlchemy 2.0+' : '',
});
console.log(JSON.stringify(results, null, 2));
process.exit(0);
}
if (args.includes('--analyze')) {
const filePath = args[args.indexOf('--analyze') + 1];
if (!filePath) {
console.error('Error: --analyze requires a file path argument');
process.exit(1);
}
if (!fs.existsSync(filePath)) {
console.error(`Error: File not found: ${filePath}`);
process.exit(1);
}
const source = fs.readFileSync(filePath, 'utf8');
const result = {
file: filePath,
frameworkDetected: null,
pythonVersionHint: null,
asyncMode: false,
keyDependencies: [],
};
// Framework detection
if (/from fastapi|import fastapi/i.test(source)) {
result.frameworkDetected = 'fastapi';
} else if (/from django|import django/i.test(source)) {
result.frameworkDetected = 'django';
} else if (/from flask|import flask/i.test(source)) {
result.frameworkDetected = 'flask';
} else if (/from litestar|import litestar/i.test(source)) {
result.frameworkDetected = 'litestar';
}
// Python version hint from match statement (3.10+) or PEP 695 syntax (3.12+)
if (/^\s*type\s+\w+\[/m.test(source)) {
result.pythonVersionHint = '>=3.12 (PEP 695 type alias syntax detected)';
} else if (/^\s*match\s+/m.test(source)) {
result.pythonVersionHint = '>=3.10 (match statement detected)';
}
// Async mode
result.asyncMode = /async\s+def\s+/.test(source);
// Key dependencies
const imports = [
...source.matchAll(
/^(?:import|from)\s+(sqlalchemy|pydantic|alembic|celery|redis|httpx|aiohttp|tortoise|uvicorn|gunicorn|starlette|motor|beanie|pymongo|psycopg|asyncpg|aiosqlite)/gm
),
];
result.keyDependencies = [...new Set(imports.map(m => m[1]))];
console.log(JSON.stringify(result, null, 2));
process.exit(0);
}
console.log(
'python-backend-expert skill loaded. Use --help for usage, --validate <file> or --analyze <file>.'
);
python-backend-expert Implementation Template
Goal
- Define target outcome and acceptance criteria.
TDD
1. Red 2. Green 3. Refactor
Verification
- lint
- format
- targeted tests