Генерация API-документации из docstrings на Python

Написание высококачественной документации для большого или сложного API упрощается простым, интуитивно понятным пакетом Python  —  pdoc3, включая также поддержку Markdown и LaTeX!


Документация важна

Все любят хорошую и полную документацию, особенно во время знакомства с новой библиотекой (хотя, даже и при миллионном её применении). Представьте, как бы вы себя чувствовали, если бы с веб-сайтов Scikit-learn или TensorFlow убрали всю документацию. Сразу ощущается беспомощность…

Поэтому она важна. Качественная документация (особенно для проекта с открытым исходным кодом) демонстрирует хорошие стороны разработки приложения:

  • Забота о проекте.
  • Забота о конечных пользователях или клиентах, ведь ваш код читают гораздо больше раз, чем пишут.
  • Разработчики эффективно осваивают кодовую базу для отладки и справок, а пользователям легче находить ошибки и проблемы.
  • Разработчики будут доводить технические проекты до логического завершения, т.е. не оставлять свой хобби-проект на уровне блокнота Jupyter, а делать его многоразовым и пригодным для распространения среди широкой пользовательской базы (таким образом вы отличитесь от многих других open-source разработчиков).

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

А что, если бы существовал инструмент, генерирующий профессионально выглядящую документацию, т.е. готовую к публикации на сервере docs или веб-сайте для общественного потребления  —  прямо из необработанных функций Python?

В руководстве рассмотрим один такой замечательный инструмент для генерации документации из docstring на нескольких базовых примерах.


pdoc3  —  интуитивно понятный, мощный инструмент для написания Python-документации

Каждый Python-разработчик пишет множество функций и создает множество классов для проектов в области науки о данных или пакетов с открытым исходным кодом. На самом деле, даже при анализе хобби-проектов необходимо внедрять в кодовую базу привычку объектно-ориентированного стиля программирования.

Было бы очень здорово иметь возможность автоматически генерировать красивую документацию для API прямо из определений функций и классов, ни одной лишней строки HTML/CSS-кода!


Установка и первое применение пакета pdoc3

Просто установите pdoc3 через пакетный менеджер pip:

pip install pdoc3

Примечание: кроме актуальной версии, также существует старый пакет под названием pdoc3. Его тоже можно применять для создания документации, так как это развилка (fork) нужного проекта, но в руководстве рассматривается более современный фреймворк.

Начните с простой функции сложения: предположим, что она написана в локальном рабочем пространстве, в файле math-func.py.

def addition(num1, num2=0):
"""
Произведение двух чисел

Args:

num1: Первое число

num2: Второе число

Возвращает:

Произведение двух чисел
"""

return (num1+num2)

Таким образом, фактический код состоит только из одного оператора возврата, а вот строка документации уже весьма длинная.

В том и суть! Docstrings.

Документационные строки  —  основа pdoc3. На сайте говорится, что это “приложение командной строки, применяется для отображения документации проекта в виде статических HTML-файлов, включает веб-сервер с живой загрузкой для предварительного просмотра изменений”.

Итак, как же создать это веб-представление? Всего одна команда CLI:

pdoc — http localhost:8080 math-func.py

С её помощью запускается живой веб-сервер на порту localhost:8080:

Starting pdoc server on localhost:8080
pdoc server ready at http://localhost:8080

Когда вы перейдёте по ссылке localhost:8080  —  в браузере отобразится страница, как на скриншоте. 

Сначала вы увидите страницу с двумя ссылками, а когда вщелкните по ссылке math-func, то увидите документационную строку API:

Круто, правда? Но выглядит довольно просто. Давайте посмотрим, получится ли добавить сайту немного “колокольчиков и свистков”!


Markdown  

Ключ к благоустройству и удобству

У формата markdown много поклонников по всему миру, ведь он идеально подходит для написания документации: разве не в формате markdown вы пишите документы README для проектов на GitHub? Самое замечательное в pdoc3  —  это то, как он позволяет легко интегрировать текст формата markdown в документационную строку.

Предположим, в модуль math-func.py добавлена вторая функция mult:

def mult(num1, num2=1):
"""
Произведение двух чисел

Args:

`num1`: Первое число

`num2`: Второе число, по умолчанию `1`

Возвращает:

**Произведение** двух чисел
"""

return (num1*num2)

Обратите внимание на небольшие изменения в документационной строке: добавлены символы разметки, такие как знаки `…` и **…** для жирного шрифта.

Теперь, если вы просто сохраните файл, то веб-страница автоматически перезагрузится со всеми изменениями.

Обратите внимание, что аргументы num1 и num2 отображаются как блоки кода в строке, а слово multiplication выделено жирным шрифтом в документации вашего API: магия разметки.

Ничего не мешает показать блок кода внутри документа  —  просто напишите три знака ```…```. Полученный API (для divide, следующей функции):

