daizutabi / mkapi Goto Github PK
View Code? Open in Web Editor NEWA plugin for MkDocs to generate API documentation
Home Page: https://daizutabi.github.io/mkapi/
License: MIT License
A plugin for MkDocs to generate API documentation
Home Page: https://daizutabi.github.io/mkapi/
License: MIT License
I have installed mkapi
via pip
.
I am trying to use page mode
as per the documentation.
My mkdocs.yml
has
# multiple lines not here for brevity
nav:
- API: mkapi/api/wappdriver
plugins:
- mkapi:
src_dirs: ['wappdriver']
Here wappdriver is the name of my package.
The directory structure is like:
- mkdocs.yml
- setup.py
- wappdriver
- __init__.py
- module.py
- docs
- index.md
When I run mkdocs serve
I get the following error
INFO - Building documentation...
Traceback (most recent call last):
File "/home/linuxbrew/.linuxbrew/bin/mkdocs", line 8, in <module>
sys.exit(cli())
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/__main__.py", line 133, in serve_command
serve.serve(
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 141, in serve
config = builder()
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 136, in builder
build(config, live_server=live_server, dirty=dirty)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/commands/build.py", line 236, in build
config = config['plugins'].run_event('config', config)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkdocs/plugins.py", line 94, in run_event
result = method(item, **kwargs)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/plugins/mkdocs.py", line 50, in on_config
config, self.abs_api_paths = mkapi.plugins.api.create_nav(
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/plugins/api.py", line 23, in create_nav
page[key], abs_api_paths_ = collect(
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/plugins/api.py", line 47, in collect
module = get_module(package_path)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/core/module.py", line 96, in get_module
obj = get_object(name)
File "/home/linuxbrew/.linuxbrew/opt/[email protected]/lib/python3.9/site-packages/mkapi/core/object.py", line 39, in get_object
raise ValueError(f"Could not find object: {name}")
ValueError: Could not find object: wappdriver
Is my way of usage of page mode incorrect ? Could you please guide if so.
Many thanks for reading. Your help is most appreciated.
Tuple
supports an undefined number of entries with ...
but an exception gets thrown when processing ...
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 270, in get_attributes
return get_class_attributes(obj)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 186, in get_class_attributes
attr_lineno = get_attributes_with_lineno(nodes, module)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 121, in get_attributes_with_lineno
attr, lineno, type_str = parse_annotation_assign(x)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 61, in parse_annotation_assign
type = parse_node(assign.annotation)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 47, in parse_node
return parse_subscript(x)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/attribute.py", line 27, in parse_subscript
slice = ", ".join(slice)
TypeError: sequence item 1: expected str instance, ellipsis found
In
def parse_subscript(x) -> str:
value = parse_node(x.value)
slice = parse_node(x.slice.value)
if isinstance(slice, str):
return f"{value}[{slice}]"
else:
slice = ", ".join(slice)
return f"{value}[{slice}]"
I am using mkapi in Page mode to build an API reference for my package, which looks like this:
Using the material theme, this is also completely unreadable as the entries get cropped at the important information.
So I was wondering if there is already a feature similar to the |short
filter for headlines that can be applied to the navigation items, so that it strips the root package name (in my case tgintegration
) from all nav items...
I can't help but think that the following function is actually responsible for doing this, so maybe I'm running into a bug or haven't turned on a feature that I missed in the docs:
Lines 146 to 151 in 6e0cf8f
Is there a way to interject the menu item generator and add this myself?
Hi,
It seems that the package distributed through pypi does not include templates
folder which produces an error in mkdocs:
(.venv) mkdocs serve
INFO - Building documentation...
[WinError 3] The system cannot find the path specified: 'c:\\users\\my.user\\devel\\rics\\pi_lib\\.venv\\lib\\site-packages\\mkapi\\templates'
I installed it via pip install mkapi
(version 0.4.0)
Placing the templates folder in the module path works like a charm.
Also, not sure if needed but the theme
folder isn't distributed either.
When running pip install mkapi:
Could not find a version that satisfies the requirement mkapi (from versions: )
No matching distribution found for mkapi
Hi,
I really like this project and how the documentation is rendered.
Is there any plan to extend this plugin to support the Numpy Doctring, as this is very commonly used?
Thanks and regards,
I'm often facing issues when my classes or functions have an ellipsis (...
).
Line 57 in 6e0cf8f
I'm not sure what's the best way to resolve this for now but wanted to raise the issue first
Hi,
First, thanks a lot for all those recent improvements in mkapi, it is impressive!
Upgrading to mkapi 0.7.6 from 0.5.0, it seems that now the inherited methods are not showing up if the base class is in a different file.
Code to reproduce:
test.py
:
from mixin_ext import MixinExt
class Mixin2:
def method_mixin2(self, c: int):
""" Doc method_mixin2 defined in same file"""
pass
class SubClass(MixinExt, Mixin2):
def __init__(self, string_a: str):
pass
def method_class(self, a: int):
""" Docstring method_class """
pass
and mixin_ext.py
:
class MixinExt:
def method_mixin_ext(self, b:int):
""" Doc method mixin defined external file"""
pass
If we then try to have ![mkapi](test.SubClass)
in the doc, it will only show:
Nothing is shown about method_mixin_ext
inherited from the MixinExt Class...
The page mode is also impacted.
It was working as expected in 0.5.0.
Thanks
Versions:
python 3.8.0
mkapi 1.0.14
mkdocs 1.1.2
Issue:
(django-admin-confirm-3.8.0) thu@Thus-MBP django-admin-confirm % python -m mkdocs build
Module('admin_confirm.admin', num_sections=0, num_members=2)
INFO - Cleaning site directory
INFO - Building documentation to directory: /Users/thu/code/django-admin-confirm/site
INFO - The following pages exist in the docs directory, but are not included in the "nav" configuration:
- api/admin_confirm.admin.md
- api/source/admin_confirm.admin.md
[I 210225 09:25:58 watcher:110] Running task: builder (delay: None)
INFO - Running task: builder (delay: None)
INFO - Building documentation...
ERROR - Config value: 'plugins'. Error: The "mkapi" plugin is not installed
It also had issues with when nav
was not listed in the yml.
This is my config:
site_name: My Docs
theme: readthedocs
plugins:
- search
- mkapi
nav:
- index.md
- API: mkapi/api/admin_confirm
If I just do build it sometimes kinda works (doesn't add nav correctly):
python -m mkdocs build
Module('admin_confirm.admin', num_sections=0, num_members=2)
INFO - Cleaning site directory
INFO - Building documentation to directory: /Users/thu/code/django-admin-confirm/site
INFO - The following pages exist in the docs directory, but are not included in the "nav" configuration:
- api/admin_confirm.admin.md
- api/source/admin_confirm.admin.md
INFO - Documentation built in 0.75 seconds
But serve has the same problem as above.
mkapi can crash for some specific classes on document generation.
Exception gets thrown in core/docstring.py:194 and core/object.py:133:
ERROR - Error reading page 'api\prettyqt.custom_widgets.promptlineedit.md': descriptor 'mro' of 'type' object needs an argument Traceback (most recent call last): File "c:\python37\lib\runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "c:\python37\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "C:\Python37\Scripts\mkdocs.exe\__main__.py", line 7, in <module> File "c:\python37\lib\site-packages\click\core.py", line 829, in __call__ return self.main(*args, **kwargs) File "c:\python37\lib\site-packages\click\core.py", line 782, in main rv = self.invoke(ctx) File "c:\python37\lib\site-packages\click\core.py", line 1259, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "c:\python37\lib\site-packages\click\core.py", line 1066, in invoke return ctx.invoke(self.callback, **ctx.params) File "c:\python37\lib\site-packages\click\core.py", line 610, in invoke return callback(*args, **kwargs) File "c:\python37\lib\site-packages\mkdocs\__main__.py", line 152, in build_command build.build(config.load_config(**kwargs), dirty=not clean) File "c:\python37\lib\site-packages\mkdocs\commands\build.py", line 271, in build _populate_page(file.page, config, files, dirty) File "c:\python37\lib\site-packages\mkdocs\commands\build.py", line 168, in _populate_page 'page_markdown', page.markdown, page=page, config=config, files=files File "c:\python37\lib\site-packages\mkdocs\plugins.py", line 94, in run_event result = method(item, **kwargs) File "c:\python37\lib\site-packages\mkapi\plugins\mkdocs.py", line 116, in on_page_markdown markdown, abs_src_path, self.abs_api_paths, filters=self.config["filters"] File "<string>", line 8, in __init__ File "c:\python37\lib\site-packages\mkapi\core\page.py", line 41, in __post_init__ self.markdown = "\n\n".join(self.split(source)) File "c:\python37\lib\site-packages\mkapi\core\page.py", line 75, in split inherit(node) File "c:\python37\lib\site-packages\mkapi\core\inherit.py", line 155, in inherit for base in bases: File "c:\python37\lib\site-packages\mkapi\core\inherit.py", line 130, in <genexpr> yield node, (get_node(base) for base in bases) File "c:\python37\lib\site-packages\mkapi\core\node.py", line 234, in get_node return Node(obj, sourcefile_index) File "<string>", line 5, in __init__ File "c:\python37\lib\site-packages\mkapi\core\node.py", line 31, in __post_init__ super().__post_init__() File "c:\python37\lib\site-packages\mkapi\core\structure.py", line 106, in __post_init__ self.members = self.get_members() File "c:\python37\lib\site-packages\mkapi\core\node.py", line 82, in get_members return get_members(self.obj) File "c:\python37\lib\site-packages\mkapi\core\node.py", line 214, in get_members member = get_node(obj, sourcefile_index) File "c:\python37\lib\site-packages\mkapi\core\node.py", line 234, in get_node return Node(obj, sourcefile_index) File "<string>", line 5, in __init__ File "c:\python37\lib\site-packages\mkapi\core\node.py", line 31, in __post_init__ super().__post_init__() File "c:\python37\lib\site-packages\mkapi\core\structure.py", line 104, in __post_init__ self.docstring = get_docstring(obj) File "c:\python37\lib\site-packages\mkapi\core\docstring.py", line 294, in get_docstring postprocess(docstring, obj) File "c:\python37\lib\site-packages\mkapi\core\docstring.py", line 236, in postprocess parse_bases(doc, obj) File "c:\python37\lib\site-packages\mkapi\core\docstring.py", line 194, in parse_bases objs = obj.mro()[1:-1] TypeError: descriptor 'mro' of 'type' object needs an argument
Can fix that by replacing the line with:
try:
objs = obj.mro()[1:-1]
except TypeError:
objs = obj.mro(type)[1:-1]
but not sure if that is the best fix.
For me it happened for a class inherited from QtCharts.QAbstractSeries (https://pypi.org/project/PyQtChart/)
This here might be a similar issue, from another project:
https://github.com/agronholm/sphinx-autodoc-typehints/issues/73
It would be nice to have the option to use different themes in mkdocs.
My suggestion: read the theme entry from mkdocs.yml
and choose the corresponding theme from mkapi/theme folder. If the theme is not available than use the default one.
Additionally i would like to have two options for the plugin:
Currently i am adding a custom css file to overwrite the theme to match the readthedocs-style, but this isn't ideal.
mkapi does not seem to detect classmethods in my setup.
Simplified example:
from abc import ABCMeta, abstractmethod
import json
class Base(object, metaclass=ABCMeta):
@abstractmethod
def __init__(self, some_arg):
"""[summary]
Args:
some_arg ([type]): [description]
Raises:
NotImplementedError: [description]
"""
raise NotImplementedError()
@classmethod
def from_json(cls, json_string):
"""[summary]
Args:
json_string ([type]): [description]
Raises:
NotImplementedError: [description]
"""
raise NotImplementedError()
def to_json(self):
"""[summary]
"""
return json.dumps(self.data)
class Child(Base):
def __init__(self, some_arg):
"""[summary]
Args:
some_arg ([type]): [description]
"""
self.some_arg = some_arg
self.data = None
@classmethod
def from_json(cls, json_string):
"""[summary]
Args:
json_string ([type]): [description]
"""
child = cls()
child.data = json.loads(json_string)
return child
This should render docs for both classes where they both have from_json
and to_json
. Instead the classmethod from_json
is missing from both.
EDIT: when removing the metaclass=ABCMeta
from the baseclass the classmethods pop up. Is this described behaviour?
Steps to pre-produce
edit mkdocs.yml to look like
site_name: My Docs
plugins:
- search
- mkapi
Then issue mkdocs serve
Expected behavior:
Mkdocs will serve the default mkdocs website on 127.0.0.1:8000
Actual behavior
<snip>
File "/home/daniel/Repositories/binance-asyncio/.env/lib/python3.9/site-packages/mkapi/plugins/api.py", line 19, in create_nav
for page in nav:
TypeError: 'NoneType' object is not iterable
Note
If i change mkdocs.yml to
site_name: My Docs
plugins:
- search
all is good. generates, Mkdocs will serve the default mkdocs website on 127.0.0.1:8000 as expected
my mkdocs.yml:
site_name: Omicron
nav:
- Home: index.md
- History: history.md
theme: readthedocs
markdown_extensions:
- admonition
plugins:
- mkapi:
src_dirs: [omicron]
have tried python -c import omicron
without error.
The error raised (by command mkdocs serve -v -a 0.0.0.0:8000
):
DEBUG - Config value: 'markdown_extensions' = ['toc', 'tables', 'fenced_code', 'admonition']
DEBUG - Config value: 'mdx_configs' = None
DEBUG - Config value: 'strict' = False
DEBUG - Config value: 'remote_branch' = 'gh-pages'
DEBUG - Config value: 'remote_name' = 'origin'
DEBUG - Config value: 'extra' = {}
DEBUG - Config value: 'plugins' = [{'mkapi': None, 'src_dirs': ['omicron']}]
Aborted with 1 Configuration Errors!
``
Hi,
I'm trying to use your mkdocs plugin for a project and I get the following error:
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/node.py", line 101, in get_kind
if hasattr(obj, "__dataclass_fields__") and hasattr(obj, "__qualname__"):
KeyError: '__dataclass_fields__'
(venv38) ~/Git/plato-common-egse/MKDOCS (develop)> mkdocs build
Traceback (most recent call last):
File "/Users/rik/Git/plato-common-egse/venv38/bin/mkdocs", line 8, in <module>
sys.exit(cli())
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkdocs/__main__.py", line 152, in build_command
build.build(config.load_config(**kwargs), dirty=not clean)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkdocs/commands/build.py", line 236, in build
config = config['plugins'].run_event('config', config)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkdocs/plugins.py", line 94, in run_event
result = method(item, **kwargs)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/plugins/mkdocs.py", line 47, in on_config
config, self.abs_api_paths = mkapi.plugins.api.create_nav(config)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/plugins/api.py", line 23, in create_nav
page[key], abs_api_paths_ = collect(value, docs_dir, config_dir)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/plugins/api.py", line 43, in collect
module = get_module(package_path)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
return Module(obj)
File "<string>", line 6, in __init__
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 28, in __post_init__
super().__post_init__()
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/tree.py", line 51, in __post_init__
self.members = self.get_members()
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 51, in get_members
return get_members(self.obj)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 99, in get_members
module = get_module(name)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
return Module(obj)
File "<string>", line 6, in __init__
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 28, in __post_init__
super().__post_init__()
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/tree.py", line 51, in __post_init__
self.members = self.get_members()
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 51, in get_members
return get_members(self.obj)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 99, in get_members
module = get_module(name)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
return Module(obj)
File "<string>", line 6, in __init__
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 28, in __post_init__
super().__post_init__()
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/tree.py", line 51, in __post_init__
self.members = self.get_members()
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 51, in get_members
return get_members(self.obj)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 99, in get_members
module = get_module(name)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 115, in get_module
return Module(obj)
File "<string>", line 6, in __init__
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 30, in __post_init__
objects = get_objects(self.obj)
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/module.py", line 71, in get_objects
if not get_kind(obj):
File "/Users/rik/Git/plato-common-egse/venv38/lib/python3.8/site-packages/mkapi/core/node.py", line 101, in get_kind
if hasattr(obj, "__dataclass_fields__") and hasattr(obj, "__qualname__"):
KeyError: '__dataclass_fields__'
Given the following class:
import numpy as np
class Thing(np.ndarray):
def something(self):
return 42
Running mkapi
on this results in:
self = Section('', num_items=0), section = Section('Parameters', num_items=7), force = True
def merge(self, section: "Section", force: bool = False) -> "Section":
"""Returns a merged Section
Examples:
>>> s1 = Section('Parameters', items=[Item('a', 's'), Item('b', 'f')])
>>> s2 = Section('Parameters', items=[Item('a', 'i'), Item('c', 'd')])
>>> s3 = s1.merge(s2)
>>> s3.items
[Item('a', 's'), Item('b', 'f'), Item('c', 'd')]
>>> s3 = s1.merge(s2, force=True)
>>> s3.items
[Item('a', 'i'), Item('b', 'f'), Item('c', 'd')]
>>> s3 = s2.merge(s1)
>>> s3.items
[Item('a', 'i'), Item('c', 'd'), Item('b', 'f')]
"""
if section.name != self.name:
> raise ValueError(f"Different name: {self.name} != {section.name}.")
E ValueError: Different name: != Parameters.
mkapi/core/base.py:422: ValueError
Adding a small test case to test_core_inherit.py
reproduces this:
def test_numpy_thing():
import numpy as np
class Thing(np.ndarray):
pass
section = get_section(Node(Thing), "Parameters", "Docstring")
I tried to dig into this to see if it was a simple fix, but I can't seem to find anything. The parameters
section seems to be an empty, default section with the name ''
which I think is incorrect.
I have a file with the following code:
@pytest.fixture(scope="module")
def chart_path(pytestconfig) -> str:
"""Return a path to the chart under test (from command line argument)."""
return pytestconfig.getoption("chart_path")
mkapi
in page mode skips this. If I remove the annotation, the docstring is picked up correctly.
(Edit: Found a bug, will make a PR)
I couldn't find instructions on how set the package (sorry if I'm missing something). I am only able to generate mkdocs
itself.
Name: mkapi
Version: 1.0.12
Summary: An Auto API Documentation tool.
Home-page: https://mkapi.daizutabi.net
Author: daizutabi
Author-email: [email protected]
License: MIT
Location: /home/t/work/python/libvcs/.venv/lib/python3.7/site-packages
Requires: jinja2, markdown
Required-by:
libvcs on ๎ new-docs [โ!] โฏ python -V
Python 3.7.7
libvcs on ๎ new-docs [โ!] โฏ pip show mkdocs
Name: mkdocs
Version: 1.1.2
Summary: Project documentation with Markdown.
Home-page: https://www.mkdocs.org
Author: Tom Christie
Author-email: [email protected]
License: BSD
Location: /home/t/work/python/libvcs/.venv/lib/python3.7/site-packages
Requires: PyYAML, Jinja2, tornado, livereload, lunr, click, Markdown
Required-by: mkdocstrings, mkdocs-material
mkdocs.yml:
# mkdocs.yml
site_name: libvcs
site_url: https://libvcs.git-pull.com
repo_url: https://github.com/vcs-python/libvcs
repo_name: 'GitHub'
theme:
name: "material"
custom_dir: .
logo: assets/images/libvcs.svg
favicon: assets/images/favicon.ico
plugins:
- search
- mkapi
nav:
- index.md
- API: mkapi/api/mkapi
# - API: mkapi/api/libvcs will crash
Is it possible to link to python standard library? Intersphinx projects?
Is there a planned feature for it?
(e.g. linking to logging
)
I was trying to do:
nav:
- "About": index.md
- "Install": install.md
- "Getting Started": started.md
- "Config": config.md
- "FAQ": faq.md
- "Development":
- "Contributing": contributing/index.md
- "Architecture": contributing/architecture.md
- "API": mkapi/api/lib-python/foo
but create_nav
is not recursive, only finding docs in top level entries
def create_nav(config, global_filters):
nav = config["nav"]
docs_dir = config["docs_dir"]
config_dir = os.path.dirname(config["config_file_path"])
abs_api_paths = []
for page in nav:
if isinstance(page, dict):
for key, value in page.items():
if isinstance(value, str) and value.startswith("mkapi/"):
page[key], abs_api_paths_ = collect(
value, docs_dir, config_dir, global_filters
)
abs_api_paths.extend(abs_api_paths_)
return config, abs_api_paths
Requiring me to do
nav:
- "About": index.md
- "Install": install.md
- "Getting Started": started.md
- "Config": config.md
- "FAQ": faq.md
- "Development":
- "Contributing": contributing/index.md
- "Architecture": contributing/architecture.md
- "API": mkapi/api/lib-python/foo
Hi ,
I would like do to document a project that makes heavy use of external libraries where I don't have access to the sources. Does mkapi offer something similar to mocks in sphinxs/autodoc
autodoc_mock_imports = ["django","td"]?
Thanks in advance
It would help teams using conda to use this library if there were a conda package on conda-forge. You can pip-install into a conda environment, but that is problematic because you will get dependencies from unpredictable locations, depending on what is already installed in the environment. I have not myself tried these instructions, so I don't know how much work this is.
Thanks
Andy
Currently, linking an enum.Enum
subclass returns the definition of the main Enum
class, which is not very useful. It would be more useful if it would display the individual elements (or even just the source code).
For example, this class definition:
from enum import Enum
class EnumExample(Enum):
FOO = 'foo'
BAR = 'bar'
... linked like this:
# Enum Test
![mkapi](diffusion.datatypes.EnumExample)
... looks like this:
Say I have the following directory structure
- package_name
- module1.py
- module2.py
- docs/
- index.md
mkdocs.yml
and i have
... snip ...
plugins:
- search
- mkapi:
src_dirs: [package]
in my mkdocs.yml
. And say we have two classes, ClassFirst in module1.py and ClassSecond in module2.py, if I now add docstrings to ClassFirst and do mkdocs build
, everything works and my documentation is generated.
Actual problem
If i now where to import ClassSecond into module1.py , everything breaks. It doesn't matter if I use
from package_name.module2 import ClassSecond
or
from .module2 import ClassSecond
I import different from other modules within the same package all the time, doesn't mkapi
support this?
First of, thanks for this library. Of all the mkdocs API documentation libraries this one has worked the best so far. God knows we need something besides sphinx for making library documentation!
I ran into an issue with a function that uses a Literal
type. EG
from typing import Literal # or from typing_extensions import Literal
def some_func(method: Literal['one', 'two']) -> str:
...
will raise something like:
line 305, in to_string_args
name = annotation.__origin__.__name__.lower()
AttributeError: '_LiteralSpecialForm' object has no attribute '__name__'
I don't think it will be a hard fix and I am happy to submit a PR if it is just a simple issue of getting a str rep for Literal
.
In the docs, it says:
For Python files that contain only a single class however, adding a docstring feels kind of unnecessary and redundant. Is it possible to override this functionality and force loading files even if they have no docstring? My current workaround is to add a docstring with invisible character, which kinda works but creates too much blank space in the docs:
Lines 201 to 203 in 6e0cf8f
When some classes have improper or complicated __getattr__
implemented, this will raise some errors unexpectedly.
We should use try-except instead:
try:
obj.__wrapped__
# Do something with obj.__wrapped__
# or in else
except AttributeError:
# no __wrapped__ attribute
If a class has many ancestors, I don't all of them to be inherited. Is it possible to add configurations to limit this? or to disable inheritance?
Another possible enhancement could be to hide the init() method when displaying a class if the docstring is empty, since all parameters appear in the class header and the docstring of the class supposedly document those.
Currently a section with the init method is created with the following content :
Initialize self. See help(type(self)) for accurate signature.
even if there is no docstring
Hi @daizutabi ,
Is there any reason this package is does not support python 3.5 and 3.6? MkDocs officially still supports 3.5+ (link). My companies hadoop cluster is still running python 3.6, and I'd like to use your package there.
Any chance you'd be willing to increase support for older python versions?
Hi,
First, thanks for allowing me to make beautiful API docs so easily!!
This is more a feature suggestion and I am not sure of the internal, so I don't know if it is possible.
But could we have the option to add the main nodes to the toc?
So If I use ![mkapi](package.module.Class)
, then that would also add the Class methods in the toc ?
That would be terrific
Another use case that I could see myself using is if we only want to display the bloc regarding a specific method from a class. So for example using: ![mkapi](numpy_style.ExampleClass.message)
It seems at the moment it is not possible, or at least it created an error on my machine.
And not sure if there is another way to achieve this, but that would be interesting to have the possibility to do so.
Thanks!
With the annotation "Union[subprocess.Popen[str], subprocess.Popen[bytes]]"
, I'm getting
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 82, in get_members
return get_members(self.obj)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 209, in get_members
member = get_node(obj, sourcefile_index)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 229, in get_node
return Node(obj, sourcefile_index)
File "<string>", line 5, in __init__
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/node.py", line 31, in __post_init__
super().__post_init__()
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/structure.py", line 100, in __post_init__
signature = get_signature(obj)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/signature.py", line 357, in get_signature
return Signature(obj)
File "<string>", line 7, in __init__
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/signature.py", line 75, in __post_init__
self.returns = resolve_forward_ref(self.obj, return_annotation)
File "/Users/edpage/.cache/ddi/venv_docs/lib/python3.8/site-packages/mkapi/core/signature.py", line 348, in resolve_forward_ref
type = eval(name, globals)
File "<string>", line 1, in <module>
TypeError: 'type' object is not subscriptable
subprocess.Popen
does not native support type subscription (which is why I have to have the ""
around it) but mypy supports it, and with at least my config settings, requires it.
Hi @daizutabi, would appreciate if you could declare the official position of this project. Seems like it's no longer being actively developed or maintain. This is a shame but fair enough. Can you confirm pls?
fwiw our main blocker is it seems to not work with newer versions of Python (3.11 in our case but seem to be broken from Python v3.9 onwards based on other users comments). #56
Thanks
I get a n error with the latest commit (6fe41e2).
Does not occur in the previous commit.
It think the problem is if the code has multiple assignments per line:
class Test():
""" bla bla blubb
Attributes:
_foo: a foobar value
"""
def __init__(self):
""" initizizes test object """
self._foo: str = "BAR"
self._bar: int = 0
def class_method(self, bar: str = "BAR") -> float:
""" class method
Args:
bar: blubb
"""
self._foo = bar
self._foo, self._bar = bar, 0 # booom crash!
return 0.0
Trace:
Traceback (most recent call last):
File "./mkapi/.env/bin/mkdocs", line 8, in <module>
sys.exit(cli())
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/__main__.py", line 152, in build_command
build.build(config.load_config(**kwargs), dirty=not clean)
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 271, in build
_populate_page(file.page, config, files, dirty)
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 167, in _populate_page
page.markdown = config['plugins'].run_event(
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/plugins.py", line 94, in run_event
result = method(item, **kwargs)
File "./mkapi/mkapi/plugins/mkdocs.py", line 108, in on_page_markdown
page = Page(markdown, abs_src_path, self.abs_api_paths)
File "<string>", line 6, in __init__
File "./mkapi/mkapi/core/page.py", line 37, in __post_init__
self.markdown = "\n\n".join(self.split(source))
File "./mkapi/mkapi/core/page.py", line 64, in split
node = get_node(name)
File "./mkapi/mkapi/core/node.py", line 209, in get_node
return Node(obj, sourcefile_index)
File "<string>", line 5, in __init__
File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
super().__post_init__()
File "./mkapi/mkapi/core/structure.py", line 104, in __post_init__
self.members = self.get_members()
File "./mkapi/mkapi/core/node.py", line 59, in get_members
return get_members(self.obj)
File "./mkapi/mkapi/core/node.py", line 189, in get_members
member = get_node(obj, sourcefile_index)
File "./mkapi/mkapi/core/node.py", line 209, in get_node
return Node(obj, sourcefile_index)
File "<string>", line 5, in __init__
File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
super().__post_init__()
File "./mkapi/mkapi/core/structure.py", line 99, in __post_init__
signature = get_signature(obj)
File "./mkapi/mkapi/core/signature.py", line 330, in get_signature
return Signature(obj)
File "<string>", line 7, in __init__
File "./mkapi/mkapi/core/signature.py", line 71, in __post_init__
self.set_attributes()
File "./mkapi/mkapi/core/signature.py", line 109, in set_attributes
for name, (type, description) in get_attributes(self.obj).items():
File "./mkapi/mkapi/core/attribute.py", line 219, in get_attributes
return get_class_attributes(obj)
File "./mkapi/mkapi/core/attribute.py", line 165, in get_class_attributes
return get_attributes_dict(attr_lineno, source, prefix="self.")
File "./mkapi/mkapi/core/attribute.py", line 146, in get_attributes_dict
description = get_description(lines[:stop], lineno)
File "./mkapi/mkapi/core/attribute.py", line 67, in get_description
line = lines[index]
IndexError: list index out of range
Error when numpy array is default value, e.g.:
def add_load(
self,
shape_type: str,
shape_group_name: str,
load_case_number: int = 0,
translations: np.ndarray = np.zeros(3),
rotations: np.ndarray = np.zeros(3),
):
Error message:
....
File "....\python38\lib\site-packages\mkapi\core\signature.py", line 62, in __post_init__
if default == inspect.Parameter.empty:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
__args__
was removed in https://bugs.python.org/issue40397 and https://bugs.python.org/issue40398 . It seems a lot of places use it that causes test failures in Python 3.9. A quick grep of args shows many places and can cause failures like this. python 3.8 added typing.get_args
as a helper.
rg __args__
mkapi/core/signature.py
164: if hasattr(annotation, "__args__") and annotation.__args__:
165: if len(annotation.__args__) == 1:
166: return to_string(annotation.__args__[0], obj=obj)
187: args = [to_string(x, obj=obj) for x in annotation.__args__]
193: if type(annotation.__args__[0]) == TypeVar:
195: args = [to_string(x, obj=obj) for x in annotation.__args__]
200: if not hasattr(annotation, "__args__"):
202: if len(annotation.__args__) == 0:
204: if len(annotation.__args__) == 1:
231: if type(annotation.__args__[0]) == TypeVar:
233: type_ = f"{name} of " + to_string(annotation.__args__[0], obj=obj)
256: args = annotation.__args__
304: args = annotation.__args__
Sample failure after trying to fix #36
==================================== FAILURES =====================================
______________________________ test_class_attribute _______________________________
def test_class_attribute():
attrs = get_attributes(A)
assert attrs
for k, (name, (type, markdown)) in enumerate(attrs.items()):
assert name == ["x", "y", "a", "z"][k]
assert markdown.startswith(["Doc ", "list of", "", "Docstring *after*"][k])
assert markdown.endswith(["attribute.", "specified.", "", "supported."][k])
if k == 0:
assert type is int
elif k == 1:
assert type is None
elif k == 2:
assert not markdown
elif k == 3:
> x = signature.to_string(type)
tests/core/test_core_attribute.py:39:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
mkapi/core/signature.py:187: in to_string
args = [to_string(x, obj=obj) for x in annotation.__args__]
mkapi/core/signature.py:187: in <listcomp>
args = [to_string(x, obj=obj) for x in annotation.__args__]
mkapi/core/signature.py:187: in to_string
args = [to_string(x, obj=obj) for x in annotation.__args__]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = typing.Tuple, attr = '__args__'
def __getattr__(self, attr):
# We are careful for copy and pickle.
# Also for simplicity we just don't relay all dunder names
if '__origin__' in self.__dict__ and not _is_dunder(attr):
return getattr(self.__origin__, attr)
> raise AttributeError(attr)
E AttributeError: __args__
/usr/lib/python3.9/typing.py:648: AttributeError
Hey there,
I'm trying to set up mkapi
to add the API of a package to its documentation. All is well, except for a module that contains a function with a See Also
section in its numpy docstring.
Somehow mkapi seems to fail its interpretation, rendering (part of) it as a new H2 header:
For reference:
readthedocs
default mkdocs theme.See Also
H2 within a Notes section: here and hereflake8
.
$ pipdeptree -p mkapi
mkapi==1.0.14
- jinja2 [required: Any, installed: 3.0.3]
- MarkupSafe [required: >=2.0, installed: 2.1.1]
- markdown [required: Any, installed: 3.2.1]
- setuptools [required: >=36, installed: 61.3.0]
$ pipdeptree -p mkdocs
mkdocs==1.2.4
- click [required: >=3.3, installed: 8.0.4]
- importlib-metadata [required: Any, installed: 4.2.0]
- typing-extensions [required: >=3.6.4, installed: 4.0.1]
- zipp [required: >=0.5, installed: 3.2.0]
- ghp-import [required: >=1.0, installed: 2.1.0]
- python-dateutil [required: >=2.8.1, installed: 2.8.2]
- six [required: >=1.5, installed: 1.13.0]
- importlib-metadata [required: >=3.10, installed: 4.2.0]
- typing-extensions [required: >=3.6.4, installed: 4.0.1]
- zipp [required: >=0.5, installed: 3.2.0]
- Jinja2 [required: >=2.10.1, installed: 3.0.3]
- MarkupSafe [required: >=2.0, installed: 2.1.1]
- Markdown [required: >=3.2.1, installed: 3.2.1]
- setuptools [required: >=36, installed: 61.3.0]
- mergedeep [required: >=1.3.4, installed: 1.3.4]
- packaging [required: >=20.5, installed: 21.3]
- pyparsing [required: >=2.0.2,!=3.0.5, installed: 2.4.5]
- PyYAML [required: >=3.10, installed: 5.3.1]
- pyyaml-env-tag [required: >=0.1, installed: 0.1]
- pyyaml [required: Any, installed: 5.3.1]
- watchdog [required: >=2.0, installed: 2.1.9]
I'm failing to use the Page Mode for other issues, but I also want to have more control on what is displayed and how.
Currently magic/dunder methods are not handled by mkapi:
e.g.:
__add__
__mul__
__eq__
__repr__
__str__
__len__
Would be nice to have them in the API docs if they are documented.
Another interesting improvement could be to be able to display the parent class if the class is a subclass. i.e, just listing the parent classes after the list of parameters.
For example, the following class:
class SubClass(MixinExt, Mixin2):
def __init__(self, string_a: str):
pass
Would result in a documentation like so:
Not sure what you think about that, but I would find it very useful for my usecase.
Thanks and regards
I can successfully run it locally. However, when I try to deploy it via GH actions or rtd, both gave the same error:
Traceback (most recent call last): File "/home/docs/.pyenv/versions/3.7.3/lib/python3.7/runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "/home/docs/.pyenv/versions/3.7.3/lib/python3.7/runpy.py", line 85, in _run_code exec(code, run_globals) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/__main__.py", line 192, in cli() File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 829, in __call__ return self.main(*args, **kwargs) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 782, in main rv = self.invoke(ctx) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 1259, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 1066, in invoke return ctx.invoke(self.callback, **ctx.params) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/click/core.py", line 610, in invoke return callback(*args, **kwargs) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/__main__.py", line 152, in build_command build.build(config.load_config(**kwargs), dirty=not clean) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/commands/build.py", line 236, in build config = config['plugins'].run_event('config', config) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkdocs/plugins.py", line 94, in run_event result = method(item, **kwargs) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/plugins/mkdocs.py", line 51, in on_config config, self.config["filters"] File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/plugins/api.py", line 24, in create_nav value, docs_dir, config_dir, global_filters File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/plugins/api.py", line 47, in collect module = get_module(package_path) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/core/module.py", line 96, in get_module obj = get_object(name) File "/home/docs/checkouts/readthedocs.org/user_builds/python-varname/envs/cleanup/lib/python3.7/site-packages/mkapi/core/object.py", line 39, in get_object raise ValueError(f"Could not find object: {name}") ValueError: Could not find object: varname
And you can see the configurations here:
https://github.com/pwwang/python-varname/tree/857b4c0206e4315d00a3ab85ceb932e9aebf1f69
Command : mkdocs build -f docs/mkdocs.yml -v
When i run the command with python 3.8, it works.
When i run the command with python 3.9, it fails :
DEBUG - Config value: 'plugins' = PluginCollection([('search', <mkdocs.contrib.search.SearchPlugin object at 0x7f9f49027970>), ('mkapi', <mkapi.plugins.mkdocs.MkapiPlugin object at 0x7f9f48fbd880>)])
Traceback (most recent call last):
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/bin/mkdocs", line 8, in <module>
sys.exit(cli())
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkdocs/__main__.py", line 152, in build_command
build.build(config.load_config(**kwargs), dirty=not clean)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkdocs/commands/build.py", line 236, in build
config = config['plugins'].run_event('config', config)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkdocs/plugins.py", line 94, in run_event
result = method(item, **kwargs)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/plugins/mkdocs.py", line 50, in on_config
config, self.abs_api_paths = mkapi.plugins.api.create_nav(
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/plugins/api.py", line 23, in create_nav
page[key], abs_api_paths_ = collect(
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/plugins/api.py", line 47, in collect
module = get_module(package_path)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 104, in get_module
module = Module(obj)
File "<string>", line 4, in __init__
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 27, in __post_init__
super().__post_init__()
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/structure.py", line 106, in __post_init__
self.members = self.get_members()
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 48, in get_members
return get_members(self.obj)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 81, in get_members
module = get_module(name)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 104, in get_module
module = Module(obj)
File "<string>", line 4, in __init__
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/module.py", line 28, in __post_init__
self.node = get_node(self.obj)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 229, in get_node
return Node(obj, sourcefile_index)
File "<string>", line 5, in __init__
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 31, in __post_init__
super().__post_init__()
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/structure.py", line 106, in __post_init__
self.members = self.get_members()
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 82, in get_members
return get_members(self.obj)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 209, in get_members
member = get_node(obj, sourcefile_index)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 229, in get_node
return Node(obj, sourcefile_index)
File "<string>", line 5, in __init__
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/node.py", line 31, in __post_init__
super().__post_init__()
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/structure.py", line 100, in __post_init__
signature = get_signature(obj)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/signature.py", line 356, in get_signature
return Signature(obj)
File "<string>", line 7, in __init__
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/signature.py", line 71, in __post_init__
self.set_attributes()
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/signature.py", line 118, in set_attributes
for name, (type, description) in get_attributes(self.obj).items():
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 269, in get_attributes
return get_class_attributes(obj)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 185, in get_class_attributes
attr_lineno = get_attributes_with_lineno(nodes, module)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 121, in get_attributes_with_lineno
attr, lineno, type_str = parse_annotation_assign(x)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 61, in parse_annotation_assign
type = parse_node(assign.annotation)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 47, in parse_node
return parse_subscript(x)
File "/root/.cache/pypoetry/virtualenvs/ifr-lib-OYUa1U17-py3.9/lib/python3.9/site-packages/mkapi/core/attribute.py", line 23, in parse_subscript
slice = parse_node(x.slice.value)
AttributeError: 'Name' object has no attribute 'value'
Have you any idea ?
What are the plans to support Python version 3.10?
We use namespace packages so we don't clutter the global package namespace. This line in a mkdocs.yml
trying to document namespacefoo.packagefoo
does not produce the expected results:
nav:
- API: mkapi/api/src/namespacefoo
I expect it to find and document namespacefoo.packagefoo
. Instead it finds other packages in the same namespace installed in the current environment (e.g. namespacefoo.anotherpackage), but not namespacefoo.packagefoo.
I can convince mkapi
to find namespacefoo.packagefoo with this mkdocs.yml:
nav:
- API: mkapi/api/src/namespacefoo/packagefoo
But in this case:
[Baz](packagefoo.modulebar.Baz)
I'd like to be able to use references that are obvious to someone reading the docstring without the web page. I think fully a qualified reference would be clear, if long: [Baz](namespacefoo.packagefoo.modulebar.Baz)
. It would be nice if you could also use Baz from a doctring inside the module containing Baz.
This is anecdotal, but CloudFront wants paths to end in a slash:
https://libvcs.git-pull.com/api/source/libvcs.hg/#libvcs.hg.MercurialRepo
https://libvcs.git-pull.com/api/source/libvcs.hg#libvcs.hg.MercurialRepo
Thoughts on adding this as a default behavior? Setting?
diff --git a/mkapi/core/postprocess.py b/mkapi/core/postprocess.py
index 959aa77..bab3313 100644
--- a/mkapi/core/postprocess.py
+++ b/mkapi/core/postprocess.py
@@ -11,7 +11,7 @@ def sourcelink(object: Object) -> str:
link = f'<span id="{object.id}"></span>'
else:
link = ""
- link += f'<a class="mkapi-src-link" href="../source/{object.module}'
+ link += f'<a class="mkapi-src-link" href="../source/{object.module}/'
link += f'#{object.id}" title="Source for {object.id}"></></a>'
return link
diff --git a/mkapi/templates/object.jinja2 b/mkapi/templates/object.jinja2
index da1ef7f..f7a0a11 100644
--- a/mkapi/templates/object.jinja2
+++ b/mkapi/templates/object.jinja2
@@ -11,7 +11,7 @@
</div>
{% if 'sourcelink' in filters or 'link' in filters or 'apilink' in filters -%}
<div class="mkapi-src-link">
- <a class="mkapi-src-link" href="../source/{{ object.module }}#{{ object.id }}" title="Source for {{ object.id }}"></></a>
+ <a class="mkapi-src-link" href="../source/{{ object.module }}/#{{ object.id }}" title="Source for {{ object.id }}"></></a>
</div>
{%- endif %}
</div>
Currently I hard-code this in a forked package since I feel its too specialized (and I'm not sure what other static file hosts use)
In the readthedocs theme the breadcrumbs for mkapi in pagemode are not correctly displayed.
The line before API
should not be displayed. I think that is a problem with the page.anchestors
for the mkapi pages.
theme:
name: readthedocs
mkdocs serve
Hello,
first of all i like your project. Its currently the best option for creating api-docs with mkdocs using google-style, nice work ๐
Current Release 0.6.1 depends on Ipython package which is not listed in the dependencies.
after i updated the library and build with mkdocs i get the following error:
$mkdocs build -c -v
...
.env/lib/python3.8/site-packages/mkapi/utils.py", line 1, in <module>
from IPython.display import HTML
ModuleNotFoundError: No module named 'IPython'
Hello,
Current version (0.7.7) throws TypeError if the base class is Abstract (abc.ABC
)
Rerproduce Error:
change the follwing in examples/inherit.py
from dataclasses import dataclass
from mkapi.core.base import Type
import abc
@dataclass
class Base(abc.ABC):
...
Trace:
ERROR - Error reading page 'usage/inherit.md': descriptor 'mro' of 'type' object needs an argument
Traceback (most recent call last):
File "./mkapi/.env/bin/mkdocs", line 8, in <module>
sys.exit(cli())
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "./mkapi/.env/lib/python3.8/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/__main__.py", line 152, in build_command
build.build(config.load_config(**kwargs), dirty=not clean)
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 271, in build
_populate_page(file.page, config, files, dirty)
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/commands/build.py", line 167, in _populate_page
page.markdown = config['plugins'].run_event(
File "./mkapi/.env/lib/python3.8/site-packages/mkdocs/plugins.py", line 94, in run_event
result = method(item, **kwargs)
File "./mkapi/mkapi/plugins/mkdocs.py", line 86, in on_page_markdown
page = Page(markdown, abs_src_path, self.abs_api_paths)
File "<string>", line 6, in __init__
File "./mkapi/mkapi/core/page.py", line 36, in __post_init__
self.markdown = "\n\n".join(self.split(source))
File "./mkapi/mkapi/core/page.py", line 57, in split
node = get_node(name)
File "./mkapi/mkapi/core/node.py", line 197, in get_node
return _get_node(obj, sourcefile_index)
File "./mkapi/mkapi/core/node.py", line 180, in _get_node
return Node(obj, sourcefile_index)
File "<string>", line 5, in __init__
File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
super().__post_init__()
File "./mkapi/mkapi/core/tree.py", line 49, in __post_init__
self.members = self.get_members()
File "./mkapi/mkapi/core/node.py", line 58, in get_members
return get_members(self.obj)
File "./mkapi/mkapi/core/node.py", line 169, in get_members
member = get_node(obj, sourcefile_index)
File "./mkapi/mkapi/core/node.py", line 197, in get_node
return _get_node(obj, sourcefile_index)
File "./mkapi/mkapi/core/node.py", line 180, in _get_node
return Node(obj, sourcefile_index)
File "<string>", line 5, in __init__
File "./mkapi/mkapi/core/node.py", line 30, in __post_init__
super().__post_init__()
File "./mkapi/mkapi/core/tree.py", line 48, in __post_init__
self.docstring = get_docstring(obj)
File "./mkapi/mkapi/core/docstring.py", line 297, in get_docstring
postprocess(docstring, obj)
File "./mkapi/mkapi/core/docstring.py", line 230, in postprocess
add_bases(doc, obj)
File "./mkapi/mkapi/core/docstring.py", line 214, in add_bases
bases = obj.mro()[1:-1]
TypeError: descriptor 'mro' of 'type' object needs an argument
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.