Handsdown
Root of handsdown source code.
Handsdown
Python package handsdown provides types, functions, and a command-line interface
for accessing public documentation of Python modules, and for presenting it in a
Markdown format ready to be publiched to GitHub Pages or Read the Docs.
handsdown extracts documentation of:
- Modules
- docstring
- submodules
- function definitions
- class definitions
- global variables documented in comment-style
- global objects mentioned in docstring
- Functions
- docstring
- arguments
- decorators
- type annotations
- global objects mentioned in docstring
- parent module objects mentioned in docstring
- Classes
- docstring
- __init__method
- public methods
- magic methods with defined docstring
- attributes documented in comment-style
- decorators
- base classes
- global objects mentioned in docstring
- parent module objects mentioned in docstring
- Class methods
- docstring
- arguments
- decorators
- type annotations
- global objects mentioned in docstring
- parent class objects mentioned in docstring
- parent module objects mentioned in docstring
Prepare your code
# main_example.py
"""
This is a module docstring. It will appear in documentation.
## Notes
You can use Markdown here to make it nicer. Also, in any docstring you
can put a global object import string in backticks, like `other_module.OtherClass`,
and it will be transformed to a link.
"""
from typing import Text, TYPE_CHECKING
from my_project.other_module import BaseClass  # pylint: disable=import-error
if TYPE_CHECKING:
    from my_project.type_defs import StuffCallable  # pylint: disable=import-error
# This is a comment-style documented global variable, so it is added to
# `main_example` module attributes with this comment as a documentation for it
# FIXME: FIXME and TODO comments are igonred
MODULE_NAME = "My Module"
# Private args never appear in docs
_PRIVATE_ATTR = "Private attr"
def hello(name: Text) -> Text:
    """
    This is module function and it is added to documentation even if it does
    not have a docstring. Function signature will be also generated respecting
    regular and comment-style type annotations. Let's use PEP 257 format here.
    Examples::
        # Google-style code block here, but we could use Markdown code block as well
        >>> hello('John')
        'Hello, John!'
        >>> hello('')
        'Hello!'
    Arguments:
        name -- Name of the person to greet.
    Returns:
        A greeting. No need to put types here if you use type annotations.
    """
    if not name:
        return "Hello!"
    return f"Hello, {name}!"
class MyClass(BaseClass):
    """
    MyClass documentation here.
    .. note:: This time we use RST docstrings format.
    """
    # This is a comment-style documented class attribute, so it is added to
    # `main_example.MyClass` attributes with this comment as a documentation for it.
    STUFF_COUNT = 3
    @classmethod
    def do_something(cls, stuff):
        # type: (StuffCallable) -> bool
        """
        This is a public method that uses comment-style type annotations. If decorators
        or types from annotations are from your project, links to them will be added
        to `See also` section. Since this function depends on `STUFF_COUNT`, we can add
        it to a docstring in backticks and it will be transformed to a link.
        .. code-block:: python
            # usage example
            def my_stuff(amount):
                return amount > 5
            MyClass.do_something(my_stuff)  # False
        .. versionadded:: 1.3
        .. deprecated:: 1.8
        .. versionchanged:: 1.4
            All these directives are added to `Notes` section and formatted in Sphinx-style.
        :param stuff: Function do execute.
        :returns: `stuff` result.
        """
        return stuff(cls.STUFF_COUNT)
    def __bool__(self):
        # type: () -> bool
        """
        Magic methods are added to docs only if they have docstrings.
        :returns: True if `STUFF_COUNT` is not zero
        """
        return self.STUFF_COUNT
Usage
From command line
Just go to your favorite project that has lots of docstrings but missing
auto-generated docs and let handsdown do the thing.
cd ~/my/project
# build documentation *.md* files in docs/* directory
handsdown
# or provide custom output directory: output_dir/*
handsdown -o output_dir
# generate docs only for my_module, but exclude migrations
handsdown my_module --exclude 'build/*' 'tests/*' 'test/*' '*/__pycache__/*' '.*/*' 'my_module/migrations'
# generate documentation for deployment
handsdown --external `git config --get remote.origin.url` -n ProjectName
Navigate to docs/README.md to check your new documentation!
As a module
from handsdown.generator import Generator
from handsdown.utils.path_finder import PathFinder
# this is our project root directory
repo_path = Path.cwd()
# this little tool works like `pathlib.Path.glob` with some extra magic
# but in this case `repo_path.glob("**/*.py")` would do as well
path_finder = PathFinder(repo_path, "**/*.py")
# no docs for tests and build
path_finder.exclude("tests/*", "build/*")
# initialize generator
handsdown = Generator(
    input_path=repo_path,
    output_path=repo_path / 'output',
    source_paths=path_finder.glob("**/*.py")
)
# generate all docs at once
handsdown.generate_docs()
# or generate just for one doc
handsdown.generate_doc(repo_path / 'my_module' / 'source.py')
# and generate index.md file
handsdown.generate_index()
# navigate to `output` dir and check results
Installation
Install using pip
More examples
- All documentation in this project
- Main with generated output
- RST docstrings with generated output
- Google docstrings with generated output
- PEP 257 docstrings with generated output
- Sphinx docstrings with generated output
- Type annotations with generated output
- Comment-style type annotations with generated output
Handsdown API Index / Handsdown
Auto-generated documentation for handsdown module.