Skip to main content

Autodox

Tool for generating documentation automatically from code annotations, types, and docstrings.

Status

Primary development is complete. Further development will be tracked in the issues. Historical changes can be found in the changelog.

Full API documentation generated by autodox can be found here.

Usage

Note that autodox imports the module being documented, so it must be installed in the same Python environment as the target module. If autodox is installed at the system or user level while the target module lives in a virtual environment, the autodox CLI will not be able to import it. Install autodox inside the target module's environment (e.g. activate the virtualenv and run pip install autodox there) before documenting it.

Installation

pip install autodox

Note that Protocols do not support __init__ methods before Python 3.11. To use __init__ method signatures for Protocols in Python 3.10, use the typing.Protocol backport from the 3rd-party typing_extensions package. Otherwise, the __init__ method signature will be overridden with an empty one named _no_init_or_replace_init and will be ignored by this tool.

Document a module from CLI

Use the following to document a module with default configuration:

autodox module_name [options] > target_file.md

The output can be configured with the following options:

  • -exclude_name=name to exclude a specific part of the module by name
  • -exclude_type=type to exclude any module parts of the given type
  • -package=module_name to scope a relative import
  • -header_level=number to increase the hashtag count in headers by number
  • -function_format=format - can be one of 'header', 'paragraph', or 'list'
  • -method_format=format - can be one of 'header', 'paragraph', or 'list'
  • -value_format=format - can be one of 'header', 'paragraph', or 'list'
  • -line_length=number - number of chars per line in paragraphs
  • -include_private to include things prefaced with '_'
  • -include_dunder to include things prefaced with '__'
  • -include_submodules to include submodules
  • -document_submodules to run the module documentation for submodules
  • -debug to increase the level of debug statements printed (starts at 0)

For experimentation and to learn how the options work, try running the following:

autodox autodox [options]

Programmatic access

The autodox package can also be used by importing and running the desired documentation function(s). The following are included.

  • dox_a_module(module: ModuleType, options: dict | None = None) -> str produces docs for a module
  • dox_a_value(value: Any, options: dict | None = None) -> str produces docs for a value
  • dox_a_function(function: Callable, options: dict | None = None) -> str produces docs for a function
  • dox_a_class(cls: type, options: dict | None = None) -> str produces docs for a class

The valid options for each will be described below. Additionally, there is a system for setting up hooks that interact with the doc generation process to change the inputs or outputs, and that will be described below the options for the four dox_a_{thing} functions.

dox_a_module(module: ModuleType, options: dict | None = None) -> str

Produces docs for a module. Valid options are the following:

  • exclude_names: list[str] - names to exclude from docs
  • exclude_types: list[str] - types to exclude from docs
  • header_level: int - number of additional hashtags to add to headers
  • function_format: str - can be one of 'header', 'paragraph', or 'list'
  • method_format: str - can be one of 'header', 'paragraph', or 'list'
  • value_format: str - can be one of 'header', 'paragraph', or 'list'
  • include_private: bool - if True, includes things with names prefaced by '_'
  • include_dunder: bool - if True, includes things with names prefaced by '__'
  • include_submodules: bool - if True, notes will be made about any additional modules encountered when analyzing the specified module
  • document_submodules: bool - if True, dox_a_module will be called recursively on any additional modules encountered when analyzing the specified module
  • line_length: int - number of chars per line in paragraphs

