Skip to content

Sphinx (documentation generator)

다른 의미는 (동음이의어)이곳을참조

Sphinx is a documentation generator for the Python programming language.

Categories

Quick start

Assuming you have Python already, install Sphinx:

$ pip install sphinx

Create a directory inside your project to hold your docs:

$ cd /path/to/project
$ mkdir docs

Run sphinx-quickstart in there:

$ cd docs
$ sphinx-quickstart

This quick start will walk you through creating the basic configuration; in most cases, you can just accept the defaults. When it’s done, you’ll have an index.rst, a conf.py and some other files. Add these to revision control.

Now, edit your index.rst and add some information about your project. Include as much detail as you like (refer to the reStructuredText syntax or this template if you need help). Build them to see how they look:

$ make html

How to Build

python 모듈을 호출할 수 있는 상황(e.g. pyenv을 사용할 경우)은 sphinx-build 명령행을 바로 사용할 수 있다. 그렇지 않다면 python -m sphinx 명령으로 대체할 수 있다.

$ sphinx-build
## OR
$ python -m sphinx

Example

sphinx-build -W -b html -d ./_doctrees ./_doc ./_html
  • -W: 경고를 에러로 처리한다.
  • -b html: 빌더(Builder)를 HTML로 선택한다. html, man, latex, text, texinfo, pdf 등이 있다.
  • -d ./_doctrees: 캐시 파일을 저장할 디렉토리 위치.
  • ./_doc: 문서 원본이 포함된 디렉토리 위치. -c PATH 옵션이 적용되지 않다면 conf.py파일은 이 디렉토리에서 읽는다.
  • ./_html: 출력 디렉토리.

Help message

$ sphinx-build --help
usage: sphinx-build [OPTIONS] SOURCEDIR OUTPUTDIR [FILENAMES...]

Generate documentation from source files. sphinx-build generates documentation
from the files in SOURCEDIR and places it in OUTPUTDIR. It looks for 'conf.py'
in SOURCEDIR for the configuration settings. The 'sphinx-quickstart' tool may
be used to generate template files, including 'conf.py' sphinx-build can
create documentation in different formats. A format is selected by specifying
the builder name on the command line; it defaults to HTML. Builders can also
perform other tasks related to documentation processing. By default,
everything that is outdated is built. Output only for selected files can be
built by specifying individual filenames.

positional arguments:
  sourcedir         path to documentation source files
  outputdir         path to output directory
  filenames         a list of specific files to rebuild. Ignored if -a is
                    specified

optional arguments:
  -h, --help        show this help message and exit
  --version         show program's version number and exit

general options:
  -b BUILDER        builder to use (default: html)
  -a                write all files (default: only write new and changed
                    files)
  -E                don't use a saved environment, always read all files
  -d PATH           path for the cached environment and doctree files
                    (default: OUTPUTDIR/.doctrees)
  -j N              build in parallel with N processes where possible (special
                    value "auto" will set N to cpu-count)

build configuration options:
  -c PATH           path where configuration file (conf.py) is located
                    (default: same as SOURCEDIR)
  -C                use no config file at all, only -D options
  -D setting=value  override a setting in configuration file
  -A name=value     pass a value into HTML templates
  -t TAG            define tag: include "only" blocks with TAG
  -n                nit-picky mode, warn about all missing references

console output options:
  -v                increase verbosity (can be repeated)
  -q                no output on stdout, just warnings on stderr
  -Q                no output at all, not even warnings
  --color           do emit colored output (default: auto-detect)
  -N, --no-color    do not emit colored output (default: auto-detect)
  -w FILE           write warnings (and errors) to given file
  -W                turn warnings into errors
  --keep-going      with -W, keep going when getting warnings
  -T                show full traceback on exception
  -P                run Pdb on exception

For more information, visit <http://sphinx-doc.org/>.

Configuration

conf.py파일을 수정하면 된다.

exclude_patterns
무시할 패턴을 입력하면 된다.
master_doc
시작 문서

conf.py

# -*- coding: utf-8 -*-
#
# Configuration file for the Sphinx documentation builder.
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import os
import sys

SCRIPT_PATH = os.path.abspath(__file__)
SCRIPT_DIR = os.path.dirname(SCRIPT_PATH)
STATIC_DIR = os.path.join(SCRIPT_DIR, "_static")
LOCALE_DIR = os.path.join(SCRIPT_DIR, "_locale")
TEMPLATES_DIR = os.path.join(SCRIPT_DIR, "_templates")
EXTENSIONS_DIR = os.path.join(SCRIPT_DIR, '_extensions')

sys.path.insert(0, EXTENSIONS_DIR)


# Project information
project = "project"
copyright = "2021-2022, Company"  # noqa
author = "yourname"

