Render JSX representations of python classes and functions interactively.

is_valid_xml[source]

is_valid_xml(xml:str)

Determine if xml is valid or not.

You can use is_valid_xml to determine if JSX is valid:

_valid = "<Foo></Foo>" # valid jsx
assert is_valid_xml(_valid)

If you pass invalid JSX to is_valid_xml, a warning will be printed:

_invalid1 = "<Foo><Foo>"
_invalid2 = "<Foo></Bar>"

assert not is_valid_xml(_invalid1)
assert not is_valid_xml(_invalid2)
WARNING: xml not does not parse:no element found: line 1, column 10
WARNING: xml not does not parse:mismatched tag: line 1, column 7

param2JSX[source]

param2JSX(p:Parameter)

Format a numpydoc.docscrape.Parameters as JSX components

_fd = FunctionDoc(ex.function_with_types_in_docstring)
_p = _fd['Parameters'][0]

test_eq(param2JSX(_p), '<Parameter name="param1" type="int" desc="The first parameter. something something\\nsecond line. foo" />')
assert is_valid_xml(param2JSX(_p))

np2jsx[source]

np2jsx(obj, skip_sections='')

Turn Numpy Docstrings Into JSX components

Below are some examples of docstrings and resulting JSX that comes out of them. This one is of a class:

print(inspect.getdoc(ex.ExampleClass))
The summary line for a class docstring should fit on one line.

If the class has public attributes, they may be documented here
in an ``Attributes`` section and follow the same formatting as a
function's ``Args`` section. Alternatively, attributes may be documented
inline with the attribute's declaration (see __init__ method below).

Properties created with the ``@property`` decorator should be documented
in the property's getter method.

Attributes
----------
attr1 : str
    Description of `attr1`.
attr2 : :obj:`int`, optional
    Description of `attr2`.
_res = np2jsx(ex.ExampleClass)
assert '<Parameter name="attr1" type="str" desc="Description of `attr1`." />' in _res
assert 'extended_summary="If the class has public attributes' in _res
assert '</ParamSection>' in _res
print(_res)
<Description summary="The summary line for a class docstring should fit on one line." extended_summary="If the class has public attributes, they may be documented here\nin an ``Attributes`` section and follow the same formatting as a\nfunction's ``Args`` section. Alternatively, attributes may be documented\ninline with the attribute's declaration (see __init__ method below).\n\nProperties created with the ``@property`` decorator should be documented\nin the property's getter method." />
<ParamSection name="Attributes">
	<Parameter name="attr1" type="str" desc="Description of `attr1`." />
	<Parameter name="attr2" type=":obj:`int`, optional" desc="Description of `attr2`." />
</ParamSection>

This next one is of a top-level function:

print(inspect.getdoc(ex.function_with_types_in_docstring))
Example function with types documented in the docstring.

`PEP 484`_ type annotations are supported. If attribute, parameter, and
return types are annotated according to `PEP 484`_, they do not need to be
included in the docstring:

Parameters
----------
param1 : int
    The first parameter. something something
    second line. foo
param2 : str
    The second parameter.

Returns
-------
bool
    True if successful, False otherwise.
_res = np2jsx(ex.function_with_types_in_docstring)
assert 'extended_summary="`PEP 484`_ type annotations are supported' in _res
assert '<Parameter name="param2" type="str" desc="The second parameter." />' in _res
assert '<ParamSection name="Returns">' in _res
print(_res)
<Description summary="Example function with types documented in the docstring." extended_summary="`PEP 484`_ type annotations are supported. If attribute, parameter, and\nreturn types are annotated according to `PEP 484`_, they do not need to be\nincluded in the docstring:" />
<ParamSection name="Parameters">
	<Parameter name="param1" type="int" desc="The first parameter. something something\nsecond line. foo" />
	<Parameter name="param2" type="str" desc="The second parameter." />
</ParamSection>
<ParamSection name="Returns">
	<Parameter type="bool" desc="True if successful, False otherwise." />
</ParamSection>

fmt_sig_param[source]

fmt_sig_param(p:Parameter)

Format inspect.Parameters as JSX components.

fmt_sig_param converts individual parameters in signatures to JSX. Let's take the complex signature below, for example:

_sig = inspect.signature(ex.Bar)
_sig
<Signature (a: int, b: str = 'foo', c: float = 0.1, *args, **tags)>

