:blue_book: Automatic documentation from sources, for MkDocs.

Overview

mkdocstrings

ci documentation pypi version conda version gitter

Automatic documentation from sources, for MkDocs.


mkdocstrings_gif1


Features

  • Language agnostic: just like mkdocs, mkdocstrings is written in Python but is language-agnostic. It means you can use it for any language, as long as you implement a handler for it. Currently, we only have a Python handler. Maybe you'd like to contribute another one 😉 ?
  • Multiple themes support: each handler can offer multiple themes. Currently, we offer the Material theme as well as basic support for the ReadTheDocs theme for the Python handler.
  • Cross-references to other objects: mkdocstrings makes it possible to reference other headings from your Markdown files with the classic Markdown syntax: [identifier][] or [title][identifier]. This feature is language agnostic as well: you can cross-reference any heading that appear in your Markdown pages. If the handler for a particular language renders headings for documented objects, you'll be able to reference them!
  • Inline injection in Markdown: instead of generating Markdown files, mkdocstrings allows you to inject documentation anywhere in your Markdown contents. The syntax is simple: ::: identifier followed by a 4-spaces indented YAML block. The identifier and YAML configuration will be passed to the appropriate handler to collect and render documentation.
  • Global and local configuration: each handler can be configured globally in mkdocs.yml, and locally for each "autodoc" instruction.
  • Watch source code directories: you can tell mkdocstrings to add directories to be watched by mkdocs when serving the documentation, for auto-reload.
  • Sane defaults: you should be able to just drop the plugin in your configuration and enjoy your auto-generated docs.

Python handler features

  • Data collection from source code: collection of the object-tree and the docstrings is done by pytkdocs. The following features are possible thanks to it:
    • Support for type annotations: pytkdocs collects your type annotations and mkdocstrings uses them to display parameters types or return types.
    • Recursive documentation of Python objects: just use the module dotted-path as identifier, and you get the full module docs. You don't need to inject documentation for each class, function, etc.
    • Support for documented attribute: attributes (variables) followed by a docstring (triple-quoted string) will be recognized by pytkdocs in modules, classes and even in __init__ methods.
    • Support for objects properties: pytkdocs detects if a method is a staticmethod, a classmethod, etc., it also detects if a property is read-only or writable, and more! These properties will be displayed next to the object signature by mkdocstrings.
    • Google-style sections support in docstrings: pytkdocs understands Arguments:, Raises: and Returns: sections, and returns structured data for mkdocstrings to render them.
    • reStructuredText-style sections support in docstrings: pytkdocs understands all the reStructuredText fields, and returns structured data for mkdocstrings to render them. Note: only RST style is supported, not the whole markup.
    • Admonition support in docstrings: blocks like Note: or Warning: will be transformed to their admonition equivalent. We do not support nested admonitions in docstrings!
    • Support for reStructuredText in docstrings: pytkdocs can parse simple RST.
  • Every object has a TOC entry: we render a heading for each object, meaning mkdocs picks them into the Table of Contents, which is nicely display by the Material theme. Thanks to mkdocstrings cross-reference ability, you can even reference other objects within your docstrings, with the classic Markdown syntax: [this object][package.module.object] or directly with [package.module.object][]
  • Source code display: mkdocstrings can add a collapsible div containing the highlighted source code of the Python object.

To get an example of what is possible, check mkdocstrings' own documentation, auto-generated from sources by itself of course, and the following GIF:

mkdocstrings_gif2

Roadmap

See the Feature Roadmap issue on the bugtracker.

Requirements

mkdocstrings requires Python 3.6 or above.

To install Python 3.6, I recommend using pyenv.
# install pyenv
git clone https://github.com/pyenv/pyenv ~/.pyenv

# setup pyenv (you should also put these three lines in .bashrc or similar)
export PATH="${HOME}/.pyenv/bin:${PATH}"
export PYENV_ROOT="${HOME}/.pyenv"
eval "$(pyenv init -)"

# install Python 3.6
pyenv install 3.6.12

# make it available globally
pyenv global system 3.6.12

This project currently only works with the Material theme of MkDocs. Therefore, it is required that you have it installed.

pip install mkdocs-material

Installation

With pip:

python3.6 -m pip install mkdocstrings

With conda:

conda install -c conda-forge mkdocstrings

Quick usage

# mkdocs.yml
theme:
  name: "material"

plugins:
- search
- mkdocstrings

In one of your markdown files:

# Reference

::: my_library.my_module.my_class

See the Usage section of the docs for more examples!

