0

I'm wanting a simple way to show rich HTML documentation of a python object in a Jupyter Notebook or JupyterLab context. It's possible this already exists. I basically want what Jupyter/IPython does when you call ? on an object, except I want it as an inline HTML output.

The ability to generate a nice summary of a function or class's documentation exists in the builtin help function. This text can be accessed directly with pydoc.render_doc. When I looked for an HTML version of this, I found that all you have to do is specify an HTML renderer (shown below). Coupling this with the IPython rich display system (implementing _repr_html_()) I made a simple class:

from pydoc import render_doc, HTMLDoc

class doc:
    def __init__(self, obj):
        self.obj = obj

    def _repr_html_(self):
        return render_doc(self.obj, renderer=HTMLDoc())

Which, when I run in the "Classic" Jupyter Notebook looks like this:

screenshot of pydoc HTML output in Jupyter

If I run the same in JupyterLab with dark theme I see this:

enter image description here

I don't like that it is right aligned, that it appears to be using the Notebook's warning color, and that some elements aren't visible in the dark theme of JupyterLab. Content also falls off the right margin and gets clipped, so the right alignment doesn't appear to work well. In the figure below I had to scroll the cell output to the right to see the overflowing text. 2/3 of the page is un-used to the left of that docstring, so it doesn't make any sense for it to overflow.

enter image description here

I think what I want is just the HTML output rendered as if it didn't inherit the notebook's CSS styles, so that it would look the same as if I opened the document in it's own tab. If these are shortcomings of pydoc, then that's understandable. It just seems like this should be quite doable with existing code from either pydoc, Jupyter, sphinx, or something.

I see things described in this question, but I don't know how to implement any of those answers within a _repr_html_() method or within an IPython.display.HTML context. My CSS knowledge is rudimentary.

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
flutefreak7
  • 2,321
  • 5
  • 29
  • 39

2 Answers2

1

Instead of relying on the default HTML display renderer in Jupyter notebook, I write the documentation into a temporary HTML file, then display it using IFrame. The output looks much better.

If necessary, additional line of codes can be written to delete the temporary HTML file after the display.

Code

from pydoc import render_doc, HTMLDoc
from IPython.display import IFrame
from IPython.core.display import display

class doc:
    def __init__(self, obj):
        self.obj = obj

    def display(self):
        with open('temp.html', 'w') as outfile:
            outfile.write(render_doc(self.obj, renderer=HTMLDoc()))
        display(IFrame('temp.html', '100%', '300px'))

Output Display

QuantStats
  • 1,448
  • 1
  • 6
  • 14
0

According to https://github.com/ipython/ipython/issues/5021 the solution is the flag metadata=dict(isolated=True)

e.g.

from pydoc import render_doc, HTMLDoc

HTML(render_doc(list, renderer=HTMLDoc()), metadata=dict(isolated=True))

works for me, although the pink background remains, because (incredibly) it is there by design. See https://svn.python.org/projects/python/trunk/Lib/pydoc.py

        return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)

It can be removed via css:

from pydoc import render_doc, HTMLDoc
from IPython.core.display import HTML

unstyle = "<style>tr {background: none !important; }</style>"
HTML(unstyle + render_doc(list, renderer=HTMLDoc()), metadata=dict(isolated=True))