Skip to content

Commit b26db3e

Browse files
authored
Autodocument Traitlets from UI Server (#385)
Autodocument traits in UI Server config documentation
1 parent 66173d6 commit b26db3e

File tree

6 files changed

+150
-3
lines changed

6 files changed

+150
-3
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def get_version(module, path):
4343
'eralchemy==1.2.*',
4444
'hieroglyph>=2.1.0',
4545
'setuptools>=50',
46-
'sphinx>=3.0.0',
46+
'sphinx>=4.4',
4747
'sphinx_rtd_theme>=0.5.0',
4848
'sphinxcontrib-svg2pdfconverter',
4949
]

src/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
from cylc_release import CYLC_RELEASE
2626

27-
2827
# -- General configuration ------------------------------------------------
2928

3029
# Sphinx extension module names.
@@ -40,6 +39,7 @@
4039
'hieroglyph',
4140
'sphinx_rtd_theme',
4241
# custom project extensions (located in ext/)
42+
'autodoc_traits', # autodoc uiserver traitlets
4343
'database_diagram',
4444
# cylc-sphinx-extensions
4545
'cylc.sphinx_ext.cylc_lang',
@@ -50,7 +50,7 @@
5050
'cylc.sphinx_ext.practical',
5151
'cylc.sphinx_ext.rtd_theme_addons',
5252
'cylc.sphinx_ext.sub_lang',
53-
'cylc.sphinx_ext.literal_sub_include',
53+
'cylc.sphinx_ext.literal_sub_include'
5454
]
5555

5656
rst_epilog = open('hyperlinks.rst.include', 'r').read()

src/ext/autodoc_traits/__init__.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
2+
#
3+
# This program is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
"""Autodoc extension for configurable traits.
16+
This code auto documents traits from Cylc UI Server:
17+
"""
18+
19+
__version__ = "0.1.0"
20+
21+
22+
def setup(app, *args, **kwargs):
23+
from .autodoc_traits import setup
24+
25+
return setup(app, *args, **kwargs)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
2+
#
3+
# This program is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
"""Autodoc extension for configurable traits.
16+
This code auto documents traits from Cylc UI Server:
17+
Acknowledgment:
18+
Code derived from the Jupyter Hub source (BSD).
19+
20+
https://github.com/jupyterhub/autodoc-traits/
21+
autodoc_traits.py
22+
23+
BSD 3-Clause License
24+
25+
Copyright (c) Project Jupyter Contributors
26+
All rights reserved.
27+
28+
Redistribution and use in source and binary forms, with or without
29+
modification, are permitted provided that the following conditions are met:
30+
31+
* Redistributions of source code must retain the above copyright notice, this
32+
list of conditions and the following disclaimer.
33+
34+
* Redistributions in binary form must reproduce the above copyright notice,
35+
this list of conditions and the following disclaimer in the documentation
36+
and/or other materials provided with the distribution.
37+
38+
* Neither the name of the copyright holder nor the names of its
39+
contributors may be used to endorse or promote products derived from
40+
this software without specific prior written permission.
41+
42+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
46+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
51+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52+
"""
53+
from sphinx.ext.autodoc import AttributeDocumenter
54+
from sphinx.ext.autodoc import ClassDocumenter
55+
from traitlets import TraitType
56+
from traitlets import Undefined
57+
58+
59+
class ConfigurableDocumenter(ClassDocumenter):
60+
"""Specialized Documenter subclass for traits with config=True"""
61+
62+
objtype = "configurable"
63+
directivetype = "class"
64+
65+
def get_object_members(self, want_all):
66+
"""Add traits with .tag(config=True) to members list"""
67+
check, members = super().get_object_members(want_all)
68+
get_traits = (
69+
self.object.class_own_traits
70+
if self.options.inherited_members
71+
else self.object.class_traits
72+
)
73+
trait_members = []
74+
for name, trait in sorted(get_traits(config=True).items()):
75+
# put help in __doc__ where autodoc will look for it
76+
trait.__doc__ = trait.help
77+
trait_members.append((name, trait))
78+
return check, trait_members
79+
80+
81+
class TraitDocumenter(AttributeDocumenter):
82+
objtype = "trait"
83+
directivetype = "attribute"
84+
member_order = 1
85+
priority = 100
86+
87+
@classmethod
88+
def can_document_member(cls, member, membername, isattr, parent):
89+
return isinstance(member, TraitType)
90+
91+
def add_directive_header(self, sig):
92+
default = self.object.get_default_value()
93+
if default is Undefined:
94+
default_s = ""
95+
else:
96+
default_s = repr(default)
97+
self.options.annotation = "c.{name} = {trait}({default})".format(
98+
name=self.format_name(),
99+
trait=self.object.__class__.__name__,
100+
default=default_s,
101+
)
102+
super().add_directive_header(sig)
103+
104+
105+
def setup(app):
106+
app.add_autodocumenter(ConfigurableDocumenter)
107+
app.add_autodocumenter(TraitDocumenter)

src/reference/config/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ Configuration
77
file-format
88
workflow
99
global
10+
ui-server
1011
types
1112
writing-platform-configs

src/reference/config/ui-server.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
UI Server Configuration
2+
=======================
3+
4+
Cylc UI Server can be configured using a ``jupyter_config.py``.
5+
6+
Site level configuration, such as ``c.CylcUIServer.site_authorization`` should
7+
be defined in ``/etc/cylc/hub/jupyter_config.py``, or, alternatively, the
8+
environment variable ``CYLC_SITE_CONF_PATH``.
9+
User level configuration should be located in ``~/.cylc/hub/jupyter_config.py``.
10+
11+
.. automodule:: cylc.uiserver.app
12+
13+
.. autoconfigurable:: cylc.uiserver.app.CylcUIServer
14+
:inherited-members: False

0 commit comments

Comments
 (0)