Files
py-export-api-docs/README.md
T
grayhook 0230587040 Add installed package version to exported API docs.
Write api-<version>.md with version metadata in each file and index, sanitize
output for safe paths/markdown, atomically replace exports, and add
--keep-old-versions to retain prior exports as an archive.
2026-05-30 18:14:33 +07:00

131 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# py-export-api-docs
Экспорт Markdown-документации API для пакетов из `requirements.txt`.
Скрипт создаёт временное виртуальное окружение (не трогает системный Python), устанавливает зависимости и генерирует документацию через [pydoc-markdown](https://github.com/NiklasRosenstein/pydoc-markdown) 4.x.
## Требования
- Python 3 с модулем `venv` (на Debian/Ubuntu: `python3-venv`)
- `pip` внутри создаваемого venv (устанавливается автоматически)
## Использование
Запускайте из каталога, куда нужно положить папку `docs/`:
```bash
./py-export-api-docs.py requirements.txt
./py-export-api-docs.py /path/to/requirements.txt --recreate-venv
./py-export-api-docs.py requirements.txt --strict
./py-export-api-docs.py requirements.txt --keep-old-versions
```
Или через интерпретатор:
```bash
python3 py-export-api-docs.py requirements.txt
```
### Опции
| Опция | Описание |
|-------|----------|
| `requirements` | Путь к файлу `requirements.txt` (обязательный аргумент) |
| `--venv-dir PATH` | Каталог виртуального окружения. По умолчанию: `/tmp/export-api-docs-<uid>-<hash>`, где `hash` — SHA256 от текущей рабочей директории |
| `--recreate-venv` | Удалить и пересоздать venv, переустановить пакеты |
| `--strict` | Завершить с кодом 1, если хотя бы один пакет или модуль не удалось экспортировать |
| `--keep-old-versions` | Не удалять предыдущие `api-<version>.md` и legacy `api.md` в каталогах модулей |
## Результат
В текущей рабочей директории создаётся:
```
docs/
├── README.md # индекс текущего экспорта
├── <import-module>/
│ ├── api-<version>.md # документация модуля
│ └── ... # другие api-<version>.md — только с --keep-old-versions
└── ...
```
### Версия в файлах
В каждом `api-<version>.md` в начале указаны имя пакета, **фактически установленная** версия (из метаданных venv, не из спецификатора в `requirements.txt`) и import-модуль:
```markdown
<!-- py-export-api-docs: package=requests version=2.32.3 module=requests -->
> **Source:** `requests` **2.32.3** (import: `requests`)
```
Имя файла — filesystem-safe slug той же версии: небезопасные символы заменяются на `_` (например, `1.0+local``api-1.0+local.md`, `1.0 rc1``api-1.0_rc1.md`). В редких случаях разные строки версии могут дать один slug — тогда файл перезаписывается.
### Очистка и архив
| Режим | Поведение |
|-------|-----------|
| По умолчанию | После успешного экспорта удаляются другие `api-<version>.md` и legacy `api.md` в каталоге модуля |
| `--keep-old-versions` | Старые файлы остаются на диске как архив |
`docs/README.md` перезаписывается при каждом запуске и содержит только модули **текущего** экспорта — архивные файлы в индекс не попадают.
Для каждого пакета определяются корневые import-модули (из `top_level.txt` в метаданных дистрибутива, из встроенных fallback-таблиц или по эвристике). Каждый модуль экспортируется один раз, даже если несколько пакетов его предоставляют.
## Поддерживаемые строки requirements.txt
**Обрабатываются:**
- PEP 508 спецификации имён пакетов (`requests>=2.28`, `flask[async]`, с маркерами окружения после `;`)
- Включения `-r other.txt` — только если файл лежит внутри дерева каталога, где находится корневой `requirements.txt`
**Устанавливаются pip'ом, но не экспортируются** (имя пакета не извлекается):
- `-e` (editable installs)
- Прямые URL и прочие pip-опции, начинающиеся с `-`
## Кэширование venv
Переустановка пакетов пропускается, если:
- venv уже существует;
- хеш дерева requirements-файлов (все `-r` включения) совпадает с сохранённым в `.requirements.sha256` внутри venv.
При изменении `requirements.txt` или включённых файлов зависимости переустанавливаются автоматически. Флаг `--recreate-venv` принудительно пересоздаёт окружение.
## Коды выхода
| Код | Причина |
|-----|---------|
| `0` | Документация экспортирована (в не-strict режиме допускаются предупреждения) |
| `1` | Файл requirements не найден; нет имён пакетов; ничего не экспортировано; или `--strict` и были ошибки |
## Предупреждения
Скрипт продолжает работу при частичных сбоях (без `--strict`):
- пакет не установился в venv;
- не удалось определить import-модуль;
- небезопасное имя модуля;
- ошибка `pydoc-markdown` при экспорте.
Для пакетов без `top_level.txt` используется guess по имени дистрибутива (`my-package``my_package`) или встроенные соответствия (`python-gitlab``gitlab`, `pyyaml``yaml`, `pillow``PIL` и др.).
## Пример вывода
```
Creating virtualenv: /tmp/export-api-docs-1000-a1b2c3d4e5f6
Installing packages into temporary virtualenv…
requests -> requests
wrote docs/requests/api-2.32.3.md (42 KiB)
Done. Documentation in /home/user/project/docs
```
Сгенерированный `docs/README.md`:
```markdown
| Module | Version | File |
|--------|---------|------|
| `requests` | `2.32.3` | [requests/api-2.32.3.md](requests/api-2.32.3.md) |
```