Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Документация Python-проекта: Sphinx и MkDocs

Sphinx или MkDocs: документация Python-проекта, которую читают

Как построить документацию проекта: MkDocs Material для руководств, Sphinx + autodoc для API-справок, docstring-стили, автогенерация и CI-публикация — практическая схема.

Прямой ответ

Выбор инструмента следует из содержания: MkDocs (с темой Material) — для руководств и продуктовых доков, написанных людьми в Markdown: настройка за минуты, поиск из коробки, красивый дефолт; Sphinx — когда ядро документации — API-справка из кода: autodoc вытягивает docstring'и, cross-references связывают сущности, доменные расширения (API, опции, глоссарий) мощнее. Для библиотеки с публичным API разумный дефолт — Sphinx (или MkDocs + mkdocstrings, который закрывает разрыв); для внутреннего продукта/гайда — MkDocs. Но важнее инструмента две вещи: docstring-дисциплина в коде (документация живёт рядом с кодом, а не в вики) и публикация из CI на каждый мерж (документация, которую собирают руками, устаревает в тот же день).

Структура документации: четыре типа текста

Схема Diátaxis (де-факто стандарт организации доков) делит текст по назначению: tutorial (обучение через первый результат — «установил и получил работающее за 10 минут»), how-to guides (рецепты под задачи — «как подключить S3»), reference (справка API — точность, полнота, автогенерация), explanation (контекст и решения — «почему мы выбрали очереди»). Практическая польза: читатель с задачей не тонет в «обо всём», а автор знает, куда класть текст; большинство «мёртвых» документаций умерли от смешения всех четырёх в одну простыню README. README при этом остаётся витриной: что за проект, быстрый старт, ссылка на доки.

Docstring'и: источник API-документации

Стиль выбирается один на проект: Google-style (читается легко, поддерживается Sphinx через napoleon и mkdocstrings — популярный дефолт), reST/Sphinx-style (:param x: — исторический стандарт Sphinx), NumPy-style (научная экосистема). Правила, которые важнее стиля: публичный API документируется обязательно (приватное — по вкусу); первая строка — глагольное резюме; аргументы/возврат/исключения — перечислены; примеры — для неочевидного (>>> doctest-блоки ещё и тестируются). Типизация уменьшает объём docstring-рутины (аннотации видны в справке — связь с типизацией), но «что и почему» аннотация не заменяет. Линтинг документации (pydocstyle/ruff-правила D) держит планку автоматически — в pre-commit (настройка).

Sphinx: сила и цена мощности

Минимальный рабочий Sphinx: sphinx-quickstart → conf.py (тема — furo или sphinx_rtd_theme; расширения — autodoc, napoleon, intersphinx) → apidoc/autosummary генерирует страницы справки из модулей → сборка make html. Сильные стороны: cross-reference (:func:/:class: — ссылки на сущности с проверкой на сборке), intersphinx (ссылки на документацию Python/pandas как на локальные — документация «встроена» в экосистему), домены и расширения под любой формат (HTTP-API — sphinxcontrib-httpdomain, хотя для REST чаще генерируют из OpenAPI — контрактный подход). Цена: reStructuredText (порог входа для контрибьюторов выше Markdown), conf.py-магия при кастомизации, сборка медленнее.

MkDocs: простота и mkdocstrings

