Sphinx doc
Sphinx
install
pip install sphinx
Layout
Run this at the root dir of your lib:
sphinx-quickstart docs
# separate source and build --> usually choose yes.
The layout will be:
mylib # <-- source code
setup.py
readme.md
# create by sphinx
docs
├── build # rendered doc
├── make.bat
├── Makefile
└── source
├── conf.py # important!
├── index.rst # welcome page
├── _static
└── _templates
Build the doc by:
sphinx-build -M html docs/source/ docs/build
# or in linux
cd docs
make html
Then you can open the built index html (e.g., right click and openning by vs code live server):
http://127.0.0.1:5500/docs/build/html/index.html
Write docs
By default sphinx uses ReStructuredText (.rst) mark up language, which is less common. But we can use m2r2
extension to convert markdown (.md) to rst formats:
extensions = [
"m2r2",
]
source_suffix = [".rst", ".md"]
Narrative documentation
Just create a new file under docs/source
, like index.md
.
Remember to cross-reference it to index.md
under toctree
:
.. table of content trees
.. toctree::
:caption: Tutorials
:hidden:
:maxdepth: 1
:titlesonly:
./mesh.md
./camera.md
.. toctree::
:caption: API
:hidden:
:maxdepth: 1
:titlesonly:
./utils.md
./cli.md
Automatic documentation
To automatically document all APIs, use these extensions:
extensions = [
'sphinx.ext.autodoc', # extract doc for single func/class
]
These extensions will extract docstring from py
source files.
There are different docstring styles, by default sphinx use a format as:
def func(path):
"""
Func description.
:param path: The path of the file to wrap
:type path: str
:returns: A buffered writable file descriptor
:rtype: BufferedFileStorage
"""
...
Another popular format is Google Python style:
def func(arg1: int, arg2: str) --> bool:
"""Summary line.
Extended description of function.
Args:
arg1 (int): Description of arg1
arg2 (str): Description of arg2
Returns:
bool: Description of return value
"""
return True
You need this extension to use it:
extensions = ['sphinx.ext.napoleon']
To auto-generate the docs, you need to write in your doc file:
.. autodoc a func
.. autofunction:: kiui.func
.. autodoc a class, including all members
.. autoclass:: kiui.myClass()
:members:
.. autodoc a file, including all functions and classes, most useful!
.. automodule:: kiui.utils
:members:
Note that autodoc
will import the file to doc it! Ensure there are no side effects for any import.
Note the number of spaces before :members:
! It must be 2 or 3 spaces, and 4 spaces will complain Explicit markup ends without a blank line; unexpected unindent
and won't correctly generate your doc!
Publish
Use extension:
extensions = [
"sphinx.ext.githubpages",
]
Create a doc building docs/requirements.txt
:
sphinx
sphinx_design
sphinx-copybutton
furo
m2r2
Make sure the setup of your lib includes all necessary dependencies (may use a [full]
dependency setting), since the sphinx need to import all modules to perform auto doc.
Create workflow under .github/workflows/docs.yaml
:
name: docs
on:
push:
branches: [main]
workflow_dispatch:
jobs:
docs:
runs-on: ubuntu-latest
steps:
# Check out source
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: "3.10"
# Build documentation
- name: Building documentation
run: |
pip install --upgrade pip
pip install -e ".[full]"
pip install -r docs/requirements.txt
sphinx-build docs/source docs/build -b dirhtml
# Deploy
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # Note that the GITHUB_TOKEN is NOT a personal access token. A GitHub Actions runner automatically creates a GITHUB_TOKEN secret to authenticate in your workflow. So, you can start to deploy immediately without any configuration.
publish_dir: ./docs/build
cname: kit.kiui.moe
Push to your git repo and trigger the workflow. Don't forget to configure the github pages!
Theme
For example:
pip install furo
Change conf.py:
html_theme = 'furo'
You may also want to add a badge to github and show the stars, this will need to create a file under source/_templates/sidebar/brand.html
:
<a class="sidebar-brand{% if logo %} centered{% endif %}" href="{{ pathto(master_doc) }}">
{% block brand_content %} {%- if logo_url %}
<div class="sidebar-logo-container">
<img class="sidebar-logo" src="{{ logo_url }}" alt="Logo" />
</div>
{%- endif %} {%- if theme_light_logo and theme_dark_logo %}
<div class="sidebar-logo-container" style="margin: .5rem auto .5rem auto">
<img class="sidebar-logo only-light" src="{{ pathto('_static/' + theme_light_logo, 1) }}" alt="Light Logo" />
<img class="sidebar-logo only-dark" src="{{ pathto('_static/' + theme_dark_logo, 1) }}" alt="Dark Logo" />
</div>
{%- endif %} {#- {% if not theme_sidebar_hide_name %}
<span class="sidebar-brand-text">{{ docstitle if docstitle else project }}</span>
{%- endif %} -#} {% endblock brand_content %}
</a>
<div style="text-align: center">
<b>kiuikit</b>
</br>
<script async defer src="https://buttons.github.io/buttons.js"></script>
<a class="github-button" href="https://github.com/ashawkey/kiuikit"
data-color-scheme="no-preference: light; light: light; dark: light;" data-size="large" data-show-count="true"
aria-label="Download buttons/github-buttons on GitHub">
Github
</a>
</div>
The logo and website favicon should be put under source/_static/
, and set in conf.py
:
html_favicon = '_static/icon.png'
html_logo = '_static/logo.png'
Example conf
# -- Project information -----------------------------------------------------
project = 'kiui'
copyright = '2024, kiui'
author = 'kiui'
# The full version, including alpha/beta/rc tags
release = '0.2.0'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx.ext.githubpages",
"sphinx.ext.viewcode",
"sphinx_design",
"sphinx_copybutton",
"m2r2",
]
# sort automodule generated doc by source
autodoc_default_options = {
"member-order": "bysource",
}
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'furo'
# html_title = "kiuikit" # default is name-version documentation
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_favicon = '_static/icon.png'
html_logo = '_static/logo.png'
sphinx_to_github = True
sphinx_to_github_verbose = True
sphinx_to_github_encoding = "utf-8"
napoleon_google_docstring = True
napoleon_numpy_docstring = False
napoleon_include_init_with_doc = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = True
napoleon_use_rtype = True
napoleon_preprocess_types = False
napoleon_type_aliases = None
napoleon_attr_annotations = True