How do I display __doc__ string of Parameterized Class in my Panel App?

I would like to include the __doc__ string of a Parameterized class in my application for … documentation and reference purposes.

But when I display it, it contains a lot of “special” (ansi?) characters.

How do I display it nicely in my application?

from panel.template.fast.list import FastListTemplate
import param
import panel as pn

ACCENT_COLOR = "#0072B5"
pn.state.sizing_mode="stretch_width"

class ClassificationPlot(param.Parameterized):
    """The ClassificationPlot provides plots the output of a classification, i.e. the *labels*
    and their *score*.
    """
    output_json = param.List(doc="""
    The ouput of the classification""")
    options = param.Dict(constant=True, doc="""
    The configuration used to construct the plot""")
    color = param.Color(ACCENT_COLOR, doc="""
    The colors of the bars""")
    theme = param.Selector(default="default", objects=["default", "dark"], doc="""
    The theme, i.e. 'default' or 'dark'. This is automatically set from pn.state.session_args""")

plot = ClassificationPlot()
card = pn.layout.Card(
    plot.__doc__, header="ClassificationPlot", sizing_mode="stretch_width"
)

FastListTemplate(
    title="ClassificationPlot", main=[card], accent_base_color=ACCENT_COLOR, header_background=ACCENT_COLOR
).servable()

I found a solution using the ansiconv package.

The only downside is that it introduces an additional dependency.

I don’t yet know how to get a nice styling for “default”/ “light” themed apps.

"""The ClassificationPlot plots the `output_json` of a classification

- It automatically determines the `theme` from the query args
- It allows you to change the color
"""
from panel.template.fast.list import FastListTemplate
import param
import panel as pn

ACCENT_COLOR = "#0072B5"
pn.state.sizing_mode="stretch_width"

class ClassificationPlot(param.Parameterized):
    """The ClassificationPlot provides plots the output of a classification, i.e. the *labels*
    and their *score*.
    """
    output_json = param.List(doc="""
    The ouput of the classification""")
    options = param.Dict(constant=True, doc="""
    The configuration used to construct the plot""")
    color = param.Color(ACCENT_COLOR, doc="""
    The colors of the bars""")
    theme = param.Selector(default="default", objects=["default", "dark"], doc="""
    The theme, i.e. 'default' or 'dark'. This is automatically set from pn.state.session_args""")

plot = ClassificationPlot()

def to_html(txt):
    import ansiconv

    html = ansiconv.to_html(txt)
    css = ansiconv.base_css()

    html = f"""
    <style>{css}</style>
    <pre class="ansi_fore ansi_back">{html}</pre>
    """
    return pn.pane.HTML(html)

card = pn.layout.Card(
    to_html(plot.__doc__), header="ClassificationPlot", sizing_mode="stretch_width"
)

FastListTemplate(
    title="ClassificationPlot", main=[card], accent_base_color=ACCENT_COLOR, header_background=ACCENT_COLOR
).servable()

The video shows the full app. The simple app here unfortunately does not layout the card very well.

An alternative that does not introduce the ansiconv dependency is to use the Terminal widget.

from panel.template.fast.list import FastListTemplate
import param
import panel as pn

ACCENT_COLOR = "#0072B5"
pn.state.sizing_mode="stretch_width"

class ClassificationPlot(param.Parameterized):
    """The ClassificationPlot provides plots the output of a classification, i.e. the *labels*
    and their *score*.
    """
    output_json = param.List(doc="""
    The ouput of the classification""")
    options = param.Dict(constant=True, doc="""
    The configuration used to construct the plot""")
    color = param.Color(ACCENT_COLOR, doc="""
    The colors of the bars""")
    theme = param.Selector(default="default", objects=["default", "dark"], doc="""
    The theme, i.e. 'default' or 'dark'. This is automatically set from pn.state.session_args""")

plot = ClassificationPlot()

def to_html(txt):
    import ansiconv

    html = ansiconv.to_html(txt)
    css = ansiconv.base_css()

    html = f"""
    <style>{css}</style>
    <pre class="ansi_fore ansi_back">{html}</pre>
    """
    return pn.pane.HTML(html)

doc_terminal = pn.widgets.Terminal(plot.__doc__, height=400)
card = pn.layout.Card(
    doc_terminal, header="ClassificationPlot", sizing_mode="stretch_width"
)

FastListTemplate(
    title="ClassificationPlot", main=[card], accent_base_color=ACCENT_COLOR, header_background=ACCENT_COLOR
).servable()

Unfortunately the Terminal widget does not always show the string. I’ve filed a bug Terminal does not always show output on first render · Issue #2923.