Перейти к основному содержимому

Python Skill

Python Skill — набор инструкций для Claude Code и совместимых AI-агентов, которые пишут Python-код. В нём я собрал свой стек и правила: как называть функции, обрабатывать ошибки и писать тесты.

В новых проектах скил задаёт инструменты по умолчанию. В существующих — сохраняет принятый стек и структуру.

Репозиторий: github.com/akmalovaa/python-skill

Установка

Проще всего через skills CLI — работает с Claude Code, Codex, Cursor и другими агентами.

Глобально, для всех проектов:

npx skills add akmalovaa/python-skill -g

В текущий проект:

npx skills add akmalovaa/python-skill
Ручная установка для Claude Code

Для всех проектов:

git clone https://github.com/akmalovaa/python-skill ~/.claude/skills/python-skill

Или скачать только сам файл:

mkdir -p ~/.claude/skills/python-skill
curl -fsSL -o ~/.claude/skills/python-skill/SKILL.md \
https://raw.githubusercontent.com/akmalovaa/python-skill/main/SKILL.md

Для одного проекта — положить в <project>/.claude/skills/python-skill/. Агенты, следующие спецификации Agent Skills (Codex, Copilot CLI, Gemini CLI), читают также ~/.agents/skills/.

Принципы

Я оставляю в скиле короткий список правил, чтобы приоритеты были понятны:

  • Фиксировать выбор инструментов. Один инструмент на задачу, чтобы агент не выбирал стек заново в каждом проекте.
  • Описывать соглашения. Скил задаёт требования к коду: именование, обработку ошибок и тестирование.
  • Сохранять существующий проект. Замена инструментов и изменение структуры — только по явной просьбе. Правила работы с кодом применяются и к новым, и к существующим проектам.

Стек

ЗадачаИнструмент
Пакеты, виртуальные окружения, версии Pythonuv
Линт и форматированиеruff
Проверка типовpyright
Проверка данных из внешних источниковpydantic v2
Настройки из переменных окружения и .envpydantic-settings
HTTP-клиентhttpx2
Логированиеstructlog
Тестыpytest + pytest-asyncio, pytest-httpx2, time-machine

Для отдельных задач:

  • FastAPI + uvicorn — API.
  • SQLAlchemy 2.0 + alembic + psycopg 3 — работа с базой данных.
  • typer — интерфейс командной строки.
  • tenacity — повторные попытки при сбоях.

Базовый набор для нового проекта: uv, ruff, pyright и pytest. Остальные библиотеки и плагины подключаются по необходимости. Например, pydantic — для проверки внешних данных, structlog — для логирования.

httpx2

httpx2 — продолжение httpx под крылом Pydantic. Это реальный пакет, а не опечатка; агенты часто «исправляют» его обратно на httpx, поэтому в скиле это оговорено отдельно.

Выбор инструментов для новых проектов

Эти замены относятся к новым проектам. В существующих агент сохраняет принятые инструменты.

ВместоМой выбор
pip, poetry, pipenv, pyenvuv
requirements.txt, setup.pypyproject.toml + uv.lock
black, isort, flake8, pylintruff
mypypyright
requests, aiohttp, httpxhttpx2
python-dotenv, разбросанный os.environpydantic-settings
print вместо логовstructlog
freezeguntime-machine
unittestpytest

Структура и команды

Для нового проекта — структура с каталогом src: pyproject.toml, uv.lock, src/<package>/, tests/.

uv init --package # новый проект (--lib для библиотеки)
# tests/ не создаётся — создать вручную
uv add <pkg> # зависимость (--dev для dev)
uv add --dev ruff pyright pytest
uv sync # установка

Линтер, проверка типов и тесты добавляются как зависимости для разработки.

Локальная проверка

uv run ruff check --fix .
uv run ruff format .
uv run pyright
uv run pytest

Проверка в CI

В CI код проверяется без автоматических исправлений:

uv sync --locked
uv run --locked ruff check .
uv run --locked ruff format --check .
uv run --locked pyright
uv run --locked pytest
uv audit --locked # проверка зависимостей на известные уязвимости

ruff check --fix и ruff format чинят не всё: длинные строки (E501) придётся переносить руками.

Разовые скрипты запускаются через uv run --script. Зависимости можно указать прямо в файле по стандарту PEP 723.

Конфигурация

Базовый набор правил ruff. N следит за регистром имён, PTH заставляет использовать pathlib, ARG ловит неиспользуемые аргументы:

[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "SIM", "N", "PTH", "ARG", "RUF"]

[tool.ruff.lint.per-file-ignores]
"tests/**" = ["ARG"] # фикстуры выглядят как неиспользуемые аргументы

[tool.pyright]
typeCheckingMode = "strict"

