Skip to content

Object Mode

MkAPI offers an Object mode that allows you to seamlessly embed object documentation within your Markdown source.

Demonstration Package

In this section, we utilize a demonstration package called example to illustrate the Object mode of MkAPI. This package includes a module named mod_a and a subpackage named sub, which contains a module named mod_b.

The directory structure of the example package is as follows:

example/
├─ __init__.py
├─ mod_a.py
└─ sub/
   ├─ __init__.py
   └─ mod_b.py

Top-level Package

Let’s first explore the top-level package example. To embed the object documentation in your Markdown source, you can use the following syntax:

::: example

The line must start with three colons (:::), followed by a space () and the full name of the object (e.g., package.module.function). In this case, we simply use the package name example. MkAPI scans the Markdown source to find this syntax pattern and converts it into the corresponding object documentation as shown below:

source package example

Example package.

Modules

Note

In the example above, the green dashed border serves as a visual guide to clarify the region of the documentation generated by MkAPI.

In the above example, the object type (package) and its name (example) are displayed. This section serves as the heading of the object documentation.

At the right end of the heading, a [source] button is provided. Clicking this button will navigate to the source code of the object. Next to the [source] button, a button is provided. Clicking this button will hide the documentation to save space, and the button will change to a button. When you click the button again, the documentation will be shown once more.

Following the heading, the main content of the documentation is rendered. The content of the example package is simply a one-line summary:

example/__init__.py
"""Example package."""

The example package contains a example.sub subpackage and a example.mod_a module. A Modules section is automatically generated and the example.sub subpackage and example.mod_a module are listed in this section.

Note

This is because the example package does not define or import any members. If there are members, they will take precedence.

Like the heading, the Modules section also contains a / button. The behavior of this button is the same as that of the heading. All sections of the object documentation are collapsible, as shown in the following example.

Package with Members

If a package has members, MkAPI automatically lists them as a table of contents (TOC), categorizing them by type (class, function, or module).

In our example, the example.sub package has some members. Check the output:

::: example.sub

source package example.sub

Subpackage.

Classes

Functions

In the above example, the documentation for the example.sub package includes:

  • A Classes section including two classes: ClassA and ClassB.
  • A Functions section including two functions: func_a and func_b.

These names link to the object documentation for easy navigation if the objects are defined in the current MkDocs project. A summary line for each class and function is also provided for convenience.

Below is the source code of example/sub/__init__.py.

example/sub/__init__.py
"""Subpackage."""

from ..mod_a import ClassA, func_a
from .mod_b import ClassB, func_b

__all__ = ["ClassA", "ClassB", "func_a", "func_b"]

The example.sub package also has an__all__ attribute. The package members listed in the TOC are sorted by the order of appearance in the __all__ attribute.

Module

A Python module consists of classes and functions as its members. MkAPI automatically adds a list of members.

::: example.mod_a

source module example.mod_a

Module A.

Classes

Functions

Function

The example.mod_a module contains a function named func_a. You can embed it like this:

::: example.mod_a.func_a

source func_a(x: int)int

Function A.

Parameters

  • x : int An integer.

Returns

  • int An integer.

The heading of the object documentation contains a tooltip displaying the full name of the object. You can view the full name by hovering your mouse cursor over the function name func_a in the example above. This feature is helpful for quickly identifying the object, keeping the documentation concise.

You can find a See also section at the bottom of the documentation. This section contains links to the documentation of listed objects. Again, hovering your mouse cursor over the links will display a tooltip with the full name of each object. Instructions on how to generate these links will be described below.

Class

The example.mod_a module contains a class named ClassA. You can embed it in the same way as functions.

::: example.mod_a.ClassA

source class ClassA()

Class A.

Attributes

  • attr_a : str Attribute A.

Methods

A class has its own members like modules. You can find Attributes and Methods sections as the TOC. When a class has many members, you can hide and show the members by clicking the / button in these sections of the class documentation.

Method

Methods can also be embedded in a Markdown source by its qualified name.

::: example.mod_a.ClassA.method_a

source method ClassA.method_a(x: Iterable[str], y: ClassB)ClassA

Method A. Return ClassA.

Parameters

  • x : Iterable[str] An iterable of strings.

  • y : ClassB An instance of ClassB.

Returns

Raises

  • ValueError

The heading of a method's documentation contains a tooltip displaying the full name of the method along with the class to which the method belongs. You can also click the button to display the qualified names of all methods on the current page.

Source Code

Finally, check the source code of example/mod_a.py.

example/mod_a.py
"""Module A."""

from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from collections.abc import Iterable

    from .sub.mod_b import ClassB


class ClassA:
    """Class A."""

    attr_a: str = "string"
    """Attribute A."""

    def method_a(self, x: Iterable[str], y: ClassB) -> ClassA:
        """Method A. Return `ClassA`.

        Args:
            x: An iterable of strings.
            y: An instance of `ClassB`.

        Returns:
            An instance of `ClassA`.
        """
        if not x:
            raise ValueError

        return self


def func_a(x: int) -> int:
    """Function A.

    Args:
        x: An integer.

    Returns:
        An integer.

    See Also:
        - `ClassA.method_a`
        - `ClassB.method_b`
        - [`func_b`][example.sub.mod_b.func_b]
    """
    return 2 * x

In the See Also: section of the func_a function, ClassA.method_a is listed as just `ClassA.method_a`. This is because ClassA is defined in the same module as func_a and it is visible from func_a. MkAPI recognizes the fully qualified name and embeds a link to the corresponding object documentation.

ClassB.method_b is also listed as just `ClassB.method_b`. Although ClassB isn't defined in the same module, it is visible from func_a because ClassB is imported.

Note

ClassB is imported in a TYPE_CHECKING context so that it is not visible to the Python interpreter. MkAPI inspects the source code using abstract syntax tree (AST) to find objects.

For func_b in example.sub.mod_b, Markdown link syntax is used because func_b is not visible from func_a. If you write it as just `func_b`, MkAPI will not be able to identify the object, and the link will not be generated.

Note

Did you notice that the link to the func_a function is written on this page (not in the docstring)? It is written as follows:

In the `See Also:` section of the [`func_a`][example.mod_a.func_a]
function, `ClassA.method_a` is ...

Now, you might be wondering if you have to write all of the module members by yourself. The Page mode of MkAPI will assist you.