Each of these parameters are then converted to JSX components

_ps = _sig.parameters
test_eq(fmt_sig_param(_ps['a']), '<SigArg name="a" type="int" />')
test_eq(fmt_sig_param(_ps['b']), '<SigArg name="b" type="str" default="foo" />')
test_eq(fmt_sig_param(_ps['args']), '<SigArg name="*args" />')
test_eq(fmt_sig_param(_ps['tags']), '<SigArg name="**tags" />')
assert is_valid_xml(fmt_sig_param(_ps['b']))

get_sig_section[source]

get_sig_section(obj, spoofstr=None)

Get JSX section from the signature of a class or function consisting of all of the argument. Optionally replace signature with spoofstr

Let's take the class Bar, for example:

inspect.signature(ex.Bar)
<Signature (a: int, b: str = 'foo', c: float = 0.1, *args, **tags)>

The signature will get converted to JSX components, like so:

_ex_result="""<SigArgSection>
<SigArg name="a" type="int" /><SigArg name="b" type="str" default="foo" /><SigArg name="c" type="float" default="0.1" /><SigArg name="*args" /><SigArg name="**tags" />
</SigArgSection>
""".strip()

_gen_result = get_sig_section(ex.Bar)
assert is_valid_xml(_gen_result) # make sure its valid xml
test_eq(_gen_result, _ex_result)
print(_gen_result)
<SigArgSection>
<SigArg name="a" type="int" /><SigArg name="b" type="str" default="foo" /><SigArg name="c" type="float" default="0.1" /><SigArg name="*args" /><SigArg name="**tags" />
</SigArgSection>

get_type[source]

get_type(obj)

Return type of object as a either 'method', 'function', 'class' or None.

test_eq(get_type(ex.function_with_types_in_docstring),'function')
test_eq(get_type(ex.ExampleClass), 'class')
test_eq(get_type(ex.ExampleClass.example_method), 'method')

get_base_urls[source]

get_base_urls(warn=False, param='module_baseurls')

Get baseurls from config file

This project has a settings.ini which defines the module_baseurls parameter. get_base_urls will return a dictionary of all the baseurls defined there. This is useful used to construct URLs to source code in documentation.

Here is how the relevant parts of this project's settings.ini file is defined:

module_baseurls = metaflow=https://github.com/Netflix/metaflow/tree/master/
    nbdev=https://github.com/fastai/nbdev/tree/master
    fastcore=https://github.com/fastcore/tree/master
_base_urls = get_base_urls()
assert len(_base_urls.keys()) == 3
_base_urls
{'metaflow': 'https://github.com/Netflix/metaflow/tree/master/',
 'nbdev': 'https://github.com/fastai/nbdev/tree/master',
 'fastcore': 'https://github.com/fastcore/tree/master'}

class ShowDoc[source]

ShowDoc(obj, hd_lvl=None, name=None, objtype=None, module_nm=None, decorator=False, spoofstr=None, show_import=False, skip_sections='')

Type Default Details
obj No Content
hd_lvl NoneType None override heading level
name NoneType None override name of object ex: '@mydecorator'
objtype NoneType None override type of object. ex: 'decorator'
module_nm NoneType None override module name. ex: 'fastai.vision'
decorator bool False same as setting objtype = 'decorator'
spoofstr NoneType None Spoof the signature
show_import bool False show import statement
skip_sections str "" list of sections to skip, one or more of 'Parameters', 'Attributes', 'Returns', 'Yields', 'Raises'

ShowDoc will render the function signature as well as other info that may help you author documentation for a function, method, or class in a notebook:

Below, we render the docs for a class:

ShowDoc(ex.ExampleClass)

class ExampleClass (param1, param2, param3)

The summary line for a class docstring should fit on one line.

If the class has public attributes, they may be documented here
in an ``Attributes`` section and follow the same formatting as a
function's ``Args`` section. Alternatively, attributes may be documented
inline with the attribute's declaration (see __init__ method below).

Properties created with the ``@property`` decorator should be documented
in the property's getter method.

Attributes
----------
attr1 : str
    Description of `attr1`.
attr2 : :obj:`int`, optional
    Description of `attr2`.

There is a special override for decorators:

ShowDoc(ex.ExampleClass, decorator=True, name='example')

decorator @example (...)

The summary line for a class docstring should fit on one line.

