feat(docs): add api-docs template for pypi (lazydocs)#18
Conversation
Mirrors the TypeScript and dotnet pipelines for Python. Iterates over packages declared in the PUBLIC_PACKAGES env (resq-mcp, resq-dsa today), installs each editable into a uv-backed venv plus lazydocs, then runs lazydocs against each package's import-name to produce a per-package Markdown tree. Reuses the shared Mintlify-safety post-processing (./ prefix on bare-filename links, MDX curly-brace escape outside code regions) and opens a PR via peter-evans/create-pull-request authored as resq-sw. Picked lazydocs over mkdocstrings because mkdocstrings expects a mkdocs site config; lazydocs is a single CLI invocation that takes a module name and emits Markdown directly. Keeps the template shape consistent with the other two languages.
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a new GitHub Actions workflow for generating Python API documentation using lazydocs and updates the project README accordingly. The workflow handles package installation, documentation generation, and post-processing for MDX compatibility before opening a PR in the docs repository. Feedback focuses on correcting the source code links by accounting for the packages/ subdirectory and improving the robustness of the curly brace escaping logic to correctly handle multi-backtick inline code spans.
* lazydocs --src-base-url: prefix the URL with packages/${pkg_dir}/.
When the package is installed editable, lazydocs records source
paths relative to the package's pyproject root, so generated
GitHub source links land on the wrong directory unless the URL
base names that subpath. Without this, every "View source"
anchor 404s.
* Curly-brace escape awk: rewrite the inline-code detector to
count backtick run length and scan for a matching-length closer
rather than toggling on every backtick. Single-backtick spans
and multi-backtick spans (e.g. ``code with ` inside``) now
preserve braces correctly.
Two fixes from the source-of-truth template's review:
1. lazydocs --src-base-url now points at packages/${pkg_dir}/
instead of the repo root. Without this, generated 'View
source' links 404 because lazydocs records source paths
relative to the package's pyproject root, not the repo root.
2. Curly-brace escape awk: count backtick run length and scan
for a matching-length close instead of toggling on every
single backtick. CommonMark inline code spans of any width
(e.g. ``code with \` inside``) now preserve braces
correctly.
Two fixes from the source-of-truth template's review:
1. lazydocs --src-base-url now points at packages/${pkg_dir}/
instead of the repo root. Without this, generated 'View
source' links 404 because lazydocs records source paths
relative to the package's pyproject root, not the repo root.
2. Curly-brace escape awk: count backtick run length and scan
for a matching-length close instead of toggling on every
single backtick. CommonMark inline code spans of any width
(e.g. ``code with \` inside``) now preserve braces
correctly.
Two issues uncovered while resolving review on docs/PR#19:
1. lazydocs is broken on Python 3.12+. It uses pkgutil's
deprecated find_module() API which was removed in Python 3.12;
on the runner's Python 3.13, every submodule walk fails with:
AttributeError: 'FileFinder' object has no attribute 'find_module'
The first run produced only README.md and an empty _pages.json
because every per-module emit failed silently and the script
only fell over once both packages had zero output. Switch to
pydoc-markdown, which is on the find_spec() API and works on
3.13.
2. README intro previously read as a fragment in third person.
Per docs#19 review (active voice + code formatting), rewrite
the generator to emit "You can use this auto-generated..."
and wrap the repo / package paths in backticks.
The docs PR will refresh in place once pypi#31 (pending) merges
and the regenerator runs.
Two issues raised on docs/PR#20: 1. `pydoc-markdown -p <pkg>` only documents the top-level module. The package's submodules (resq_mcp.core, resq_mcp.drone, etc.) were not walked, so both overview.md files contained nothing beyond `# Table of Contents`. Discover submodules via pkgutil in a small inline Python script, then pass every name to pydoc-markdown via a YAML config's `loaders[].modules` list (the Python-import form, which works with editable installs). Bump the renderer to enable `render_module_header`, `descriptive_class_title`, and `add_method_class_prefix` so the layout is closer to what lazydocs produced before its 3.13 incompatibility. Also tighten the empty-output sanity check from `! -s` to a line-count threshold; a 3-line file containing only a TOC header is still technically non-empty. 2. README package list now sorts the package directories alphabetically before emitting the bullets. Keeps the README in sync with `_pages.json` (which `find ... | sort` already produces) regardless of PUBLIC_PACKAGES env order.
Two issues from resq-software/docs#20 review: 1. `pydoc-markdown -p <pkg>` does not recurse into submodules. Both overview.md files in the auto-PR contained only `# Table of Contents`. Discover submodules via pkgutil and pass every name explicitly via inline YAML loader config. Bumps renderer flags so the rendered layout matches what lazydocs produced before its 3.13 incompat. 2. README package list now sorts package directories alphabetically, matching _pages.json order. Sync from resq-software/docs#18 (commit a5b2afb).
Two issues from resq-software/docs#20 review: 1. `pydoc-markdown -p <pkg>` does not recurse into submodules. Both overview.md files in the auto-PR contained only `# Table of Contents`. Discover submodules via pkgutil and pass every name explicitly via inline YAML loader config. Bumps renderer flags so the rendered layout matches what lazydocs produced before its 3.13 incompat. 2. README package list now sorts package directories alphabetically, matching _pages.json order. Sync from resq-software/docs#18 (commit a5b2afb).
Single-line nav addition — points at sdks/python/api/README which Mintlify resolves via the existing .md file. No file renames; the auto-generated trees stay as .md because Mintlify's .md link resolver is filesystem-based and already accepts the cross-references TypeDoc / DefaultDocumentation / pydoc-markdown emit. Renaming the READMEs to .mdx (attempted in earlier commits 4e31133 / 7301dbc / 54934ef) was the wrong move — .mdx parents have stricter link resolution that requires every link target to be nav-registered, which is not feasible for 3500+ auto-generated pages. The "is referenced in docs.json navigation but the file does not exist" warning that mint dev emits for .md-extension README references is cosmetic; Mintlify still renders the page. The "Generated API Reference" group from PR #17 only had TypeScript and .NET sub-groups; PR #18 (Python template) and the resulting auto-PRs (#19, #20) landed the Python content after that PR was opened.
Single-line nav addition — points at sdks/python/api/README which Mintlify resolves via the existing .md file. No file renames; the auto-generated trees stay as .md because Mintlify's .md link resolver is filesystem-based and already accepts the cross-references TypeDoc / DefaultDocumentation / pydoc-markdown emit. Renaming the READMEs to .mdx (attempted in earlier commits 4e31133 / 7301dbc / 54934ef) was the wrong move — .mdx parents have stricter link resolution that requires every link target to be nav-registered, which is not feasible for 3500+ auto-generated pages. The "is referenced in docs.json navigation but the file does not exist" warning that mint dev emits for .md-extension README references is cosmetic; Mintlify still renders the page. The "Generated API Reference" group from PR #17 only had TypeScript and .NET sub-groups; PR #18 (Python template) and the resulting auto-PRs (#19, #20) landed the Python content after that PR was opened. Co-authored-by: Mike Odnis <engineer@resq.software>
Summary
Adds the third per-language workflow template, mirroring the existing TypeScript and dotnet pipelines for Python.
automation/source-repo-templates/api-docs.python.ymlpypirow updated frommkdocstrings / _TODO_placeholder tolazydocs / api-docs.python.ymlPipeline
actions/setup-pythonat 3.13.astral-sh/setup-uv(matches the existinguv.lockinpackages/resq-dsa).uv pip install -eeach package declared inPUBLIC_PACKAGES(today:resq-mcp,resq-dsa), thenuv pip install lazydocs.lazydocs --output-path <out> --src-base-url <github>/blob/<ref>/ --no-watermark --validate <module-name>../prefix on bare-filename links, MDX curly-brace escape outside code regions).peter-evans/create-pull-requestopens a PR back toresq-software/docs, branchauto/python-api-<ref>, authored asresq-sw.Why lazydocs over mkdocstrings
mkdocstrings expects a mkdocs site config and renders into a full mkdocs site. We don't need that — we just want Markdown for Mintlify to render. lazydocs is a single CLI invocation that takes a module name and emits Markdown directly. Keeps the template shape consistent with the TypeDoc / DefaultDocumentation invocations.
Action pins
actions/checkout@v6.0.2actions/setup-python@v5.6.0astral-sh/setup-uv@v6.0.0peter-evans/create-pull-request@v7.0.8All pinned to commit SHA per the convention used elsewhere.
Test plan
resq-software/pypicopying this file to.github/workflows/api-docs.yml.workflow_dispatchand confirm the resulting docs PR contains bothresq-mcp/andresq-dsa/Markdown trees with a top-levelREADME.mdlinking to both.Out of scope
sdks/python/api/(deferred along with TS / dotnet — single-entry-page pattern would just need one more group entry indocs.json).programs(rustdoc),vcpkg(Doxygen),viz(DefaultDocumentation again).