When the same class or function is bound to more than one name in a module (e.g. UsageError = DependencyError), dox_a_module documents the target once and emits an alias entry (### \UsageError = DependencyError`) for each additional binding. Alias detection is automatic; no configuration is required, and a class-body method alias such as bar = foois handled the same way. An alias is only detected when the target is bound under itsnamein the same namespace: aliases of builtins, inherited methods, renamed imports, and name-mangled targets are documented under theirname` instead.

dox_a_value(value: Any, options: dict | None = None) -> str

Produces docs for a value. Valid options are the following:

  • header_level: int - number of additional hashtags to add to headers
  • format: str - format can be one of 'header', 'paragraph', or 'list'
  • name: str - overrides the name used in the docs (the module binding name)
  • line_length: int - number of chars per line in paragraphs

dox_a_function(function: Callable, options: dict | None = None) -> str

Produces docs for a function. Valid options are the following:

  • header_level: int - number of additional hashtags to add to headers
  • format: str - format can be one of 'header', 'paragraph', or 'list'
  • prepend: str - text prepended to the signature (used for decorators)
  • line_length: int - number of chars per line in paragraphs

dox_a_class(cls: type, options: dict | None = None) -> str

Produces docs for a class. Valid options are the following:

  • exclude_names: list[str] - names to exclude from docs
  • header_level: int - number of additional hashtags to add to headers
  • include_private: bool - if True, includes things with names prefaced by '_'
  • include_dunder: bool - if True, includes things with names prefaced by '__'
  • method_format: str - can be one of 'header', 'paragraph', or 'list'
  • line_length: int - number of chars per line in paragraphs

Hooks

There are eleven events where custom functionality can be run, specified in the Event enum:

  • AFTER_HEADER
  • AFTER_PARAGRAPH
  • AFTER_LIST
  • BEFORE_VALUE
  • AFTER_VALUE
  • BEFORE_FUNCTION
  • AFTER_FUNCTION
  • BEFORE_CLASS
  • AFTER_CLASS
  • BEFORE_MODULE
  • AFTER_MODULE

Handlers for the BEFORE_ events can be set using the set_before_handler function. These handlers will receive the item to be documented and a dict containing any options passed into the dox_a_{thing} function, and they should return a tuple containing those two arguments after any modifications are made to them. Example:

from autodox import Event, set_before_handler
from typing import Callable


def handle_before_function(function: Callable, options: dict):
    # set an option
    options['header_level'] = 2
    return (function, options)

set_before_handler(Event.BEFORE_FUNCTION, handle_before_function)

Handlers for the AFTER_ events can be set using the set_after_handler function. These handlers will receive the str doc after the dox_a_{thing} function has completed executing, and they should return that document after any modifications are made. Example:

from autodox import Event, set_after_handler


def handle_after_function(doc: str):
    # do some string manipulation
    return doc + 'But really, why would you call this function anyway?\n\n'

set_after_handler(Event.AFTER_FUNCTION, handle_after_function)

Muliple handlers can be set for each event, and they will be executed in order, passing the output from the first as input to the second, etc. Example:

from autodox import Event, set_after_handler


# add 'hello world' to the end of each list item in two steps
def hello(doc: str):
    return doc + ' hello'

def world(doc: str):
    return doc + ' world'

set_after_handler(Event.AFTER_LIST, hello)
set_after_handler(Event.AFTER_LIST, world)

Testing

The test suite uses the standard library unittest module and covers the hook system and the generated documentation, including signature rendering, class annotations, protocols, and alias detection.

To run it, clone the repository and run the following:

# setup
python -m venv venv
source venv/bin/activate
pip install -e .

# then
python tests/test_hooks.py
python tests/test_doxing.py
# or
python -m unittest discover tests/

ISC License

Copyright (c) 2026 k98kurz

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyleft notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Metadata

Release files for autodox 0.1.17

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for autodox 0.1.17
File Size Uploaded
autodox-0.1.17.tar.gz 12.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for autodox 0.1.17
File Interpreter ABI Platform
autodox-0.1.17-py3-none-any.whl Python 3 none any Details

Total release size: 24.5 kB

Release files / autodox-0.1.17.tar.gz

Download URL autodox-0.1.17.tar.gz
Size 12.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f7d9e8914b227fad7d6803f77486d5c0cc51177caf1b45239b41a2a1e177f92c
BLAKE2b-256 checksum
How to use checksums
b94d43e37a8b5737373fa244ce0c1d8cc4dda0bd0d092ee03fb6963a49011576
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / autodox-0.1.17-py3-none-any.whl

Download URL autodox-0.1.17-py3-none-any.whl
Size 12.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ff33499d81ef69dfb2d0261c142992ce3a3c33ef610afb674c8c554da0344d76
BLAKE2b-256 checksum
How to use checksums
c40f9b63cc5952e177a84047c925ce25b7ccf44bc47e6ca28860a9a749198a95
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page