If the class has public attributes, they may be documented here
in an ``Attributes`` section and follow the same formatting as a
function's ``Args`` section. Alternatively, attributes may be documented
inline with the attribute's declaration (see __init__ method below).

Properties created with the ``@property`` decorator should be documented
in the property's getter method.

Attributes
----------
attr1 : str
    Description of `attr1`.
attr2 : :obj:`int`, optional
    Description of `attr2`.

There is also a special override for the module name:

ShowDoc(ex.ExampleClass, decorator=True, name='example', module_nm='mymodule.foo')

decorator @example (...)

The summary line for a class docstring should fit on one line.

If the class has public attributes, they may be documented here
in an ``Attributes`` section and follow the same formatting as a
function's ``Args`` section. Alternatively, attributes may be documented
inline with the attribute's declaration (see __init__ method below).

Properties created with the ``@property`` decorator should be documented
in the property's getter method.

Attributes
----------
attr1 : str
    Description of `attr1`.
attr2 : :obj:`int`, optional
    Description of `attr2`.

ShowDoc(ex.ExampleClass, skip_sections='Attributes')

class ExampleClass (param1, param2, param3)

The summary line for a class docstring should fit on one line.

If the class has public attributes, they may be documented here
in an ``Attributes`` section and follow the same formatting as a
function's ``Args`` section. Alternatively, attributes may be documented
inline with the attribute's declaration (see __init__ method below).

Properties created with the ``@property`` decorator should be documented
in the property's getter method.

Attributes
----------
attr1 : str
    Description of `attr1`.
attr2 : :obj:`int`, optional
    Description of `attr2`.

Below, we render docs for method. Note that you will receive an warning if your docstrings are not able to be parsed according to the numpy format:

ShowDoc(ex.ExampleClass.example_method)
/Users/hamel/opt/anaconda3/envs/nbdoc/lib/python3.10/site-packages/numpydoc/docscrape.py:434: UserWarning: Unknown section Note in the docstring of example_method in /Users/hamel/github/nbdoc/nbs/test_lib/example.py.
  warn(msg)

method ExampleClass.example_method (param1, param2)

Class methods are similar to regular functions.

Note
----
Do not include the `self` parameter in the ``Parameters`` section.

Parameters
----------
param1
    The first parameter.
param2
    The second parameter.

Returns
-------
bool
    True if successful, False otherwise.

We can also render properties as well:

ShowDoc(ex.ExampleClass.readonly_property)

property ExampleClass.readonly_property

str: Properties should be documented in their getter method.

Finally, we can also show docs for a function. If the module associated with the object has a baseurl specified in your project's settings.ini file as described in get_base_urls, you will also see a link to the source code:

ShowDoc(test_eq)

function test_eq (a, b)[source]

`test` that `a==b`

As a debugging tool, ShowDoc.jsx extracts JSX Markup about an object so that you can use it for code documentation. Here are some examples:

_result = ShowDoc(ex.ExampleClass).jsx
assert is_valid_xml(_result)
print(_result)
<DocSection type="class" name="ExampleClass" module="test_lib.example" show_import="False" heading_level="3">
<SigArgSection>
<SigArg name="param1" /><SigArg name="param2" /><SigArg name="param3" />
</SigArgSection>
<Description summary="The summary line for a class docstring should fit on one line." extended_summary="If the class has public attributes, they may be documented here\nin an ``Attributes`` section and follow the same formatting as a\nfunction's ``Args`` section. Alternatively, attributes may be documented\ninline with the attribute's declaration (see __init__ method below).\n\nProperties created with the ``@property`` decorator should be documented\nin the property's getter method." />
<ParamSection name="Attributes">
	<Parameter name="attr1" type="str" desc="Description of `attr1`." />
	<Parameter name="attr2" type=":obj:`int`, optional" desc="Description of `attr2`." />
</ParamSection>
</DocSection>
_result = ShowDoc(ex.Foo).jsx
assert is_valid_xml(_result)
assert 'link' not in _result
print(_result)
<DocSection type="class" name="Foo" module="test_lib.example" show_import="False" heading_level="3">
<SigArgSection>
<SigArg name="a" type="int" /><SigArg name="b" type="str" default="foo" /><SigArg name="c" type="float" default="0.1" /><SigArg name="*args" /><SigArg name="**tags" />
</SigArgSection>


</DocSection>