python-expert
Python Expert
Expert Python guidance across scripting, web frameworks, and production systems.
Important — Read Reference Files First
Before writing code, load the reference file that matches the user's task:
| User wants to... | Read first |
|---|---|
| Run a quick script, one-off tool, CLI utility, or use inline dependencies | references/uv-scripts.md |
| Build or modify a Django project (models, views, admin, DRF APIs) | references/django.md |
| Build or modify a Flask or FastAPI project (routes, middleware, APIs) | references/flask-fastapi.md |
If none of those match, use the core principles below directly.
Core Principles (Always Apply)
Modern Python Style (3.10+)
Write Python that uses current idioms. Avoid legacy patterns.
# Type hints on all public functions
def fetch_users(limit: int = 50, active: bool = True) -> list[dict[str, Any]]:
...
# Dataclasses over manual __init__
from dataclasses import dataclass, field
@dataclass
class Config:
host: str = "localhost"
port: int = 8000
tags: list[str] = field(default_factory=list)
# match-case for dispatch
match command:
case "start":
start_server()
case "stop" | "quit":
shutdown()
case _:
print(f"Unknown: {command}")
# f-strings, never .format() or %
msg = f"Processing {count:,} items in {elapsed:.2f}s"
# pathlib, never os.path
from pathlib import Path
config_path = Path.home() / ".config" / "app" / "settings.toml"
Project Structure Defaults
When creating a new Python project (not a uv one-off script), use this layout:
project-name/
├── pyproject.toml # Single source of truth for metadata + deps
├── src/
│ └── project_name/ # Importable package
│ ├── __init__.py
│ └── main.py
├── tests/
│ ├── conftest.py
│ └── test_main.py
└── README.md
Use pyproject.toml as the single config file. Do not create setup.py, setup.cfg, or requirements.txt unless the user specifically asks for them.
Error Handling
Be specific with exceptions. Never use bare except:.
# Good — specific exceptions, useful messages
try:
data = json.loads(raw)
except json.JSONDecodeError as e:
logger.error("Invalid JSON at line %d: %s", e.lineno, e.msg)
raise ValueError(f"Could not parse config: {e}") from e
# Good — custom exceptions for domain logic
class InsufficientFundsError(Exception):
def __init__(self, balance: Decimal, amount: Decimal):
self.balance = balance
self.amount = amount
super().__init__(f"Cannot withdraw {amount}: balance is {balance}")
Testing with pytest
Default to pytest for all testing. Structure tests to mirror source layout.
# Use fixtures for shared setup
import pytest
@pytest.fixture
def db_session():
session = create_test_session()
yield session
session.rollback()
# Parametrize for multiple cases
@pytest.mark.parametrize("input,expected", [
("hello", "HELLO"),
("", ""),
("café", "CAFÉ"),
])
def test_uppercase(input, expected):
assert to_upper(input) == expected
# Use tmp_path for file operations
def test_export(tmp_path):
out = tmp_path / "report.csv"
export_report(out)
assert out.read_text().startswith("id,name")
Async Programming
Use async for I/O-bound work. Never use it for CPU-bound work (use multiprocessing instead).
import asyncio
import httpx
async def fetch_all(urls: list[str]) -> list[dict]:
async with httpx.AsyncClient() as client:
tasks = [client.get(url) for url in urls]
responses = await asyncio.gather(*tasks, return_exceptions=True)
return [
r.json() for r in responses
if not isinstance(r, Exception)
]
Prefer httpx over aiohttp — it has sync and async APIs with the same interface.
Dependencies and Packaging
For full projects, use pyproject.toml:
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
"httpx>=0.27",
"pydantic>=2.0",
]
[project.optional-dependencies]
dev = ["pytest>=8.0", "ruff"]
[tool.ruff]
line-length = 100
[tool.uv]
exclude-newer = "30 days"
For quick scripts, use uv inline metadata — see references/uv-scripts.md.
Supply Chain Security (uv Projects)
Always include exclude-newer = "30 days" in every uv project. This is a rolling window that tells uv to ignore any package version published within the last 30 days, protecting against supply chain attacks like the March 2026 litellm compromise (malicious versions were caught and yanked within hours).
Two places to set this — both should be in place:
pyproject.toml (per-project, committed to git):
[tool.uv]
exclude-newer = "30 days"
~/.config/uv/uv.toml (machine-wide fallback, top-level key — no [tool.uv] section):
exclude-newer = "30 days"
Important caveats:
- This only applies to registry packages (PyPI). Git and local path dependencies are not affected.
- The timestamp is written into
uv.lockat resolution time. The window doesn't move until you runuv lock --upgradeoruv sync --upgrade. - If a project genuinely needs a package released within the last 30 days, use
exclude-newer-packageto opt that specific package out:exclude-newer-package = { some-package = false }.
Logging (not print)
Use structured logging for anything beyond throwaway scripts:
import logging
logger = logging.getLogger(__name__)
# Configure once at entry point
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
Common Pitfalls to Catch
When reviewing or writing Python code, watch for:
- Mutable default arguments (
def f(items=[])— useNone+ conditional) - Late binding closures in loops (use
functools.partialor default args) - Missing
if __name__ == "__main__":guard in scripts - Using
datetime.now()without timezone (usedatetime.now(timezone.utc)) - Bare
except:orexcept Exception:swallowing errors silently os.pathwhenpathlibwould be clearerrequestsin async contexts (usehttpxinstead)
Troubleshooting Approach
When the user has an error or unexpected behavior:
- Read the full traceback — Python errors are specific and descriptive
- Identify the exception type and the failing line
- Check types with
type()/isinstance()if the error suggests a type mismatch - Reproduce minimally — strip away unrelated code
- Verify Python version compatibility (
python --version) - Check the virtual environment is activated and deps are installed
- Use
python -m pytest -x --tb=shortfor quick test feedback - Use
ruff check .for lint issues instead of pylint/flake8 (faster, more modern)
More from oiler/claude-skills
wordpress-themes
WordPress custom theme development specialist focused on clean, maintainable code following VIP standards. Includes modular theme structure, dart-sass via Homebrew, proper script/style enqueueing, template parts organization, text domain management, and comprehensive security practices (escaping, sanitization, file paths).
16plotly-dash-expert
Expert guidance for building Plotly Dash web applications. Use when user asks to create dashboards, interactive tables, data browsers, Dash apps, or mentions "Dash", "plotly", "DataTable", "dash callbacks", "dcc", or "dash_table". Covers app structure, callbacks, layouts, DataTable with server-side paging/sorting/filtering, database integration (SQLite/Postgres), multi-page apps, and self-hosted deployment with gunicorn/nginx. Focused on open-source Dash (not Dash Enterprise).
15css-specialist
Expert CSS guidance for developers with strong fundamentals who need help with modern CSS features (2020-2025) and advanced animations/visual effects. Applies clean, semantic CSS patterns with minimal utility classes and shallow inheritance.
6web-security
Application-level security for web development. Use when writing, reviewing, or auditing code for security in WordPress, Laravel, Django, FastAPI, or Plotly Dash. Covers OWASP Top 10 2021, XSS prevention, SQL injection, CSRF, security headers (CSP, HSTS, CORS), session and cookie security, JWT handling, authentication, file uploads, API security, PII protection, and secure configuration. Trigger on "security review", "secure this", "harden", "vulnerability", "XSS", "injection", "CSRF", "CORS", "CSP", "security headers", "session security", "JWT", or "OWASP".
4wordpress-blocks
WordPress custom Gutenberg block development with server-side PHP rendering. Includes block registration patterns, media upload integration, multiple item blocks, proper escaping/sanitization, and editor UI best practices. Maintains separation of concerns where editors control content while developers control design.
4