Files
main_backend/.agents/skills/python-practices/SKILL.md
T
Daniil cca1668fee
dev / deploy (push) Failing after 2m50s
compute / deploy (push) Has been cancelled
chore: agentic upgrade
2026-05-17 02:11:48 +03:00

4.9 KiB

name, description
name description
python-practices Use when writing, reviewing, refactoring, or debugging Python code in this repository, including style, typing, error handling, async work, tests, packaging, security, and verification.

Python Practices

Core Rule

Write Python that is boring to maintain: explicit, typed, small, tested, and easy to inspect in production. Prefer this repository's existing conventions over generic advice. When a library, framework, SDK, CLI, or cloud-service detail matters, fetch current docs with Context7; use Tavily for broader ecosystem practice research.

Source Priority

  1. Project files: AGENTS.md, pyproject.toml, existing cpv3/ code, tests.
  2. Current official docs and PEPs.
  3. High-quality community research for trade-offs, checked against project needs.
  4. Memory or intuition, only after the above.

Readability

  • Keep functions small enough to read in one pass. Extract helpers when branching, parsing, or side effects start competing for attention.
  • Use intention-revealing names: snake_case for functions and variables, CapWords for classes, UPPER_SNAKE_CASE for constants.
  • Prefer direct control flow, early returns, and clear condition names over nested cleverness.
  • Avoid ad hoc string parsing when Python, Pydantic, SQLAlchemy, JSON, pathlib, or another structured API can express the operation.
  • Comments should explain non-obvious reasons, not repeat the code.

Types And Data

  • Annotate public functions, service/repository boundaries, async helpers, and values that cross module boundaries.
  • Prefer precise built-in generics such as list[str], dict[str, Any], and tuple[int, int]; avoid bare dict, list, or Any unless the shape is genuinely unknown.
  • Use Pydantic schemas for API and validation boundaries. Use dataclasses or small typed objects for internal value bundles when Pydantic validation is not needed.
  • Do not mutate default containers. Use None plus initialization or a factory.
  • Convert external data at the boundary, then keep internal code working with typed values instead of raw payload dictionaries.

Errors And Logging

  • Catch specific exceptions. Avoid bare except, silent fallbacks, and swallowing errors without observability.
  • Preserve context with exception chaining: raise DomainError(...) from exc.
  • Define reusable user-facing or domain error strings as ERROR_... constants.
  • Use logging.getLogger(__name__) for diagnostics. Do not use print in application code.
  • Error messages should help the next maintainer find the failing input, dependency, or state without leaking secrets.

Async And Resources

  • Do not block the event loop. Use async APIs, subprocess APIs, or anyio.to_thread.run_sync for sync I/O and CPU-bound library calls.
  • Use context managers for files, sessions, locks, temporary resources, and network clients. Cleanup must be visible in normal and exceptional paths.
  • Add timeouts around network, subprocess, and external-service operations when the called API supports them.
  • Do not share mutable state across concurrent tasks unless access is synchronized.
  • For this backend, do not share one SQLAlchemy AsyncSession across concurrent tasks; use a session per task/request.

Tests

  • Test behavior, not implementation details. Name tests after the observable rule.
  • Prefer deterministic fixtures, explicit inputs, and parametrized edge cases.
  • Cover failure paths for parsing, permissions, missing data, external services, and persistence boundaries.
  • Use unit tests for pure helpers and service/repository rules. Use integration tests for endpoint contracts and dependency overrides.
  • For bug fixes, write or update the failing test first when practical, then make the smallest code change that proves the fix.

Security And Configuration

  • Keep secrets in environment-backed settings, never source files, tests, fixtures, generated docs, or logs.
  • Validate paths, object keys, URLs, filenames, and user-controlled identifiers at the boundary.
  • Prefer allowlists for modes, providers, file types, and status transitions.
  • Treat serialization as a boundary: expose only fields that should leave the module or API.

Project Tooling

Use the repository's Python 3.11+ and uv workflow. Keep Ruff formatting with the configured 100-character line length.

uv run ruff format cpv3 tests
uv run ruff check cpv3 tests
uv run pytest

Run narrower checks while iterating, then broaden when the change touches shared behavior. If verification cannot run, record the exact blocker.

Project Overlay

  • FastAPI HTTP concerns belong in router.py.
  • Pydantic DTOs belong in schemas.py and usually inherit cpv3.common.schemas.Schema.
  • Business orchestration belongs in service.py.
  • SQLAlchemy statements belong in repository.py.
  • Database shape changes need Alembic migrations and tests.
  • Do not rely on .claude/ directory contents.