Skip to content

Commit

Permalink
Automate api_index.rst generation
Browse files Browse the repository at this point in the history
  • Loading branch information
lochhh committed Jul 3, 2024
1 parent 43f17d7 commit 1dcdb00
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 53 deletions.
45 changes: 42 additions & 3 deletions .github/workflows/docs_build_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,48 @@ jobs:
name: Build Sphinx Docs
runs-on: ubuntu-latest
steps:
- uses: neuroinformatics-unit/actions/build_sphinx_docs@main
with:
python-version: 3.11
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.11

- name: Upgrade pip
shell: bash
run: |
# install pip=>20.1 to use "pip cache dir"
python3 -m pip install --upgrade pip
- name: Get pip cache dir
shell: bash
id: pip-cache
run: echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT

- name: Cache dependencies
uses: actions/cache@v4
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
shell: bash
run: python3 -m pip install -r ./docs/requirements.txt

- name: Check links and build documentation
shell: bash
run: |
cd docs
make linkcheck
make html
- name: Upload the content for deployment
uses: actions/upload-artifact@v4
with:
name: docs-build
path: ./docs/build/

deploy_sphinx_docs:
name: Deploy Sphinx Docs
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ instance/
docs/build/
docs/source/examples/
docs/source/api/
docs/source/api_index.rst
sg_execution_times.rst

# MkDocs documentation
Expand Down
32 changes: 7 additions & 25 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,32 +209,14 @@ If it is not yet defined and you have multiple external links pointing to the sa


### Updating the API reference
If your PR introduces new public modules, or renames existing ones,
make sure to add them to the `docs/source/api_index.rst` page, so that they are included in the [API reference](target-api), e.g.:

```rst
API Reference
=============
Information on specific functions, classes, and methods.
.. rubric:: Modules
.. autosummary::
:toctree: api
:recursive:
:nosignatures:
movement.move_accessor
movement.io.load_poses
movement.io.save_poses
movement.your_new_module
```

The API reference is auto-generated by the `sphinx-autodoc` and `sphinx-autosummary` plugins, based on docstrings.
The API reference is auto-generated by the `docs/make_api_index.py` script, and the `sphinx-autodoc` and `sphinx-autosummary` plugins.
The script generates the `docs/source/api_index.rst` file containing the list of modules to be included in the [API reference](target-api).
The plugins then generate the API reference pages for each module listed in `api_index.rst`, based on the docstrings in the source code.
So make sure that all your public functions/classes/methods have valid docstrings following the [numpydoc](https://numpydoc.readthedocs.io/en/latest/format.html) style.
Our `pre-commit` hooks include some checks (`ruff` rules) that ensure the docstrings are formatted consistently.

If your PR introduces new modules that should not be documented in the [API reference](target-api), or if there are changes to existing modules that necessitate their removal from the documentation, make sure to update the `exclude_modules` list within the `docs/make_api_index.py` script to reflect these exclusions.

### Updating the examples
We use [sphinx-gallery](sphinx-gallery:)
to create the [examples](target-examples).
Expand All @@ -259,14 +241,14 @@ pip install -r docs/requirements.txt

Then, from the root of the repository, run:
```sh
sphinx-build docs/source docs/build
python docs/make_api_index.py && sphinx-build docs/source docs/build
```

You can view the local build by opening `docs/build/index.html` in a browser.
To refresh the documentation, after making changes, remove the `docs/build` folder and re-run the above command:

```sh
rm -rf docs/build && sphinx-build docs/source docs/build
rm -rf docs/build && python docs/make_api_index.py && sphinx-build docs/source docs/build
```

To check that external links are correctly resolved, run:
Expand Down
13 changes: 12 additions & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@ help:

.PHONY: help Makefile

# Generate the API index file
api_index.rst:
python make_api_index.py

# Remove all generated files
clean:
rm -rf ./build
rm -f ./source/api_index.rst
rm -rf ./source/api
rm -rf ./source/examples

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
%: Makefile api_index.rst
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
3 changes: 3 additions & 0 deletions docs/make.bat
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ if errorlevel 9009 (

if "%1" == "" goto help

echo "Generating API index..."
python make_api_index.py

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

Expand Down
44 changes: 44 additions & 0 deletions docs/make_api_index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Generate the API index page for all ``movement`` modules."""

import os

# Modules to exclude from the API index
exclude_modules = ["cli_entrypoint"]

# Set the current working directory to the directory of this script
script_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(script_dir)


def make_api_index():
"""Create a doctree of all ``movement`` modules."""
doctree = "\n"

for root, _, files in os.walk("../movement"):
# Remove leading "../"
root = root[3:]
for file in sorted(files):
if file.endswith(".py") and not file.startswith("_"):
# Convert file path to module name
module_name = os.path.join(root, file)
module_name = module_name[:-3].replace(os.sep, ".")
# Check if the module should be excluded
if not any(
file.startswith(exclude_module)
for exclude_module in exclude_modules
):
doctree += f" {module_name}\n"

# Get the header
with open("./source/_templates/api_index_head.rst") as f:
api_head = f.read()
# Write api_index.rst with header + doctree
with open("./source/api_index.rst", "w") as f:
f.write("..\n This file is auto-generated.\n\n")
f.write(api_head)
f.write(doctree)
print(os.path.abspath("./source/api_index.rst"))


if __name__ == "__main__":
make_api_index()
13 changes: 13 additions & 0 deletions docs/source/_templates/api_index_head.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.. _target-api:

API Reference
=============

Information on specific functions, classes, and methods.

.. rubric:: Modules

.. autosummary::
:toctree: api
:recursive:
:nosignatures:
24 changes: 0 additions & 24 deletions docs/source/api_index.rst

This file was deleted.

0 comments on commit 1dcdb00

Please sign in to comment.