Skip to content
Merged
13 changes: 13 additions & 0 deletions docs/model_card.rst
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ using :meth:`.Card.select`, and you can delete sections using
To see how you can use the API in ``skops`` to create a model card, please
refer to :ref:`sphx_glr_auto_examples_plot_model_card.py`.

You can also fold sections after adding them to the model card. This is useful
if you have a lot of content in a section that you don't want to show by
default. To fold a section, you can use the :attr:`.Section.folded` property:

.. code-block:: python

section = card.select("Model description/Figures")
section.folded = True

After setting :attr:`.Section.folded` to ``True``, the section will be collapsed by default
when the model card is rendered.


Saving and Loading Model Cards
------------------------------

Expand Down
5 changes: 3 additions & 2 deletions skops/card/_model_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class Section:
content: str
subsections: dict[str, Section] = field(default_factory=dict)
visible: bool = True
folded: bool = False

def select(self, key: str) -> Section:
"""Return a subsection or subsubsection of this section
Expand Down Expand Up @@ -243,7 +244,7 @@ def select(self, key: str) -> Section:
return section

def format(self) -> str:
return self.content
return wrap_as_details(self.content, folded=self.folded)

def __repr__(self) -> str:
"""Generates the ``repr`` of this section.
Expand Down Expand Up @@ -1343,7 +1344,7 @@ def _generate_content(
if destination_path is not None and isinstance(section, PlotSection):
shutil.copy(section.path, destination_path)

if section.subsections:
if section.subsections and not section.folded:
yield from self._generate_content(
section.subsections,
depth=depth + 1,
Expand Down
44 changes: 44 additions & 0 deletions skops/card/tests/test_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,50 @@ def test_toc_with_invisible_section(self, card):
assert toc == "\n".join(exptected_toc)


class TestFoldedSection:
def test_folded_section(self, destination_path, model_card):
model_card.add(foo="Foo")
model_card.add(**{"foo/bar": "Foo/Bar", "foo/baz": "Foo/Baz"})
model_card.select("foo/baz").folded = True

foo_details = (
"<details>\n<summary> Click to expand </summary>\n\nFoo\n\n</details>\n"
)
foo_bar_details = (
"<details>\n<summary> Click to expand </summary>\n\nFoo/Bar\n\n</details>\n"
)
foo_baz_details = (
"<details>\n<summary> Click to expand </summary>\n\nFoo/Baz\n\n</details>\n"
)

output = model_card.render()
assert foo_details not in output
assert foo_bar_details not in output
assert foo_baz_details in output

model_card.select("foo").folded = True

output = model_card.render()
assert foo_details in output
assert foo_bar_details not in output
assert foo_baz_details not in output

model_card.select("foo").folded = False

output = model_card.render()
assert foo_details not in output
assert foo_bar_details not in output
assert foo_baz_details in output

Comment thread
BenjaminBossan marked this conversation as resolved.
model_card.select("foo/bar").folded = True
model_card.select("foo/baz").folded = False

output = model_card.render()
assert foo_details not in output
assert foo_bar_details in output
assert foo_baz_details not in output


class TestCardSaveWithPlots:
def test_copy_plots(self, destination_path, model_card):
import matplotlib.pyplot as plt
Expand Down