MkDocs: mkdocs.yml (тема material, навигация, плагины) + Markdown в docs/ — работающая документация с поиском за вечер. Material-тема даёт вкладки, копируемые блоки кода, тёмную тему, аннотации — «дорогой» вид без верстки. Разрыв с Sphinx закрывает mkdocstrings (API-страницы из docstring'ов, Google/NumPy-стили) — для большинства библиотек связка MkDocs+Material+mkdocstrings теперь достаточна; Sphinx остаётся выбором для сложных справочников с плотными cross-references и многолетней инерцией (документация Python, pandas — на нём). Полезные плагины: mkdocs-autorefs (перекрёстные ссылки), mike (версии документации по релизам — «доки для 1.x и 2.x рядом»), literate-nav.

Публикация и поддержка живости

Пайплайн здорового проекта: документация собирается в CI на каждый PR (битые ссылки/сборка падают до мержа — линк-чекинг mkdocs build --strict/sphinx -W превращает предупреждения в ошибки) и публикуется на Pages/хостинг на мерж в main (GitHub Actions-воркфлоу — гайд по CI); версии документации тегируются вместе с релизами (mike/ReadTheDocs-модель). Поддержка: «документация или код» в определении готовности фичи (DoD), примеры в доках покрываются тестами (doctest/собранные сниппеты — «пример из документации не работает» убивает доверие быстрее всего), а API-изменения ломают сборку справок автоматически — autodoc не даст забыть. Для открытой библиотеки публикация на PyPI и документация — одна история релиза (упаковка).

Практический сценарий: документация библиотеки за выходные

Реалистичный план для open-source библиотеки. Субботнее утро — каркас: mkdocs init, тема Material, в mkdocs.yml — навигация из четырёх разделов по Diátaxis (Get Started, How-to, Reference, About); pip install mkdocstrings[python] — плагин API-страниц. Субботный день — содержание: Get Started пишется как честные десять минут пользователя (установка, минимальный рабочий пример, что получилось — с реальным выводом); три-четыре how-to под главные задачи («как обработать ошибки», «как настроить…») — каждый как рецепт с полным листингом; explanation — одна страница «зачем эта библиотека и чем отличается» (её отсутствие — причина половины вопросов в issues). Reference — автогенерация: ::: synctool.client с опциями mkdocstrings; качество страницы равно качеству docstring'ов — субботний вечер уходит на Google-style docstring'и публичного API (первая строка, аргументы, пример на неочевидное). Воскресенье — конвейер: mkdocs build --strict в CI (битые ссылки и недокументированное падают на PR), публикация на Pages по мержу в main, mike — если у библиотеки несколько поддерживаемых версий. Понедельник — проверка реальностью: коллега ставит библиотеку и идёт по Get Started молча, без вопросов в личку; каждое место, где он споткнулся, — правка текста. Дальше документация живёт по правилу «PR без обновления доков для публичного API не мержится» — и остаётся живой без отдельных «дней документации».

FAQ

Можно ли вообще без генератора — просто Markdown в репозитории? Для маленького внутреннего инструмента — да (GitHub рендерит Markdown, навигация — оглавлением). Генератор окупается, когда страниц больше десятка, нужны поиск/версии/API-справка — то есть почти для любой библиотеки.

Где держать документацию: в репозитории кода или отдельно? В репозитории кода (docs/ рядом): меняется код — в том же PR меняется док; отдельный репозиторий документации — рассинхрон по построению, оправдан только для мультирепозиторийных продуктовых доков.

Read the Docs или GitHub Pages? RTD — бесплатно для open source, версии/переводы из коробки, интеграция с PR; Pages — проще для статической сборки своим CI. Оба рабочие; выбор — по потребности в версиях и приватности (Pages приватных репо — платный тариф).

Нужна ли документация внутреннему сервису? Минимально — да: README с запуском, схема данных/эндпоинтов (из OpenAPI — автоматически), runbook основных операций. «Команда и так знает» имеет срок годности ровно до первого отпуска или нового сотрудника.

Источники: документация Sphinx, MkDocs и Material for MkDocs — ссылки в шапке.

FAQ

Как держать примеры кода в документации рабочими? Тестировать их: doctest-блоки в docstring'ах прогоняются pytest'ом, сниппеты how-to выносятся в исполняемые файлы, из которых документация вставляет фрагменты плагином. Мёртвый пример встречается пользователем в первый же час — дешевле автоматизировать проверку.

Что делать с документацией на нескольких языках? Начинать с одного и не переводить вручную дважды: при реальной потребности — плагин i18n, где переводятся только explanation и how-to, а автогенерируемый Reference остаётся из кода один на все языки.