Page Mode and Internal Links

Page Mode

Page mode is a powerful feature that constructs a comprehensive API documentation for your project. To use the page mode, just add one line to mkdocs.yml:

  - API: mkapi/api/mkapi

MkApi scans the nav to find an entry that starts with 'mkapi/'. This entry must include two or more slashes ('/'). Second part ('api') splitted by slash is a directory name. MkApi automatically creates this directory in the docs directory at the beginning of the process and deletes it and its contents after the process.

The rest ('mkapi') is a root package name, which is assumed to exist in the mkdocs.yml directory. However, if a root package is in src directory, for example, you can specify it like this:

  - API: mkapi/api/src/mkapi

MkApi searches all packages and modules and create a Markdown source for one package or module, which is saved in the api directory. The rest work is done by MkDocs. You can see the documentation of MkApi in the left navigation menu.


  • If a package or module has no package- or module-level docstring and its members have no docstring as well, MkApi doesn't process it.
  • For upper case heading, use the upper filter. See Documentation with Heading.

Once a project documentation is generated, you can use hyperlink to it using normal Markdown syntax.

Go to [Section](mkapi.core.base.Section).

The above line create a link to mkapi.core.base.Section object:

Go to Section.

You can use this feature even in your docstring. For example, assume that func() is defined in a link.fullname module:

File 4 link/

def func():
    """Internal link example.

    See Also:
        [a method](mkapi.core.base.Item.set_html)

The link.fullname.func() is rendered as:


Internal link example.

See Also

You can click the above "a method" to visit its documentation.

Furthermore, if your module imports an object, you can refer it by its qualified name only.

File 5 link/

from mkapi.core.base import Section
from mkapi.core.docstring import get_docstring

def func():
    """Internal link example.

    * [Section]() --- Imported object.
    * [](get_docstring) --- Imported object.
    * [Section.set_html]() --- Member of imported object.
    * [Section definition](Section) --- Alternative text.
    * Section_  --- reStructuredText style.
    return Section(), get_docstring(None)

The link.qualname.func() is rendered as:


Internal link examples.

Documentation created by the embedding mode has link to its project documentation.


creates the documentation of the section_heading():


Returns a tuple of (section name, style name).

  • line (str) Docstring line.
>>> section_heading("Args:")
('Args', 'google')
>>> section_heading("Raises")
('Raises', 'numpy')
>>> section_heading("other")
('', '')

You can click the prefix (mkapi.core.docstring) or the function name (section_heading) to go to the project documentation.

Docstring class of MkApi has an attribute sections that is a list of Section class instance:

# Mimic code of Docstring class.
from dataclasses import dataclass
from typing import List

from mkapi.core.base import Section

class Docstring:
    """Docstring ...."""
    sections: List[Section] = field(default_factory=list)
    type: str = ""

Corresponding real documentation is displayed as below. Note that Section and Type are bold, which indicates that it is a link. Let's click. This link system using type annotation is useful to navigate users throughout the project documentation.

mkapi.core.base.Docstring(sections=<factory>, type=<factory>)

Docstring class represents a docstring of an object.

  • sections (list of Section, optional) List of Section instance.
  • type (Type, optional) Type for Returns or Yields sections.
  • sections (list of Section) List of Section instance.
  • type (Type) Type for Returns or Yields sections.

Empty docstring:

>>> docstring = Docstring()
>>> assert not docstring

Docstring with 3 sections:

>>> default = Section("", markdown="Default")
>>> parameters = Section("Parameters", items=[Item("a"), Item("[b](!a)")])
>>> returns = Section("Returns", markdown="Results")
>>> docstring = Docstring([default, parameters, returns])
>>> docstring

Docstring is iterable:

>>> list(docstring)
[Section('', num_items=0), Item('[b](!a)', ''), Section('Returns', num_items=0)]


>>> docstring["Parameters"].items[0].name

Section ordering:

>>> docstring = Docstring()
>>> _ = docstring['']
>>> _ = docstring['Todo']
>>> _ = docstring['Attributes']
>>> _ = docstring['Parameters']
>>> [ for section in docstring.sections]
['', 'Parameters', 'Attributes', 'Todo']

Returns True if the number of sections is larger than 0.


Yields Base instance.


Returns a Section instance whose name is equal to name.

If there is no Section instance, a Section instance is newly created.

  • name (str) Section name.
__contains__(name) → bool

Returns True if there is a Section instance whose name is equal to name.

  • name Section name.
set_section(section, force=False, copy=False, replace=False)

Sets a Section.

  • section (Section) Section instance.
  • force (bool, optional) If True, overwrite self regardless of existing seciton.
>>> items = [Item('x', 'int'), Item('y', 'str', 'y')]
>>> s1 = Section('Attributes', items=items)
>>> items = [Item('x', 'str', 'X'), Item('z', 'str', 'z')]
>>> s2 = Section('Attributes', items=items)
>>> doc = Docstring([s1])
>>> doc.set_section(s2)
>>> doc['Attributes']['x'].to_tuple()
('x', 'int', 'X')
>>> doc['Attributes']['z'].to_tuple()
('z', 'str', 'z')
>>> doc.set_section(s2, force=True)
>>> doc['Attributes']['x'].to_tuple()
('x', 'str', 'X')
>>> items = [Item('x', 'X', 'str'), Item('z', 'z', 'str')]
>>> s3 = Section('Parameters', items=items)
>>> doc.set_section(s3)
>>> doc.sections
[Section('Parameters', num_items=2), Section('Attributes', num_items=3)]