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/.
Принципы
Я оставляю в скиле короткий список правил, чтобы приоритеты были понятны:
- Фиксировать выбор инструментов. Один инструмент на задачу, чтобы агент не выбирал стек заново в каждом проекте.
- Описывать соглашения. Скил задаёт требования к коду: именование, обработку ошибок и тестирование.
- Сохранять существующий проект. Замена инструментов и изменение структуры — только по явной просьбе. Правила работы с кодом применяются и к новым, и к существующим проектам.
Стек
| Задача | Инструмент |
|---|---|
| Пакеты, виртуальные окружения, версии Python | uv |
| Линт и форматирование | ruff |
| Проверка типов | pyright |
| Проверка данных из внешних источников | pydantic v2 |
Настройки из переменных окружения и .env | pydantic-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 — продолжение httpx под крылом Pydantic. Это реальный пакет, а не опечатка; агенты часто «исправляют» его обратно на httpx, поэтому в скиле это оговорено отдельно.
Выбор инструментов для новых проектов
Эти замены относятся к новым проектам. В существующих агент сохраняет принятые инструменты.
| Вместо | Мой выбор |
|---|---|
| pip, poetry, pipenv, pyenv | uv |
| requirements.txt, setup.py | pyproject.toml + uv.lock |
| black, isort, flake8, pylint | ruff |
| mypy | pyright |
| requests, aiohttp, httpx | httpx2 |
| python-dotenv, разбросанный os.environ | pydantic-settings |
| print вместо логов | structlog |
| freezegun | time-machine |
| unittest | pytest |
Структура и команды
Для нового проекта — структура с каталогом 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=...)
При исправлении ошибки:
- Написать регрессионный тест, который воспроизводит сбой.
- Убедиться, что он падает по ожидаемой причине.
- Исправить код и проверить, что тест проходит.
Если исправление уже написано, временно убрать его, проверить падение теста и вернуть исправление.
Другие скилы и каталоги
Ресурсы, которые я изучал при создании своего скила:
- 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 — комплексная настройка среды агента. Для точечных задач я бы выбирал отдельные скилы.
Каталоги для поиска:
- ComposioHQ/awesome-claude-skills — подборка скилов.
- hesreallyhim/awesome-claude-code — скилы, хуки, плагины и другие расширения.
- skills.sh — поиск скилов с командами установки.