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()
|