Autodoc

WriteADoc provides functionality for automatically generating documentation from Python code docstrings. It extracts information from docstrings—including descriptions, parameters, return values, examples, and more—and structures them into a standardized format.

Usage

::: my_library.my_module.my_class_or_function

This works with classes, functions, and individual class methods and properties.

Function

::: jx.meta.extract_metadata

function extract_metadata

Extract metadata from the Jx template source.

extract_metadata(
    source: str,
    base_path: pathlib._local.Path,
    fullpath: pathlib._local.Path
) -> jx.meta.Meta
ArgumentDescription
source

The template source code.

base_path

Absolute base path for all the template files, for relative imports.

fullpath

The absolute full path of the current template, for relative imports.

Returns:

A Meta object containing the extracted metadata.

Class

::: jx.Catalog

class Catalog

Manager of the components and their global settings.

Catalog(
    folder: str | pathlib._local.Path | None = None,
    *,
    jinja_env: jinja2.environment.Environment | None = None,
    extensions: list | None = None,
    filters: dict[str, typing.Any] | None = None,
    tests: dict[str, typing.Any] | None = None,
    auto_reload: bool = True,
    **globals: Any
) -> None
ArgumentDescription
folder

Optional folder path to scan for components. It's a shortcut to calling add_folder when only one is used.

jinja_env

Optional Jinja2 environment to use for rendering.

extensions

Optional extra Jinja2 extensions to add to the environment.

filters

Optional extra Jinja2 filters to add to the environment.

tests

Optional extra Jinja2 tests to add to the environment.

auto_reload

Whether to check the last-modified time of the components files and automatically re-process them if they change. The performance impact of leaving it on is minimal, but might be noticeable when rendering a component that uses a large number of child components.

**globals

Variables to make available to all components by default.

function add_folder

Add a folder path from which to search for components, optionally under a prefix.

add_folder(
    path: str | pathlib._local.Path,
    *,
    prefix: str = '',
    preload: bool = True
) -> None
ArgumentDescription
path

Absolute path of the folder with component files.

prefix

Optional path prefix that all the components in the folder will have. The default is empty.

preload

Whether to preload the data of components in the folder. If set to True (the default), the component data will be loaded into memory when the folder is added, instead of just before rendering it. This makes the first render faster at the expense of a few microseconds upfront.

Components without a prefix can be imported as a path relative to the folder, e.g.: sub/folder/component.jinja or with a path relative to the component where it is used: ./folder/component.jinja.

Relative imports cannot go outside the folder.

Components added with a prefix must be imported using the prefix followed by a colon: prefix:sub/folder/component.jinja. If the importing is done from within a component with the prefix itself, a relative import can also be used, e.g.: ./component.jinja.

All the folders added under the same prefix will be treated as if they were a single folder. This means if you add two folders, under the same prefix, with a component with the same subpath/filename, the one in the folder added first will be used and the other ignored.

WARNING: You cannot move or delete components files from the folder after calling this method, but you can call it again to add new components added to the folder. This is unrelated to the value of preload.

function get_component

Instantiate and return a component object by its relative path.

get_component(
    relpath: str
) -> jx.component.Component
ArgumentDescription
relpath

The path of the component to render, including the extension,relative to its view folder. e.g.: "sub/component.jinja". Always use the forward slash (/) as the path separator.

function get_component_data

Get the component data from the cache. If the file has been updated, the component is re-processed.

get_component_data(
    relpath: str
) -> jx.catalog.CData
ArgumentDescription
relpath

The path of the component to render, including the extension,relative to its view folder. e.g.: "sub/component.jinja". Always use the forward slash (/) as the path separator.

function render

Render a component with the given relative path and context.

render(
    relpath: str,
    globals: dict[str, typing.Any] | None = None,
    **kwargs
) -> str
ArgumentDescription
relpath

The path of the component to render, including the extension,relative to its view folder. e.g.: "sub/component.jinja". Always use the forward slash (/) as the path separator.

globals

Optional global variables to make available to the component and all its imported components.

**kwargs

Keyword arguments to pass to the component. They will be available in the component's context but not to its imported components.

Returns:

The rendered component as a string.

function render_string

Render a component from a string source. Works like render, but the component is not cached and cannot do relative imports.

render_string(
    source: str,
    globals: dict[str, typing.Any] | None = None,
    **kwargs
) -> str
ArgumentDescription
source

The Jinja2 source code of the component to render.

globals

Optional global variables to make available to the component and all its imported components.

**kwargs

Keyword arguments to pass to the component. They will be available in the component's context but not to its imported components.

Returns:

The rendered component as a string.

Customizing What Is Documented

By default, all members of a class whose names don't start with an underscore ("_") will be included. You can include one or more members that start with an underscore using the include option:

::: jx.Catalog include=__call__,__html__

You can also exclude some members with the exclude option:

::: jx.Catalog exclude=get_data,to_dict include=__call__

Note

As you can see, the options must be separated from each other by spaces.

Changing the Starting Heading Level

By default, the name of the function or class is rendered with an <h2>, and the names of attributes/methods with <h3>. You can change this by adding the starting heading level after the import path:

Custom Starting Heading Level

::: jx.meta.extract_metadata level=4

function extract_metadata

Extract metadata from the Jx template source.

extract_metadata(
    source: str,
    base_path: pathlib._local.Path,
    fullpath: pathlib._local.Path
) -> jx.meta.Meta
ArgumentDescription
source

The template source code.

base_path

Absolute base path for all the template files, for relative imports.

fullpath

The absolute full path of the current template, for relative imports.

Returns:

A Meta object containing the extracted metadata.

Customizing the Output

The extracted information is rendered using the autodoc.jinja view, recursively. There, you can see it receives a ds argument with these fields:

  • name: The name of the documented element
  • symbol: Type of the element (e.g., "class", "function", "method")
  • label: Additional label (e.g., "property", "attribute")
  • signature: Function/method signature
  • params: List of parameters (for functions/methods)
  • short_description: First paragraph of the description
  • long_description: Rest of the description
  • description: The full description
  • deprecation: Deprecation notes
  • examples: List of examples
  • returns: Return information
  • many_returns: List of multiple return values
  • raises: List of exceptions that the function may raise
  • bases: List of base classes (for classes)
  • attrs: List of ds objects for each attribute (for classes)
  • properties: List of ds objects for each property (for classes)
  • methods: List of ds objects for each method (for classes)

Notes on Docstring Parsing

The autodoc module relies on the docstring_parser library to parse docstrings. It supports various docstring formats, but works best with Google-style docstrings.

For optimal results:

  1. Start with a short, one-line description.
  2. Follow with a blank line and then a more detailed description.
  3. Use standard sections like "Arguments:" (or "Args:"), "Returns:", "Raises:", and "Examples:".
  4. Document all parameters, return values, and exceptions.