Все, что нужно сделать  —  поместить в docstring следующее:

"""

...

Обработка исключения,
    
    ```python
    if num2 != 0:
        return (num1/num2)
    else:
        raise ValueError('The second argument cannot be zero')
    ```
    
 """

Обратите внимание на идентификатор python после тройных апострофов: сделано для красивого отображения блока кода в документации API в правильном формате.


Математика LaTeX

Пакет pdoc с легкостью отобразит в документации API основные математические выражения LaTeX из документационных строк. Например, пишем функцию вычисления пифагорейского расстояния со следующей документационной строкой:

def pythagorus(num1, num2=0):    """
    ### Description:
    
    Вычисляет корень-сумму-квадрат двух чисел
    
    ### Args:
    
    `num1`: Первое число
        
    `num2`: Второе число, по умолчанию `1`
    
    Возвращает:

    Результат **теоремы Пифагора**
    
    $$dist = \\sqrt { a^2+b^2 }$$
    """

Необходимо подчеркнуть следующее:

  • Символы $$ … $$ обертывают LaTeX-выражение.
  • Два символа обратной косой черты подряд символизируют обычную обратную косую черту внутри LaTeX-выражения: помогает справиться с обычной ролью обратного слеша как символа экранирования в Python docstrings.

Результат должен быть таким:


Индекс функций

Обратите внимание на список функций в левой части страницы. Он похож на оглавление и переносит в любое место документации, когда вы нажимаете на соответствующую функции ссылку; модуль за модулем. 

Главный модуль, конечно же  —  это файл math-func.py.

Как вы могли заметить, индекс отсортирован в алфавитном порядке (по именам функций). Хотя в исходном коде мы добавили функцию divide позже, чем функцию mult, но тем не менее, она индексируется на втором месте.


Разные утилиты и опции

В предыдущем разделе руководства рассматривались основные возможности применения пакета pdoc3. Здесь же хочется показать еще несколько глобальных опций и утилит для большего контроля и удобства.

Параметры вывода

Обычно вы можете сгенерировать одно из двух представлений:

  1. HTML-страницы: с помощью команды pdoc --html <filename.py>, она помещает HTML-файлы модуля в папку ./html внутри вашего рабочего каталога. Можете установить дополнительный флаг каталога, чтобы поместить внутрь него HTML-файлы.
  2. Сервер: с помощью pdoc — http HOST:PORT <filename.py> можно показать предварительный просмотр странниц API-документации на веб-странице, HOST и PORT задаются пользователем.

Экземпляры классов

Вы точно так же можете сгенерировать документацию при помощи стандартных объектов-экземпляров классов, вместо функций. Например, превратим весь код модуля math-func в класс, а также добавим в модуль второй класс Dataframe. Сгенерированная документация выглядит следующим образом:

Всё вместе

Если поместить классы и функции в один сценарий (модуль) Python, то это документация станет такой:

Программная генерация

По сути, pdoc3  —  это пакет Python, и поэтому он легко применяется прямо в Python-коде приложения для программной генерации документации. Ниже приведен пример кода:

import pdoc
modules = ['a', 'b']  # Публичные субмодули импортируются автоматически
context = pdoc.Context()
modules = [pdoc.Module(mod, context=context)
           for mod in modules]
pdoc.link_inheritance(context)

def recursive_htmls(mod):
    yield mod.name, mod.html()
    for submod in mod.submodules():
        yield from recursive_htmls(submod)

for mod in modules:
    for module_name, html in recursive_htmls(mod):
        ...  # Процесс

Обратите внимание, что mod.html()  —  по сути, функция, возвращающая необработанную HTML-строку с документационными строками модуля: она возвращает то, что отображается при выполнении команды pdoc — html <filename.py>

Готовый модуль

С pdoc3 вам по силам создать готовый, документированный модуль за один раз: нужно просто поместить необходимые файлы в обычную иерархию модулей/подмодулей, как в стандартном пакете Python.

Например, рассмотрим простую структуру каталогов пакета math-mod (обратите внимание на __init__.py, как того требует пространство имен Python), внутри которого по подкаталогам размещены модули.

Запустим однострочную команду:

pdoc --http localhost:8080 -c latex_math=True math-mod

И получим следующую структуру:

Выводы

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

В руководстве показано, как при помощи простого модуля pdoc3 создать красивую документацию для API (с поддержкой синтаксиса markdown и математического рендеринга LaTeX) еще на этапе работы с документационными строками функций.

Надеемся, статья поможет преодолеть барьер в написании хорошей документации следующему проекту с открытым исходным кодом, над которым вы работаете.

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Tirthajyoti Sarkar: How to Generate Professional API Docs in Minutes from Docstrings

Предыдущая статьяТеория игр
Следующая статьяСоздание архитектур кода с помощью функциональных операторов