I built a Sphinx documentation and the build works well locally. My docstrings appear as shown below.
When moving to readthedoc.io, I added a specific requirement file under docs/requirement.txt
which is:
sphinx==3.5.4
sphinx_rtd_theme==0.5.2
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==1.0.3
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.4
And my .readthedocs.yaml
looks like:
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py
# Optionally build your docs in additional formats such as PDF
formats:
- pdf
# Optionally set the version of Python and requirements required to build your docs
python:
version: 3.7
install:
- requirements: docs/requirements.txt
However, when building the doc on readthedocs.io, even if my build completes with no error, the docstrings don't show.
Here is the log:
git clone --no-single-branch --depth 50 https://github.com/Green-Investement-Dashboard/GRID_app.git .
git checkout --force origin/app_v2
git clean -d -f -f
python3.7 -mvirtualenv /home/docs/checkouts/readthedocs.org/user_builds/grid-app/envs/latest
/home/docs/checkouts/readthedocs.org/user_builds/grid-app/envs/latest/bin/python -m pip install --upgrade --no-cache-dir pip setuptools
/home/docs/checkouts/readthedocs.org/user_builds/grid-app/envs/latest/bin/python -m pip install --upgrade --no-cache-dir mock==1.0.1 pillow==5.4.1 alabaster>=0.7,<0.8,!=0.7.5 commonmark==0.8.1 recommonmark==0.5.0 sphinx sphinx-rtd-theme readthedocs-sphinx-ext<2.2
/home/docs/checkouts/readthedocs.org/user_builds/grid-app/envs/latest/bin/python -m pip install --exists-action=w --no-cache-dir -r docs/requirements.txt
cat docs/source/conf.py
/home/docs/checkouts/readthedocs.org/user_builds/grid-app/envs/latest/bin/python -m sphinx -T -b html -d _build/doctrees -D language=en . _build/html
/home/docs/checkouts/readthedocs.org/user_builds/grid-app/envs/latest/bin/python -m sphinx -b latex -D language=en -d _build/doctrees . _build/latex
cat latexmkrc
latexmk -r latexmkrc -pdf -f -dvi- -ps- -jobname=grid-app -interaction=nonstopmode
mv -f /home/docs/checkouts/readthedocs.org/user_builds/grid-app/checkouts/latest/docs/source/_build/latex/grid-app.pdf /home/docs/checkouts/readthedocs.org/user_builds/grid-app/artifacts/latest/sphinx_pdf/grid-app.pdf
What have I done wrong?
Remember that Sphinx's Autodoc extension "imports the modules to be documented". That's because Autodoc uses Python introspection to access the doc-strings. This has the advantage, from Autodoc's perspective, that it can let Python do the parsing. The disadvantage, from a user perspective, is that we have to make sure all dependencies are installed, or at least "mocked".
This is not a problem on your development machine where, naturally, all external libraries your package depends on are already installed. But when building on the Read-the-Docs server, in a "naked" Python environment so to speak, many of them are missing. You added the dependencies required for building the Sphinx project to docs/requirements.txt
, and that would be sufficient if you didn't use the Autodoc extension. But since you do, your doc-strings are missing because modules in your package import something like flask_login
or plotly
. On Read-the-Docs, you should see warning messages to that effect if you look at the extended log (not the basic one you posted), which is accessible by clicking "View raw" in the Builds tab. These are warnings, not errors. So the build passes, but the doc-strings are missing.
Adding the extra dependencies will slow down the documentation builds because they all have to be installed before Sphinx even gets to work. So a better strategy is to mock them. You could test that locally first, in a new virtual environment.
Packages which are imported like import numpy
can be mocked by adding the Autodoc option autodoc_mock_imports
to conf.py
:
autodoc_mock_imports = ['numpy']
If you import objects directly from a package's name space, like from numpy import array
, it may be necessary to use MagicMock
from the unittest
module instead:
from unittest.mock import MagicMock
sys.modules['numpy'] = MagicMock()