Git Product home page Git Product logo

better-apidoc's Introduction

better-apidoc

PyPI version

A version of sphinx-apidoc with support for templating

Author: Michael Goerz <[email protected]>

Website: Github

Installation

pip install better-apidoc

This will install better-apidoc in the current environment's bin folder.

Templating

The better-apidoc script is a patched version of Sphinx' apidoc.py. After a lengthy gestation period, it is on track to be merged back into apidoc.py: sphinx-doc/sphinx#6768

Note: Due to changes in Sphinx 1.8, better-apdic in its current form can no longer run as a script from the command line, and must be run from inside conf.py, see "Usage" below.

Fundamentally, better-apidoc adds the -t/--templates option to the script. If this option is not given, it is identical to sphinx-apidoc. With the option, Jinja-based templates are used for the generated ReST files. The template directory given via -t must contain the template files module.rst and package.rst.

The following variables are available in the templates:

  • name: the name of the module/package
  • fullname: the name of the module/package, including package path (dot-separated)
  • members: list of names of all the members defined directly in the module/package
  • functions: list all the functions in members
  • classes: list of all the classes in members
  • exceptions: list of all the exceptions in members
  • data: list of all the data items in members
  • subpackages: For packages, list of subpackage names. Empty list for modules
  • submodules: For packages, list of submodule names. Empty list of modules

Furthermore, the function get_members is made available to the template:

def get_members(
        typ=None, include_imported=False, out_format='names',
        in_list=None, includeprivate=opts.includeprivate, known_refs=None):
    """Return a list of members of the current module

    Args:
        typ (None or str): One of None, 'function', 'class', 'exception',
            'data'. If not None, only members of the corresponding type
             will be returned
        include_imported (bool): If True, include members that are imported
            from other modules. If False, only return members that are
            defined directly in the module.
        out_format (str): One of 'names', 'fullnames', 'refs', and 'table'
        in_list (None or str): If not None, name of a module
            attribute (e.g. '__all__'). Only members whose names appears in
            the list will be returned.
        includeprivate (bool): If True, include members whose names starts
            with an underscore
        know_refs (None or dict or str): If not None, a mapping of names to
            rull rst-formatted references. If given as a str, the mapping
            will be taken from the module attribute of the given name. This
            is used only in conjunction with ``out_format=refs``, to
            override automatically detected reference location, or to
            provide references for object that cannot be located
            automatically (data objects).

    Returns:
        list: List of strings, depending on `out_format`.

        If 'names' (default), return a list of the simple names of all
        members.

        If 'fullnames', return a list of the fully qualified names
        of the members.

        If 'refs', return a list of rst-formatted links.

        If 'table', return a list of lines for a rst table similar to that
        generated by the autosummary plugin (left column is linked member
        names, right column is first sentence of the docstring)


    Note:
        For data members, it is not always possible to determine whther
        they are imported or defined locally. In this case, `in_list` and
        `known_refs` may be used to achieve the desired result.

        If using ``in_list='__all__'`` for a package you may also have to
        use ``include_imported=True`` to get the full list (as packages
        typically export members imported from their sub-modules)
    """

You can use this in a template as e.g.

{% set all_refs = get_members(in_list='__all__', include_imported=True, out_format='refs') %}
{% if all_refs %}
    ``__all__``: {{ all_refs|join(", ") }}
{%- endif %}

to get a linked list of members in the __all__ list of a module. Note that the template variables members, functions, classes, exceptions, and data all could be obtained by using get_members as well; they are provided as variables for convenience only.

The package.rst template will be used when rendering any package. The module.rst template will be used when rendering modules if the -s/--separate option is given, or if the <module_path> only contains modules. Note that if <module_path> contains a package and the -s/--separate is not given, the module.rst template will not be used.

The addition of templates to apidoc addresses Sphinx issue #3545. That is, it is now possible to have a list of members with short summaries at the top of the API documentation that links to the more detailed information below. It is also directly addresses the demand for this feature expressed on Stackoverflow.

See package.rst and module.rst for an example template. These render to e.g. https://qnet.readthedocs.io/en/latest/API/qnet.algebra.core.operator_algebra.html

Usage

Due to changes in Sphinx 1.8, better_apidoc can no longer be run as an independent script. Instead, it must be set up in Sphinx's conf.py. In conf.py, define a function like this:

def run_apidoc(app):
    """Generage API documentation"""
    import better_apidoc
    better_apidoc.APP = app
    better_apidoc.main([
        'better-apidoc',
        '-t',
        os.path.join('.', '_templates'),
        '--force',
        '--no-toc',
        '--separate',
        '-o',
        os.path.join('.', 'API'),
        os.path.join('..', 'src', 'krotov'),
    ])