По умолчанию для pyright выбран строгий режим — "strict". Если в конкретном проекте он выдаёт слишком много замечаний, можно перейти на "basic".

Именование

Линтер проверяет форму имени. За понятный смысл отвечает разработчик.

  • Функции и методы — действие: load_user_profile(), send_report().
  • Булевы значения — условие: is_active, has_permission, can_retry.
  • Классы — существительное с конкретной ответственностью: InvoiceGenerator.
  • Модули и пакеты — короткие названия предметной области в snake_case.
  • Один глагол на понятие — не смешивать get, fetch и retrieve для одного действия.
  • Конкретные имена — без data, info, utils, helper, manager, process, handle, tmp, если они не обозначают термин предметной области.
  • Без однобуквенных переменных, в том числе в циклах и выражениях-генераторах. Исключения: e для исключения и _ для неиспользуемого значения.
  • Именованные константы в UPPER_SNAKE_CASE вместо магических чисел.

Имена, заданные протоколом или API, сохраняются: специальные методы Python, хуки фреймворков и устоявшиеся main(), close(), commit(). Свойства с @property называются существительными.

Правила

Типы и данные

  • Указывать аннотации типов, включая возвращаемые значения.
  • Использовать list[str] и X | None, если версия Python в requires-python поддерживает этот синтаксис.
  • Проверять внешние данные через pydantic: HTTP-запросы, ответы сторонних API, переменные окружения. Внутри приложения работать с проверенными моделями.
  • Использовать pathlib.Path для файловых путей.
  • Не задавать изменяемые значения по умолчанию, например items=[].
  • Проверять отсутствие значения через is None, а не == None.
  • Для проверки типа использовать isinstance(x, T).
  • Импортировать нужные имена явно, без from module import *.

Если None означает отсутствие значения, проверять его явно. Условие if timeout: не отличает отсутствие таймаута от допустимого значения 0. Для проверки непустой коллекции if items: подходит.

Асинхронность

  • Использовать async, когда вызывающий код уже асинхронный или нужно выполнять несколько операций ввода-вывода одновременно.
  • Обычные скрипты оставлять синхронными.
  • Не вызывать time.sleep и синхронные клиенты внутри асинхронного кода. Если блокирующий вызов необходим, выполнять его через asyncio.to_thread().

Не скрывать ошибки (fail loud)

Один из главных принципов скила: ошибка должна быть видна и сохранять информацию о причине сбоя.

  • Перехватывать конкретные исключения. При замене исключения сохранять причину через raise X(...) from e.
  • Не использовать голый except:. Общий except Exception допустим только на входных точках: в main(), обработчике запроса или цикле воркера.
  • Не заменять исключение строкой вроде return {"error": str(e)}: так теряются тип и стек вызовов.
  • Не подставлять вымышленные данные при сбое запроса или разбора ответа. Сообщать об ошибке.
  • При обработке набора элементов собирать и показывать ошибки по каждому элементу. Не пропускать сбои через молчаливый continue.

На входной точке преобразовать сбой в типизированную ошибку приложения, а для API — в ответ с ошибкой. Стек вызовов записать в лог один раз и не передавать клиенту.

Тесты

  • Подменять внешние зависимости: HTTP-запросы и запуск процессов. Саму тестируемую функцию выполнять.
  • Для HTTP использовать pytest-httpx2 или httpx2.MockTransport.
  • Для асинхронных тестов — pytest-asyncio с asyncio_mode = "auto" в настройках pytest.
  • Выполнять проверки assert без условий. Предусловия проверять в начале теста.

Пример настройки HTTP-ответа через фикстуру httpx2_mock:

httpx2_mock.get(url).respond(json=...)

При исправлении ошибки:

  1. Написать регрессионный тест, который воспроизводит сбой.
  2. Убедиться, что он падает по ожидаемой причине.
  3. Исправить код и проверить, что тест проходит.

Если исправление уже написано, временно убрать его, проверить падение теста и вернуть исправление.

Другие скилы и каталоги

Ресурсы, которые я изучал при создании своего скила:

  • wondelai/skills — именование, структура функций и рефакторинг.
  • wdm0006/python-skills — отдельные скилы для настройки Python-инструментов, разработки CLI, упаковки и тестирования.
  • manikosto/claude-code-python-stack — подходы к разработке бэкенда с FastAPI, SQLAlchemy, Pydantic и Celery.
  • Jeffallan/claude-skills — экспертные роли для задач Python, FastAPI, SRE и Kubernetes.
  • obra/superpowers — организация работы: обсуждение идей, TDD и системная отладка.
  • affaan-m/ECC — комплексная настройка среды агента. Для точечных задач я бы выбирал отдельные скилы.

Каталоги для поиска: