File: generate_api_docs.py

package info (click to toggle)
python-altair 5.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,952 kB
  • sloc: python: 25,649; sh: 14; makefile: 5
file content (131 lines) | stat: -rw-r--r-- 3,489 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""
This script fills the contents of doc/user_guide/api.rst
based on the updated Altair schema.
"""
import sys
import types
from os.path import abspath, dirname, join

# Import Altair from head
ROOT_DIR = abspath(join(dirname(__file__), ".."))
sys.path.insert(0, ROOT_DIR)
import altair as alt  # noqa: E402

API_FILENAME = join(ROOT_DIR, "doc", "user_guide", "api.rst")

API_TEMPLATE = """\
.. _api:

API Reference
=============

This is the class and function reference of Altair, and the following content
is generated automatically from the code documentation strings.
Please refer to the `full user guide <http://altair-viz.github.io>`_ for
further details, as this low-level documentation may not be enough to give
full guidelines on their use.

Top-Level Objects
-----------------
.. currentmodule:: altair

.. autosummary::
   :toctree: generated/toplevel/
   :nosignatures:

   {toplevel_charts}

Encoding Channels
-----------------
.. currentmodule:: altair

.. autosummary::
   :toctree: generated/channels/
   :nosignatures:

   {encoding_wrappers}

API Functions
-------------
.. currentmodule:: altair

.. autosummary::
   :toctree: generated/api/
   :nosignatures:

   {api_functions}

Low-Level Schema Wrappers
-------------------------
.. currentmodule:: altair

.. autosummary::
   :toctree: generated/core/
   :nosignatures:

   {lowlevel_wrappers}
"""


def iter_objects(
    mod, ignore_private=True, restrict_to_type=None, restrict_to_subclass=None
):
    for name in dir(mod):
        obj = getattr(mod, name)
        if ignore_private:
            if name.startswith("_"):
                continue
        if restrict_to_type is not None:
            if not isinstance(obj, restrict_to_type):
                continue
        if restrict_to_subclass is not None:
            if not (isinstance(obj, type) and issubclass(obj, restrict_to_subclass)):
                continue
        yield name


def toplevel_charts():
    return sorted(iter_objects(alt.api, restrict_to_subclass=alt.TopLevelMixin))


def encoding_wrappers():
    return sorted(iter_objects(alt.channels, restrict_to_subclass=alt.SchemaBase))


def api_functions():
    # Exclude typing.cast
    altair_api_functions = [
        obj_name
        for obj_name in iter_objects(alt.api, restrict_to_type=types.FunctionType)
        if obj_name != "cast"
    ]
    return sorted(altair_api_functions)


def lowlevel_wrappers():
    objects = sorted(iter_objects(alt.schema.core, restrict_to_subclass=alt.SchemaBase))
    # The names of these two classes are also used for classes in alt.channels. Due to
    # how imports are set up, these channel classes overwrite the two low-level classes
    # in the top-level Altair namespace. Therefore, they cannot be imported as e.g.
    # altair.Color (which gives you the Channel class) and therefore Sphinx won't
    # be able to produce a documentation page.
    objects = [o for o in objects if o not in ("Color", "Text")]
    return objects


def write_api_file():
    print("Updating API docs\n  ->{}".format(API_FILENAME))
    sep = "\n   "
    with open(API_FILENAME, "w") as f:
        f.write(
            API_TEMPLATE.format(
                toplevel_charts=sep.join(toplevel_charts()),
                api_functions=sep.join(api_functions()),
                encoding_wrappers=sep.join(encoding_wrappers()),
                lowlevel_wrappers=sep.join(lowlevel_wrappers()),
            )
        )


if __name__ == "__main__":
    write_api_file()