You will have to adjust the last two lines: os.path.join('.', 'API') is the location relative to conf.py where the API rst files should be generated. In the last line, os.path.join('..', 'src', 'krotov') is the location of the package code (I strongly advocate the use of a src directory).

Then, at the end of conf.py, add the following code:

def setup(app):
    app.connect('builder-inited', run_apidoc)

For an full example, see the conf.py file of the krotov project

History

v0.1.0 (2017-03-08): first public release

v0.1.1 (2017-03-12): handle custom autodocumenters

v0.1.2 (2017-03-12): support for (non-standard) __local_data__ and __imported_data__ class attributes to properly identify data members

v0.1.3 (2018-03-14): support Sphinx 1.7

v0.1.4 (2018-03-24): support both Sphinx 1.6 and 1.7

v0.2.0 (2018-07-01):

  • make function get_members available to templates
  • remove template variables member_imports, members_imports_refs, all_refs: their functionality is now achieved with get_members
  • remove use of non-standard __local_data__ and __imported_data__ module attributes. These can still be used via the in_list argument of get_members.
  • add capability to generate autosummary-like tables, via out_format='table' in get_members (but solving autosummary's problem of not generating links for imported members)
  • This release breaks templates written for v0.1.x

v0.3.0 (2019-04-02): Adapt to changes in Sphinx 1.8 (#14). As a result, sphinx-apidoc can no longer run as a standalone script, but must be called from inside conf.py.

v0.3.1 (2019-04-04): Fix calls to Sphinx's get_documenter function to work for any version of version of Sphinx (tested on 1.6-2.0)

v0.3.2 (2021-05-10): Compatibility update for Sphinx 4.0 (#17)

License

This software is available under the terms of the BSD license. See LICENSE for details.

better-apidoc's People

Contributors

goerz avatar therealsupermario avatar veox avatar willu47 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

better-apidoc's Issues

"add_documenter()" is now removed from Sphinx 1.8

Getting the following error now that I've installed Sphinx 1.8:

Traceback (most recent call last):
  File "/home/jsivak/personal/knowledge_ve/bin/better-apidoc", line 6, in <module>
    from better_apidoc import main
  File "/home/jsivak/personal/knowledge_ve/lib/python3.7/site-packages/better_apidoc.py", line 51, in <module>
    from sphinx.ext.autodoc import add_documenter, \
ImportError: cannot import name 'add_documenter' from 'sphinx.ext.autodoc' (/home/jsivak/personal/knowledge_ve/lib/python3.7/site-packages/sphinx/ext/autodoc/__init__.py)

The Sphinx 1.7 change log indicates that the "add_documenter()" function was going to be removed, and now in 1.8 it is actually removed.

I've forked the repo, but I don't know how to get an "app" object so that I can update the code to use "Please use app.add_autodocumenter() instead." as specified in the change log.

Any ideas/pointers?

Thanks

Version typo in readme

In the readme it says:

This release breaks templates written for v1.0.x

But surely you meant

v0.1.x

It is not really a serious issue, just thought I mention it.

Can't run when setup.py is in source directory

When I try to run command:

>> better-apidoc --templates=templatedir -o outputdir ..
error: option --templates not recognized

Otherwise this works but when using the --templates or -t option flags and there is a setup.py in source directory then this will fail. Error message is always that some option parameter is not recognized. This is because importlib.import_module('setup') doesn't work.

You can circumvent this problem by adding setup.py into your exclude list.

Ubuntu
Python 2.7.12

UnboundLocalError: local variable 'package_ns' referenced before assignment

VERSION: better-apidoc 0.1.4

Whenever I run:

better-apidoc -t ./_templates -f ../song_match -o song_match

I get the following error:

WARNING: failed to import 'song_match': No module named 'song_match'
Traceback (most recent call last):
  File "/home/g/anaconda3/bin/better-apidoc", line 11, in <module>
    sys.exit(main())
  File "/home/g/anaconda3/lib/python3.6/site-packages/better_apidoc.py", line 604, in main
    modules = recurse_tree(rootpath, excludes, opts)
  File "/home/g/anaconda3/lib/python3.6/site-packages/better_apidoc.py", line 462, in recurse_tree
    py_files, opts, subs, is_namespace)
  File "/home/g/anaconda3/lib/python3.6/site-packages/better_apidoc.py", line 365, in create_package_file
    text = template.render(**package_ns)
UnboundLocalError: local variable 'package_ns' referenced before assignment

Not sure what I'm doing wrong.

I run the command within ./docs. Here's a snippet of my package structure.

.
├── docs
│   └── _templates
│       ├── module.rst
│       └── package.rst
├── song_match
│   ├── config.py

... The rest is omitted

Whenever I try sphinx-apidoc -f ../song_match -o song_match it works fine.

Any help?

Add six and docutils to requirements

This package depends on six and docutils but they are not in requirements. Running it with updated docs dependencies on Python 3.8 I got:

Extension error:
Handler <function run_apidoc at 0x000001E245CEF160> for event 'builder-inited' threw an exception
(exception: No module named 'six')

Adding six to my docs requirements solved the problem of course. But this should not be necessary.

implicit namespace packages are missing in `subpackages` template variable

The sub package filter in the create_package_file function also removes implicit namespace packages (i.e.,

subs = [sub for sub in subs if path.isfile(path.join(root, sub, INITPY))]
).

The issue is apparently already fixed in the upstream apidoc tool which performs the filtering using shall_skip (see https://github.com/sphinx-doc/sphinx/blob/b135e7ce4a919f73c04e376a14ce597b0f160cac/sphinx/ext/apidoc.py#L128-L129). Could you adopt this change into better-apidoc?

Furthermore, given that other changes like, for example, exclude support for shall_skip have been added upstream, I wonder if you plan to rebase better-apidoc on a more recent version of sphinx-apidoc in general.

TypeError in 0.3.0

Now getting:

Exception occurred:
documenter = get_documenter(app=APP, obj=member, parent=mod)
TypeError: get_documenter() got an unexpected keyword argument 'app'

Include reasonable template examples in the repository

I think that including a reasonable example of package.rst and module.rst would be of huge help for everyone who'd like to use this package. Many of the people who come here, do because they'd like to strip away the "Submodules/Subpackages" headers and the "module/package" suffixes. A template that does that would be a good start.

issue with implicit-namespaces

I can run this without issue:

sphinx-apidoc -f --implicit-namespaces --no-toc --ext-todo --ext-intersphinx --ext-viewcode -o source/apidoc <excludes>

without issue

However when I run the same with better-apidoc like this:

better-apidoc -t './rst_template_dir' -f --implicit-namespaces --no-toc --ext-todo --ext-intersphinx --ext-viewcode -o source/apidoc <excludes>

I get the following:

Traceback (most recent call last):
  File "c:\anaconda3\envs\py352\lib\runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\anaconda3\envs\py352\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Anaconda3\envs\py352\Scripts\better-apidoc.exe\__main__.py", line 9, in <module>
  File "c:\anaconda3\envs\py352\lib\site-packages\better_apidoc.py", line 600, in main
    modules = recurse_tree(rootpath, excludes, opts)
  File "c:\anaconda3\envs\py352\lib\site-packages\better_apidoc.py", line 458, in recurse_tree
    py_files, opts, subs, is_namespace)
  File "c:\anaconda3\envs\py352\lib\site-packages\better_apidoc.py", line 318, in create_package_file
    includeprivate=opts.includeprivate)
  File "c:\anaconda3\envs\py352\lib\site-packages\better_apidoc.py", line 270, in _get_mod_ns
    mod = importlib.import_module(fullname)
  File "c:\anaconda3\envs\py352\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 981, in _gcd_import
  File "<frozen importlib._bootstrap>", line 933, in _sanity_check
ValueError: Empty module name
make: *** [rst] Error 1

> pip show better-apidoc
Name: better-apidoc
Version: 0.1.2

I don't appear to get any error when not using --implicit-namespaces: for whatever that's worth.

Error from using sphinx.utils.walk

Hi,

I was running into the following error

Running Sphinx v4.0.0
making output directory... done
[autosummary] generating autosummary for: XXX

Extension error:
Handler <function run_apidoc at 0x7f83a4aa1550> for event 'builder-inited' threw an exception (exception: cannot import name 'walk' from 'sphinx.util.osutil' (XXX/lib/python3.8/site-packages/sphinx/util/osutil.py))
make: *** [html] Error 2

Turns out the problem comes from import better_apidoc in conf.py. The fix is extremely simple: just don't use the walk from sphinx, but use os.walk.

https://github.com/goerz/better-apidoc/blob/master/better_apidoc.py#L39

As it turns out, sphinx.utils.walk is deprecated anyway. See https://www.sphinx-doc.org/en/master/changes.html#id96.

Do you guys think it is a good idea to fix this?

pypi install is outdated

The version of better-apidoc on PyPI is v1.2, and doesn't include the latest changes for forward compatibility with Sphinx 1.7. Any chance of a new release?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.