# General configuration
extensions = [
    "sphinx.ext.autodoc",
    "recommonmark",
    "google_analytics",
]
source_suffix = [".rst", ".md"]
source_encoding = "utf-8"
master_doc = "index"
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", ".tox"]
templates_path = [TEMPLATES_DIR]
language = "ko"

# HTML Output
html_theme = "furo"
html_static_path = [STATIC_DIR]

# Locale
locale_dirs = [LOCALE_DIR]
gettext_compact = False

# Google Analytics
google_analytics_enabled = True
google_analytics_id = "UA-162764112-2"

Internationalization

gettext를 사용해야 한다.

Themes

Extensions

googleanalytics

recommonmark

간단히, markdown 파서.

WARNING

recommonmark is now deprecated. We recommend using MyST for a docutils bridge going forward.

cannot import name ExtensionError

sphinx.errors.ExtensionError를 사용하도록 코드 수정.

직접 연결

Google analytics 서비스를 Sphinx에 직접연결하고 싶다면, You can use a custom layout.html template, like this:

{% extends "!layout.html" %}

{%- block extrahead %}
{{ super() }}
<script>
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'XXX account number XXX']);
  _gaq.push(['_trackPageview']);
</script>
{% endblock %}

{% block footer %}
{{ super() }}
<div class="footer">This page uses <a href="https://analytics.google.com/">
Google Analytics</a> to collect statistics. You can disable it by blocking
the JavaScript coming from www.google-analytics.com.
<script>
  (function() {
    var ga = document.createElement('script');
    ga.src = ('https:' == document.location.protocol ?
              'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    ga.setAttribute('async', 'true');
    document.documentElement.firstChild.appendChild(ga);
  })();
</script>
</div>
{% endblock %}

automodule

Include documentation from docstrings

recc.config
===========

.. automodule:: recc.config
    :members:
    :undoc-members:
    :show-inheritance:

    .. automodule:: recc.config.argparse
        :members:

    .. automodule:: recc.config.init_params
        :members:

Python documentation example

In general, a typical Sphinx docstring has the following format:

"""[Summary]

:param [ParamName]: [ParamDescription], defaults to [DefaultParamVal]
:type [ParamName]: [ParamType](, optional)
...
:raises [ErrorType]: [ErrorDescription]
...
:return: [ReturnDescription]
:rtype: [ReturnType]
"""

Let’s have a look at a typical class documentation. In this example we show the docstrings written for the SimpleBleDevice class, which is defined within our simpleble module:

class SimpleBleDevice(object):
    """This is a conceptual class representation of a simple BLE device
    (GATT Server). It is essentially an extended combination of the
    :class:`bluepy.btle.Peripheral` and :class:`bluepy.btle.ScanEntry` classes

    :param client: A handle to the :class:`simpleble.SimpleBleClient` client
        object that detected the device
    :type client: class:`simpleble.SimpleBleClient`
    :param addr: Device MAC address, defaults to None
    :type addr: str, optional
    :param addrType: Device address type - one of ADDR_TYPE_PUBLIC or
        ADDR_TYPE_RANDOM, defaults to ADDR_TYPE_PUBLIC
    :type addrType: str, optional
    :param iface: Bluetooth interface number (0 = /dev/hci0) used for the
        connection, defaults to 0
    :type iface: int, optional
    :param data: A list of tuples (adtype, description, value) containing the
        AD type code, human-readable description and value for all available
        advertising data items, defaults to None
    :type data: list, optional
    :param rssi: Received Signal Strength Indication for the last received
        broadcast from the device. This is an integer value measured in dB,
        where 0 dB is the maximum (theoretical) signal strength, and more
        negative numbers indicate a weaker signal, defaults to 0
    :type rssi: int, optional
    :param connectable: `True` if the device supports connections, and `False`
        otherwise (typically used for advertising ‘beacons’).,
        defaults to `False`
    :type connectable: bool, optional
    :param updateCount: Integer count of the number of advertising packets
        received from the device so far, defaults to 0
    :type updateCount: int, optional
    """

    def __init__(self, client, addr=None, addrType=None, iface=0,
                 data=None, rssi=0, connectable=False, updateCount=0):
        """Constructor method
        """
        super().__init__(deviceAddr=None, addrType=addrType, iface=iface)
        self.addr = addr
        self.addrType = addrType
        self.iface = iface
        self.rssi = rssi
        self.connectable = connectable
        self.updateCount = updateCount
        self.data = data
        self._connected = False
        self._services = []
        self._characteristics = []
        self._client = client

    def getServices(self, uuids=None):
        """Returns a list of :class:`bluepy.blte.Service` objects representing
        the services offered by the device. This will perform Bluetooth service
        discovery if this has not already been done; otherwise it will return a
        cached list of services immediately..

        :param uuids: A list of string service UUIDs to be discovered,
            defaults to None
        :type uuids: list, optional
        :return: A list of the discovered :class:`bluepy.blte.Service` objects,
            which match the provided ``uuids``
        :rtype: list On Python 3.x, this returns a dictionary view object,
            not a list
        """
        self._services = []
        if(uuids is not None):
            for uuid in uuids:
                try:
                    service = self.getServiceByUUID(uuid)
                    self.services.append(service)
                except BTLEException:
                    pass
        else:
            self._services = super().getServices()
        return self._services

    def setNotificationCallback(self, callback):
        """Set the callback function to be executed when the device sends a
        notification to the client.

        :param callback: A function handle of the form
            ``callback(client, characteristic, data)``, where ``client`` is a
            handle to the :class:`simpleble.SimpleBleClient` that invoked the
            callback, ``characteristic`` is the notified
            :class:`bluepy.blte.Characteristic` object and data is a
            `bytearray` containing the updated value. Defaults to None
        :type callback: function, optional
        """
        self.withDelegate(
            SimpleBleNotificationDelegate(
                callback,
                client=self._client
            )
        )

    def getCharacteristics(self, startHnd=1, endHnd=0xFFFF, uuids=None):
        """Returns a list containing :class:`bluepy.btle.Characteristic`
        objects for the peripheral. If no arguments are given, will return all
        characteristics. If startHnd and/or endHnd are given, the list is
        restricted to characteristics whose handles are within the given range.

        :param startHnd: Start index, defaults to 1
        :type startHnd: int, optional
        :param endHnd: End index, defaults to 0xFFFF
        :type endHnd: int, optional
        :param uuids: a list of UUID strings, defaults to None
        :type uuids: list, optional
        :return: List of returned :class:`bluepy.btle.Characteristic` objects
        :rtype: list
        """
        self._characteristics = []
        if(uuids is not None):
            for uuid in uuids:
                try:
                    characteristic = super().getCharacteristics(
                        startHnd, endHnd, uuid)[0]
                    self._characteristics.append(characteristic)
                except BTLEException:
                    pass
        else:
            self._characteristics = super().getCharacteristics(startHnd,
                                                               endHnd)
        return self._characteristics

    def connect(self):
        """Attempts to initiate a connection with the device.

        :return: `True` if connection was successful, `False` otherwise
        :rtype: bool
        """
        try:
            super().connect(self.addr,
                            addrType=self.addrType,
                            iface=self.iface)
        except BTLEException as ex:
            self._connected = False
            return (False, ex)
        self._connected = True
        return True

    def disconnect(self):
        """Drops existing connection to device
        """
        super().disconnect()
        self._connected = False

    def isConnected(self):
        """Checks to see if device is connected

        :return: `True` if connected, `False` otherwise
        :rtype: bool
        """
        return self._connected

    def printInfo(self):
        """Print info about device
        """
        print("Device %s (%s), RSSI=%d dB" %
              (self.addr, self.addrType, self.rssi))
        for (adtype, desc, value) in self.data:
            print("  %s = %s" % (desc, value))

또다른 함수:

    async def executemany(self, command: str, args, *, timeout: float=None):
        """Execute an SQL *command* for each sequence of arguments in *args*.

        Example:

        .. code-block:: pycon

            >>> await con.executemany('''
            ...     INSERT INTO mytab (a) VALUES ($1, $2, $3);
            ... ''', [(1, 2, 3), (4, 5, 6)])

        :param command: Command to execute.
        :param args: An iterable containing sequences of arguments.
        :param float timeout: Optional timeout value in seconds.
        :return None: This method discards the results of the operations.

        .. note::

           When inserting a large number of rows,
           use :meth:`Connection.copy_records_to_table()` instead,
           it is much more efficient for this purpose.

        .. versionadded:: 0.7.0

        .. versionchanged:: 0.11.0
           `timeout` became a keyword-only parameter.
        """
        self._check_open()
        return await self._executemany(command, args, timeout)

Plugins

sphinxcontrib-httpdomain
https://sphinxcontrib-httpexample.readthedocs.io/en/latest/#

Theme

sphinx-rtd-theme
https://pypi.org/project/sphinx-rtd-theme/
pydata-sphinx-theme
The PyData Sphinx Theme
https://github.com/pydata/pydata-sphinx-theme
https://pydata-sphinx-theme.readthedocs.io/en/latest/

Troubleshooting

contents.rst not found

conf.py파일에 아래의 내용을 추가하면 된다.

master_doc = 'index'

이렇게 하면 프로젝트 디렉토리에서 index.rst파일로 찾게 된다.

See also

Favorite site

Offical documentation