Comments
  • jinja2.exceptions.TemplateNotFound: alias.html

    jinja2.exceptions.TemplateNotFound: alias.html

    Describe the bug

    While running mkdocs build I get an exception:

    $ mkdocs build
    INFO     -  Cleaning site directory
    INFO     -  Building documentation to directory: C:\Users\lameg\kubekind\site
    WARNING  -  mkdocstrings_handlers: 1 aliases were still unresolved after 2 iterations
    ERROR    -  mkdocstrings: Template 'alias.html' not found for 'python' handler and theme 'material'.
    ERROR    -  Error reading page 'index.md': alias.html
    Traceback (most recent call last):
      File "C:\Users\lameg\miniforge3\lib\runpy.py", line 197, in _run_module_as_main
        return _run_code(code, main_globals, None,
      File "C:\Users\lameg\miniforge3\lib\runpy.py", line 87, in _run_code
        exec(code, run_globals)
      File "C:\Users\lameg\miniforge3\Scripts\mkdocs.exe\__main__.py", line 7, in <module>
      File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1137, in __call__
        return self.main(*args, **kwargs)
      File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1062, in main
        rv = self.invoke(ctx)
      File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1668, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 1404, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "C:\Users\lameg\miniforge3\lib\site-packages\click\core.py", line 763, in invoke
        return __callback(*args, **kwargs)
      File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\__main__.py", line 192, in build_command
        build.build(config.load_config(**kwargs), dirty=not clean)
      File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\commands\build.py", line 292, in build
        _populate_page(file.page, config, files, dirty)
      File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\commands\build.py", line 174, in _populate_page
        page.render(config, files)
      File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocs\structure\pages.py", line 175, in render
        self.content = md.convert(self.markdown)
      File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\core.py", line 264, in convert
        root = self.parser.parseDocument(self.lines).getroot()
      File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\blockparser.py", line 90, in parseDocument
        self.parseChunk(self.root, '\n'.join(lines))
      File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\blockparser.py", line 105, in parseChunk
        self.parseBlocks(parent, text.split('\n\n'))
      File "C:\Users\lameg\miniforge3\lib\site-packages\markdown\blockparser.py", line 123, in parseBlocks
        if processor.run(parent, blocks) is not False:
      File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocstrings\extension.py", line 121, in run
        html, handler, data = self._process_block(identifier, block, heading_level)
      File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocstrings\extension.py", line 209, in _process_block
        rendered = handler.render(data, options)
      File "C:\Users\lameg\miniforge3\lib\site-packages\mkdocstrings_handlers\python\handler.py", line 215, in render
        template = self.env.get_template(f"{data.kind.value}.html")
      File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\environment.py", line 1010, in get_template
        return self._load_template(name, globals)
      File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\environment.py", line 969, in _load_template
        template = self.loader.load(self, name, self.make_globals(globals))
      File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\loaders.py", line 126, in load
        source, filename, uptodate = self.get_source(environment, name)
      File "C:\Users\lameg\miniforge3\lib\site-packages\jinja2\loaders.py", line 218, in get_source
        raise TemplateNotFound(template)
    jinja2.exceptions.TemplateNotFound: alias.html
    

    To Reproduce Steps to reproduce the behavior:

    git clone [email protected]:joaompinto/kubekind.git
    cd kubekind
    pip install mkdocs mkdocstrings mkdocstrings[python]
    mkdocs build
    

    Expected behavior A clear and concise description of what you expected to happen.

    Information (please complete the following information):

    • OS: Windows 10
    • mkdocstrings 0.19.0
    bug 
    opened by joaompinto 33
  • Circular dependency with `mkdocstrings-python-legacy`

    Circular dependency with `mkdocstrings-python-legacy`

    First off, great work on this project.

    We recently converted our API docs at https://docs.ibis-project.org over to mkdocstrings and are extremely happy with the results, so thank you for all the work that you do here.

    Describe the bug

    We are using poetry2nix to manage dependencies for development environments.

    poetry2nix will turn poetry.lock into nix expressions each of which maps to a single Python package.

    To do this, poetry2nix will traverse the transitive closure of the set of dependencies specified in poetry.lock. However, it is unable to do so when a project has mkdocstrings==0.18 as a dependency because mkdocstrings 0.18 depends on mkdocstrings-python-legacy which itself depends on mkdocstrings 0.18, resulting in infinite recursion.

    To Reproduce Steps to reproduce the behavior:

    1. Install nix
    2. Download the files in this gist into a directory
    3. Run nix build

    Expected behavior

    I expect this to work with poetry2nix without infinite recursion.

    Information (please complete the following information):

    • OS: NixOS
    • Browser: Brave
    • mkdocstrings version: 0.18.0
    packaging 
    opened by cpcloud 21
  • TOC broken when selecting non-modules

    TOC broken when selecting non-modules

    # API
    
    -----
    
    ::: datadog_checks.base.AgentCheck
        selection:
          members:
            - gauge
            - count
            - monotonic_count
            - rate
            - histogram
            - historate
            - service_check
            - event
    
    ::: datadog_checks.base.stubs.aggregator.AggregatorStub
        selection:
          members:
            - assert_metric
            - assert_metric_has_tag
            - assert_metric_has_tag_prefix
            - assert_service_check
            - assert_event
            - assert_all_metrics_covered
            - assert_no_duplicate_metrics
            - assert_no_duplicate_service_checks
            - assert_no_duplicate_all
            - reset
    
    ::: datadog_checks.base.stubs.datadog_agent.DatadogAgentStub
    

    Capture

    bug rendering templates:python/material 
    opened by ofek 21
  • Formatting of function signature

    Formatting of function signature

    Is your feature request related to a problem? Please describe. Currently using the library to do a bunch of API documentation. Overall, it's been great, but I wondered if we could do anything about the function signature. As it stands, it takes one line and wraps if necessary, but I was hoping for an option to format it more like how black formats functions when they're too long for one line. For example, if I have

    def my_function(*, argument1: List[int], argument2: List[int], argument3: List[int], argument4: List[int]):
    

    I might want it formatted like this in mkdocstrings:

    my_function(
        *, 
        argument1: List[int],
        argument2: List[int],
        argument3: List[int], 
        argument4: List[int]
    ):
    

    (I know, for now, the types aren't in the signature, but this might make it more readable). Along with this, I wondered if we could add functionality to make functions expandable. Thus, with the correct setup, I could see a list of all function calls, and click on one of them to expand the documentation about that function call. Would love to hear your thoughts @pawamoy, and as always, more than happy to contribute to a solution.

    feature help wanted rendering 
    opened by rossmechanic 20
  • Documentation broken for an unknown reason.

    Documentation broken for an unknown reason.

    Describe the bug The documentation is not building if I use mkdocstrings.

    To Reproduce

    1. git clone [email protected]:kunguz/odak.git
    2. cd odak
    3. mkdocs serve

    Expected behavior A running mkdocs server, which was the case until a week or a two ago, I haven't changed anything in the meantime. But various updates took place to mkdocstrings and mkdocs-material in the meantime. I can't interpret the issue from the terminal output. If I remove mkdocstrings related lines from my MD files, things works. If I revert to an older version of mkdocstrings things also work. Everything runs perfectly if I revert to an old version, specifically mkdocs-material==8.1.0 and mkdocstrings==0.17.0 with pytkdocs[numpy-style] support.

    Information

    • Ubuntu 22.04 LTS
    • Browser: Firefox 101.0 (64-bit)
    • mkdocstrings[python] version: 0.19.0
    • mkdocs version: 1.3.0

    Additional context

    $  mkdocs serve > output.txt
    INFO     -  Building documentation...
    INFO     -  Cleaning site directory
    INFO     -  The following pages exist in the docs directory, but are not included in the "nav" configuration:
      - notes/holographic_light_transport.md
      - notes/optimizing_holograms_using_odak.md
      - notes/using_metameric_loss.md
      - odak/beginning.md
      - odak/installation.md
      - odak/learn/perception/blur_loss.md
      - odak/learn/perception/make_3d_location_map.md
      - odak/learn/perception/make_eccentricity_distance_maps.md
      - odak/learn/perception/make_pooling_size_map_lod.md
      - odak/learn/perception/make_pooling_size_map_pixels.md
      - odak/learn/perception/make_radial_map.md
      - odak/learn/perception/metamer_mse_loss.md
      - odak/learn/perception/metameric_loss.md
      - odak/learn/perception/metameric_loss_uniform.md
      - odak/learn/perception/radially_varying_blur.md
      - odak/learn/perception/rgb_2_ycrcb.md
      - odak/learn/perception/spatial_steerable_pyramid.md
      - odak/learn/perception/ycrcb_2_rgb.md
      - odak/learn/wave/adjust_phase_only_slm_range.md
      - odak/learn/wave/band_limited_angular_spectrum.md
      - odak/learn/wave/calculate_amplitude.md
      - odak/learn/wave/calculate_phase.md
      - odak/learn/wave/custom.md
      - odak/learn/wave/generate_complex_field.md
      - odak/learn/wave/gerchberg_saxton.md
      - odak/learn/wave/gradient_descent.md
      - odak/learn/wave/impulse_response_fresnel.md
      - odak/learn/wave/linear_grating.md
      - odak/learn/wave/phase_gradient.md
      - odak/learn/wave/point_wise.md
      - odak/learn/wave/prism_phase_function.md
      - odak/learn/wave/produce_phase_only_slm_pattern.md
      - odak/learn/wave/propagate_beam.md
      - odak/learn/wave/quadratic_phase_function.md
      - odak/learn/wave/set_amplitude.md
      - odak/learn/wave/shift_w_double_phase.md
      - odak/learn/wave/speckle_contrast.md
      - odak/learn/wave/stochastic_gradient_descent.md
      - odak/learn/wave/transfer_function_kernel.md
      - odak/learn/wave/wavenumber.md
      - odak/tools/check_directory.md
      - odak/tools/convert_bytes.md
      - odak/tools/list_files.md
      - odak/tools/load_dictionary.md
      - odak/tools/load_image.md
      - odak/tools/resize_image.md
      - odak/tools/save_dictionary.md
      - odak/tools/save_image.md
      - odak/tools/shell_command.md
      - odak/tools/size_of_a_file.md
      - odak/wave/adaptive_sampling_angular_spectrum.md
      - odak/wave/add_phase.md
      - odak/wave/add_random_phase.md
      - odak/wave/adjust_phase_only_slm_range.md
      - odak/wave/angular_spectrum.md
      - odak/wave/band_extended_angular_spectrum.md
      - odak/wave/band_limited_angular_spectrum.md
      - odak/wave/calculate_amplitude.md
      - odak/wave/calculate_intensity.md
      - odak/wave/calculate_phase.md
      - odak/wave/double_convergence.md
      - odak/wave/electric_field_per_plane_wave.md
      - odak/wave/fraunhofer.md
      - odak/wave/fraunhofer_equal_size_adjust.md
      - odak/wave/fraunhofer_inverse.md
      - odak/wave/generate_complex_field.md
      - odak/wave/gerchberg_saxton.md
      - odak/wave/gerchberg_saxton_3d.md
      - odak/wave/impulse_response_fresnel.md
      - odak/wave/linear_grating.md
      - odak/wave/prism_phase_function.md
      - odak/wave/produce_phase_only_slm_pattern.md
      - odak/wave/propagate_beam.md
      - odak/wave/propagate_field.md
      - odak/wave/propagate_plane_waves.md
      - odak/wave/quadratic_phase_function.md
      - odak/wave/rayleigh_resolution.md
      - odak/wave/rayleigh_sommerfeld.md
      - odak/wave/rotationspeed.md
      - odak/wave/set_amplitude.md
      - odak/wave/transfer_function_kernel.md
      - odak/wave/wavenumber.md
    ERROR    -  Error reading page 'odak/learn/perception/blur_loss.md': '<' not supported between instances of 'NoneType' and 'int'
    Traceback (most recent call last):
      File "/home/kaan/.local/bin/mkdocs", line 8, in <module>
        sys.exit(cli())
      File "/usr/lib/python3/dist-packages/click/core.py", line 1128, in __call__
        return self.main(*args, **kwargs)
      File "/usr/lib/python3/dist-packages/click/core.py", line 1053, in main
        rv = self.invoke(ctx)
      File "/usr/lib/python3/dist-packages/click/core.py", line 1659, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/usr/lib/python3/dist-packages/click/core.py", line 1395, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/usr/lib/python3/dist-packages/click/core.py", line 754, in invoke
        return __callback(*args, **kwargs)
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocs/__main__.py", line 181, in serve_command
        serve.serve(dev_addr=dev_addr, livereload=livereload, watch=watch, **kwargs)
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocs/commands/serve.py", line 63, in serve
        config = builder()
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocs/commands/serve.py", line 58, in builder
        build(config, live_server=live_server, dirty=dirty)
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocs/commands/build.py", line 292, in build
        _populate_page(file.page, config, files, dirty)
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocs/commands/build.py", line 174, in _populate_page
        page.render(config, files)
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocs/structure/pages.py", line 175, in render
        self.content = md.convert(self.markdown)
      File "/usr/lib/python3/dist-packages/markdown/core.py", line 264, in convert
        root = self.parser.parseDocument(self.lines).getroot()
      File "/usr/lib/python3/dist-packages/markdown/blockparser.py", line 90, in parseDocument
        self.parseChunk(self.root, '\n'.join(lines))
      File "/usr/lib/python3/dist-packages/markdown/blockparser.py", line 105, in parseChunk
        self.parseBlocks(parent, text.split('\n\n'))
      File "/usr/lib/python3/dist-packages/markdown/blockparser.py", line 123, in parseBlocks
        if processor.run(parent, blocks) is not False:
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocstrings/extension.py", line 121, in run
        html, handler, data = self._process_block(identifier, block, heading_level)
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocstrings/extension.py", line 195, in _process_block
        data: CollectorItem = handler.collect(identifier, options)
      File "/home/kaan/.local/lib/python3.10/site-packages/mkdocstrings_handlers/python/handler.py", line 195, in collect
        unresolved, iterations = loader.resolve_aliases(only_exported=True, only_known_modules=True)
      File "/home/kaan/.local/lib/python3.10/site-packages/griffe/loader.py", line 179, in resolve_aliases
        self.expand_wildcards(wildcards_module)
      File "/home/kaan/.local/lib/python3.10/site-packages/griffe/loader.py", line 254, in expand_wildcards
        self.expand_wildcards(member, only_known_modules, seen)  # type: ignore[arg-type]
      File "/home/kaan/.local/lib/python3.10/site-packages/griffe/loader.py", line 260, in expand_wildcards
        if new_member.name not in obj.members or obj[new_member.name].lineno < alias_lineno:
    TypeError: '<' not supported between instances of 'NoneType' and 'int'
    
    bug collector:griffe 
    opened by kaanaksit 19
  • Is there a way to parse docstrings in Cython (.pyx) files ?

    Is there a way to parse docstrings in Cython (.pyx) files ?

    I have a Cython module that I can import this way : import cython_module. Its source code is in a cython_module.pyx file, at the same level of other .py files that already work well with mkdocstrings:

    .
    ├── cython_module.pyx
    ├── predict.py
    ├── setup.py
    └── etc
    

    This cython module contains a class with a docstring:

    cdef class Model:
        """
        This is the lower-level class used for inference, it stores the model in an optimized way and features a predict method.
    
        Attributes:
            trees : The array of trees composing the model.
            nb_trees : The number of trees in the model.
        """
    
        cdef Tree* trees
        cdef uint16_t nb_trees
    

    When specifying a ::: cython_module in one of the .md files, I get this warning: WARNING - mkdocstrings.handlers.python: Couldn't read source for 'cython_module': source code not available, and in the generated doc, the only thing showed after "cython_module" is the class name ("Model"), but no docstring, nor attributes.

    Is there a way to generate documentation from docstrings in Cython files/modules ?

    Thanks!

    question 
    opened by farjasju 17
  • Dataclasses

    Dataclasses

    @pawamoy at this point I'm going to be your top issue contributer!

    I'm starting to document some of the dataclasses we use, and was hoping for a way to easily specify a dataclass and have the docs show an optional docstring with each of the parameters of the dataclass. At the moment, it just shows the unformatted repr of the dataclass. Any ideas here?

    unconfirmed collector:pytkdocs 
    opened by rossmechanic 17
  • Allow the explicit selection of members

    Allow the explicit selection of members

    Often, you'll only want to document a subset of methods & attributes. For example: https://raw.githubusercontent.com/DataDog/integrations-core/hack-a-doc/docs/developer/base/api.md

    Is that possible currently? If so, we'll switch to this from mkautodoc 😄

    cc @pawamoy

    feature configuration 
    opened by ofek 17
  • Is there any way to skip creating the markdown files and nav manually ?

    Is there any way to skip creating the markdown files and nav manually ?

    mkdocstrings supports the injection as said in docs,

    ::: my_library.my_module.my_class
    

    I also have to create the navigation.

    This is great because it gives precise control, but is there any existing way to completely generate all the pages with sane defaults?

    Like each module's docs in separate page. And links to sub or super module. Something like pdoc3 but using the material theme.

    Many thanks for your help

    question 
    opened by aahnik 16
  • Strange error

    Strange error

    Getting this:

    ERROR   -  Error reading page 'libraries/filehandlers/api.md': list index out of range 
    Traceback (most recent call last):
      File "/workspace/.pip-modules/bin/mkdocs", line 8, in <module>
        sys.exit(cli())
      File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 764, in __call__
        return self.main(*args, **kwargs)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 717, in main
        rv = self.invoke(ctx)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 956, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/click/core.py", line 555, in invoke
        return callback(*args, **kwargs)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/__main__.py", line 134, in serve_command
        livereload=livereload
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 119, in serve
        config = builder()
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 114, in builder
        build(config, live_server=live_server, dirty=dirty)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/build.py", line 274, in build
        _populate_page(file.page, config, files, dirty)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/build.py", line 181, in _populate_page
        'page_content', page.content, page=page, config=config, files=files
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/plugins.py", line 94, in run_event
        result = method(item, **kwargs)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/plugin.py", line 138, in on_page_content
        modified_lines[i] = "\n".join(renderer.render(root_object, heading))
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 27, in render
        self.render_object(obj, heading_level, lines)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 59, in render_object
        self.render_categories(obj, heading_level + 1, lines)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 80, in render_categories
        self.render_object(method, heading_level + extra_level, lines)
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/renderer.py", line 50, in render_object
        lines.append(f'\n??? note "Show source code in {obj.relative_file_path}"')
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocstrings/documenter.py", line 190, in relative_file_path
        while path_parts[-1] != file_path_parts[-1]:
    IndexError: list index out of range
    
    bug 
    opened by RDIL 15
  • How to add path for a module

    How to add path for a module

    I think this is a fairly simple question but I haven't been able to solve it. If I have my python package in a different directory than my docs folder, how do I tell mkdocstrings to look at where the python package is?

    I'm currently using the below in my .yaml file

    plugins:
        - mkdocstrings:
            handlers:
                python:
                    setup_commands:
                        - import sys
                        - sys.path.append('../')
    
    question 
    opened by sidhomj 14
  • Expose Config to enable handling non-css files during collection or render

    Expose Config to enable handling non-css files during collection or render

    Like everyone great tool that I use to document my python code. I've been playing around with a custom handler based off your template handler to document some internal file formats/code that are not python and have a few questions.

    I am using another tool to generate some image diagrams. Doing that in the render() method makes mkdocs serve go into an infinite loop after you click a page since it sees a file change in the docs_dir, regenerates, sees lots of image files change again then loops. I can do a few things but are looking to your suggestion on the best or if I have missed an easier path.

    Use mkdocs serve --dirtyreload [Current Solution]

    Not great since an update to that file doesn't necessarily trigger updating these diagrams since they are different files. So while I'm not infinitely looping, I'm not rendering the latest and greatest when serving. Build works as expected.

    Use a similar recipe to automatic code pages with mkdocs-gen-files. [Rejected]

    Since this doesn't know what identifiers will be collected, I have to generate a lot of images that may never be used. I also have no guarantees when rendering that the file actually exists since I don't know the site_dir at the handler scope.

    mkdocstrings change to expose mkdocs config to handler

    Currently, it looks like the configuration is stripped down before passing to the handler. A potential solution to give me access to the mkdocs configuration object and ultimate configurability by passing that to the handler? This could allow collect(), render(), and teardown() have some knowledge about the current mkdocs configuration including where the site_dir is to copy these files directly into it. Looking at the python and crystal handlers, neither use site_name.

    plugin.py:168

            extension_config = {
                "site_name": config["site_name"],  # Change this to "mkdocs_config": config,
                "config_file_path": config["config_file_path"],
                "theme_name": theme_name,
                "mdx": config["markdown_extensions"],
                "mdx_configs": config["mdx_configs"],
                "mkdocstrings": self.config,
                # "mkdocs_config": config, #  Or add as a new item to not break existing code.
            }
            self._handlers = Handlers(extension_config)
    

    mkdocstrings change to add a extra_files method during the on_env event. [Rejected]

    Just like the handler.extra_css, add an attribute to BaseHandler that is a iterable of paths to copy to where ever the site_dir may be. I can populate extra_files during rendering or collecting and if one errors out for any reason, react to it in the rendering.

    if self._handlers:
        css_content = "\n".join(handler.extra_css for handler in self.handlers.seen_handlers)
        write_file(css_content.encode("utf-8"), os.path.join(config["site_dir"], self.css_filename))
    
        for handler in self.handlers.seen_handlers:
            for filepath in handler.extra_files:
                copy_file(filepath, os.path.join(config["site_dir"])
    

    If either of these two changes are favorable, happy to open a PR as such. My preference would be exposing the mkdocs configuration but the second option has better "guard rails" for users.


      - mkdocstrings:
          handlers:
            python:
              paths: [src]
              import:
                - https://docs.python.org/3/objects.inv
                - https://mkdocstrings.github.io/objects.inv
            my_custom_handler:
              paths:
                - where to look for these files.
    
    • mkdocstrings version: 0.19.1
    question 
    opened by jdpatt 3
  • Hide class docstring

    Hide class docstring

    Hi

    Thanks for a great package!

    I am trying to create sections in the docs for a class LCA . In the example below I first document the class and it's attributes from the class docstr. Subsequently methods starting with "set", "plot" and finally the remaining public methods are documented.

    With my current approach the class docstr on LCA gets repeated in each section. Is there a way to avoid the class docstr being included e.g. options.self: no. Alternatively, is there a different pattern I could use - I would like to avoid adding and sorting all methods manually.

    Happy holidays to you all. Cheers, Jacob

    ::: src.analyses.LCA
        options: 
            members: no
    
    ## `set` methods
    
    Some general description of set methods
    
    ::: src.analyses.LCA
        options:
          show_root_heading: false
        selection: 
            filters: 
                - "^set"
    
    ## `plot` methods
    
    Some general description of plot methods
    
    ::: src.analyses.LCA
        options:
          show_root_heading: false
        selection: 
            filters: 
                - "^plot"
    
    ## Other methods
    
    ::: src.analyses.LCA
        options:
          show_root_heading: false
        selection: 
            filters:
                - "!^_"
                - "!^set"
                - "!^plot"
    
    
    feature 
    opened by mrsonne 3
  • Handle Google style docstrings for Python properties

    Handle Google style docstrings for Python properties

    Hey, thank you so much for your work on mkdocstrings!

    Currently, mkdocstrings has support for methods that have docstrings that follow the Google style, but sadly it does not have support for properties (@property) that follow the Google style for Python docstrings.

    So, currently, I have to do something like:

    class MyClass:
        # ...
        @property
        def my_int_property(self) -> int:
            """My brief description here.
    
            Returns:
                int: A typically redundant description here.
            """
    

    Ideally, I would just do something like

    class MyClass:
        # ...
        @property
        def my_int_property(self) -> int:
            """int: My brief description here."""
    

    In a perfect world, mkdocstrings would even pick up the name of the return value from the property name itself!

    feature 
    opened by rodrigogiraoserrao 3
  • Adjust license entry

    Adjust license entry

    Fixes

    , line 85, in validate_pep621
          raise PEP621ValidationError(validator.errors)
      pdm.pep517.exceptions.PEP621ValidationError: {'license': ['none or more than one rule validate', {'oneof definition 0': ['must be of dict type'], 'oneof definition 1': ['must be of dict type']}]}
    
    opened by fabaff 1
  • Feature: Type links in function signatures

    Feature: Type links in function signatures

    Apologies if I've missed this discussed elswhere

    I'm like to use show_signature_annotations. And I'm wondering if it's possible to have the types be rendered with links to their references (as they would in the docstring parameters).

    For example,

    def iter_axis(self, axis: str) -> Iterator[Union[Position, Channel, float]]:
        ...
    

    is rendered as:

    Screen Shot 2022-11-21 at 11 10 04 AM

    <code class="highlight language-python">
        <span class="n">iter_axis</span>
        <span class="p">(</span>
        <span class="n">axis</span>
        <span class="p">:</span>
        <span class="nb">str</span>
        <span class="p">)</span>
        <span class="o">-&gt;</span>
        <span class="n">Iterator</span>
        <span class="p">[</span>
        <span class="n">Union</span>
        <span class="p">[</span>
        <span class="n">Position</span>
        <span class="p">,</span>
        <span class="n">Channel</span>
        <span class="p">,</span>
        <span class="nb">float</span>
        <span class="p">]]</span>
    </code>
    

    ... and I would love it if there was an option for Position, Channel, etc... to be anchor links to their respective references.

    @pawamoy, If I haven't just missed it, and this is indeed not yet possible, I'd be willing to take a stab at an implementation if you want to give me a quick pointer to the files you would begin modifying.

    feature 
    opened by tlambert03 1
  • Allow using *relative imports* to cross-reference inside the project

    Allow using *relative imports* to cross-reference inside the project

    Is your feature request related to a problem? Please describe.

    When writing cross-references inside the project, links become a bit too verbose. For example, if we have:

    # module some.deep.nested.module_a
    class A:
        """A class.
    
        We reference [B][some.deep.nested.module_b.B].
        """
    
    class AA:
        """AA class.
    
        We reference [A][some.deep.nested.module_a.A].
        """
    
    # module some.deep.nested.module_b
    class B:
        """B class.
    
        We reference [A][some.deep.nested.module_a.A].
        """
    

    Here references can get really difficult to write. Another alternative would be to write [some.deep.nested.module_a.A][], which saves a few chars (depending on the name of the leaf symbol), but then the produced documentation becomes too verbose if we are already at the context of a some.deep.nested package.

    Describe the solution you'd like

    Allow writing local cross-references using relative imports and local symbols. In the example above:

    # module some.deep.nested.module_a
    class A:
        """A class.
    
        We reference [B][.module_b.B].
        """
    
    class AA:
        """AA class.
    
        We reference [A][].
        """
    
    # module some.deep.nested.module_b
    class B:
        """B class.
    
        We reference [.module_a.A][].
        """
    

    Describe alternatives you've considered

    Just using the fully qualified symbol as stated above.

    Additional context

    None really, just that I know it would be hard to implement :)

    feature 
    opened by leandro-lucarella-frequenz 1
Releases(0.19.0)
  • 0.19.0(May 28, 2022)

    Highlights

    We decided to deprecate a few things to pave the way towards a more stable code base, bringing us closer to a v1.

    • Selection and rendering options are now combined into a single options key. Using the old keys will emit a deprecation warning.
    • The BaseCollector and BaseRenderer classes are deprecated in favor of BaseHandler, which merges their functionality. Using the old classes will emit a deprecation warning.

    New versions of the Python handler and the legacy Python handler were also released in coordination with mkdocstrings 0.19. See their respective changelogs: python, python-legacy. Most notably, the Python handler gained the members and filters options that prevented many users to switch to it.

    mkdocstrings stopped depending directly on the legacy Python handler. It means you now have to explicitely depend on it, directly or through the extra provided by mkdocstrings, if you want to continue using it.

    Packaging / Dependencies

    • Stop depending directly on mkdocstrings-python-legacy (9055d58 by Timothée Mazzucotelli). Issue #376

    Features

    Code Refactoring

    • Support options / deprecated options mix-up (7c71f26 by Timothée Mazzucotelli).
    • Deprecate watch feature in favor of MkDocs' built-in one (c20022e by Timothée Mazzucotelli).
    • Log relative template paths if possible, instead of absolute (91f5f83 by Timothée Mazzucotelli).
    • Deprecate selection and rendering YAML keys (3335310 by Timothée Mazzucotelli). PR #420
    • Deprecate BaseCollector and BaseRenderer (eb822cb by Timothée Mazzucotelli). PR #413
    Source code(tar.gz)
    Source code(zip)
  • 0.18.0(Feb 6, 2022)

    Highlights

    • Python 3.6 support is dropped.
    • We provide a new, experimental Python handler based on Griffe. This new handler brings automatic cross-references for every annotation in your code, including references to third-party libraries' APIs if they provide objects inventories and you explicitely load them in mkdocs.yml. See migration notes in the documentation.
    • The "legacy" Python handler now lives in its own repository at https://github.com/mkdocstrings/python-legacy.

    Packaging / Dependencies

    • Add Crystal extra, update Python extras versions (b8222b0 by Timothée Mazzucotelli). PR #374
    • Update autorefs to actually required version (fc6c7f6 by Timothée Mazzucotelli).
    • Drop Python 3.6 support (7205ac6 by Timothée Mazzucotelli).

    Features

    • Allow unwrapping the <p> tag in convert_markdown filter (5351fc8 by Oleh Prypin). PR #369
    • Support handlers spanning multiple locations (f42dfc6 by Timothée Mazzucotelli). PR #355

    Code Refactoring

    • Prefix logs with the package name only (6c2b734 by Timothée Mazzucotelli). PR #375
    • Extract the Python handler into its own repository (74371e4 by Timothée Mazzucotelli). PR #356
    • Support Jinja2 3.1 (b377227 by Timothée Mazzucotelli). Issue #360, PR #361
    • Find templates in new and deprecated namespaces (d5d5f18 by Timothée Mazzucotelli). PR #367
    • Support loading handlers from the mkdocstrings_handlers namespace (5c22c6c by Timothée Mazzucotelli). PR #367
    Source code(tar.gz)
    Source code(zip)
  • 0.17.0(Jan 15, 2022)

    0.17.0 - 2021-12-27

    Compare with 0.16.2

    Features

    Bug Fixes

    • Do minimum work when falling back to re-collecting an object to get its anchor (f6cf570 by Timothée Mazzucotelli). Issue #329, PR #330

    Code Refactoring

    Source code(tar.gz)
    Source code(zip)
  • 0.16.0(Sep 21, 2021)

    Features

    Bug Fixes

    • Don't render empty code blocks for missing type annotations (d2e9e1e by Oleh Prypin).
    • Fix custom handler not being used (6dcf342 by Timothée Mazzucotelli). Issue #259, PR #263
    • Don't hide setup_commands errors (92418c4 by Gabriel Vîjială). PR #258

    Code Refactoring

    • Move writing extra files to an earlier stage in the build (3890ab5 by Oleh Prypin). PR #275
    Source code(tar.gz)
    Source code(zip)
Owner
Timothée Mazzucotelli
I think I just like to create.
Timothée Mazzucotelli
Some custom tweaks to the results produced by pytkdocs.

pytkdocs_tweaks Some custom tweaks for pytkdocs. For use as part of the documentation-generation-for-Python stack that comprises mkdocs, mkdocs-materi

Patrick Kidger 4 Nov 24, 2022
sphinx builder that outputs markdown files.

sphinx-markdown-builder sphinx builder that outputs markdown files Please ★ this repo if you found it useful ★ ★ ★ If you want frontmatter support ple

Clay Risser 144 Jan 06, 2023
MonsterManualPlus - An advanced monster manual for Tower of the Sorcerer.

Monster Manual + This is an advanced monster manual for Tower of the Sorcerer mods. Users can get a plenty of extra imformation for decision making wh

Yifan Zhou 1 Jan 01, 2022
the project for the most brutal and effective language learning technique

- "The project for the most brutal and effective language learning technique" (c) Alex Kay The langflow project was created especially for language le

Alexander Kaigorodov 7 Dec 26, 2021
Rust Markdown Parsing Benchmarks

Rust Markdown Parsing Benchmarks This repo tries to assess Rust markdown parsing

Ed Page 1 Aug 24, 2022
Lightweight, configurable Sphinx theme. Now the Sphinx default!

What is Alabaster? Alabaster is a visually (c)lean, responsive, configurable theme for the Sphinx documentation system. It is Python 2+3 compatible. I

Jeff Forcier 670 Dec 19, 2022
A simple malware that tries to explain the logic of computer viruses with Python.

Simple-Virus-With-Python A simple malware that tries to explain the logic of computer viruses with Python. What Is The Virus ? Computer viruses are ma

Xrypt0 6 Nov 18, 2022
Parser manager for parsing DOC, DOCX, PDF or HTML files

Parser manager Description Parser gets PDF, DOC, DOCX or HTML file via API and saves parsed data to the database. Implemented in Ruby 3.0.1 using Acti

Эдем 4 Dec 04, 2021
The purpose of this project is to share knowledge on how awesome Streamlit is and can be

Awesome Streamlit The fastest way to build Awesome Tools and Apps! Powered by Python! The purpose of this project is to share knowledge on how Awesome

Marc Skov Madsen 1.5k Jan 07, 2023
Members: Thomas Longuevergne Program: Network Security Course: 1DV501 Date of submission: 2021-11-02

Mini-project report Members: Thomas Longuevergne Program: Network Security Course: 1DV501 Date of submission: 2021-11-02 Introduction This project was

1 Nov 08, 2021
A python package to import files from an adjacent folder

EasyImports About EasyImports is a python package that allows users to easily access and import files from sister folders: f.ex: - Project - Folde

1 Jun 22, 2022
Main repository for the Sphinx documentation builder

Sphinx Sphinx is a tool that makes it easy to create intelligent and beautiful documentation for Python projects (or other documents consisting of mul

5.1k Jan 02, 2023
A course-planning, course-map rendering and GPA-calculation web service, designed for the SFU (Simon Fraser University) student.

SFU Course Planner What is the overall goal of the project (i.e. what does it do, or what problem is it solving)? As the title suggests, this project

Ash Peng 1 Oct 21, 2021
30 days of Python programming challenge is a step-by-step guide to learn the Python programming language in 30 days

30 days of Python programming challenge is a step-by-step guide to learn the Python programming language in 30 days. This challenge may take more than100 days, follow your own pace.

Asabeneh 17.7k Jan 07, 2023
Code and pre-trained models for "ReasonBert: Pre-trained to Reason with Distant Supervision", EMNLP'2021

ReasonBERT Code and pre-trained models for ReasonBert: Pre-trained to Reason with Distant Supervision, EMNLP'2021 Pretrained Models The pretrained mod

SunLab-OSU 29 Dec 19, 2022
An open-source script written in python just for fun

Owersite Owersite is an open-source script written in python just for fun. It do

大きなペニスを持つ少年 7 Sep 21, 2022
Portfolio project for Code Institute Full Stack software development course.

Comic Sales tracker This project is the third milestone project for the Code Institute Diploma in Full Stack Software Development. You can see the fin

1 Jan 10, 2022
A document format conversion service based on Pandoc.

reformed Document format conversion service based on Pandoc. Usage The API specification for the Reformed server is as follows: GET /api/v1/formats: L

David Lougheed 3 Jul 18, 2022
Generate a backend and frontend stack using Python and json-ld, including interactive API documentation.

d4 - Base Project Generator Generate a backend and frontend stack using Python and json-ld, including interactive API documentation. d4? What is d4 fo

Markus Leist 3 May 03, 2022
Documentation and issues for Pylance - Fast, feature-rich language support for Python

Documentation and issues for Pylance - Fast, feature-rich language support for Python

Microsoft 1.5k Dec 29, 2022