Skip to content

Commit e752d82

Browse files
committed
DOC - adding a guide on how to write examples (skrub-data#1578)
1 parent 78bcde0 commit e752d82

3 files changed

Lines changed: 251 additions & 0 deletions

File tree

CONTRIBUTING.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. _contributing:
2+
13
Contributing to skrub
24
=====================
35

@@ -59,6 +61,15 @@ To help us resolve the issue quickly, please include:
5961
- A **code snippet** that reproduces the issue, if applicable.
6062
- **Version information** for Python, skrub, and relevant dependencies (e.g., scikit-learn, numpy, pandas).
6163

64+
How to write an example?
65+
^^^^^^^^^^^^^^^^^^^^^^^^^
66+
We highly encourage contributors to add examples to the documentation
67+
when they add new features, or if they have a use case that is not yet covered
68+
in the documentation.
69+
70+
You can find a guide on how to write examples in the :ref:`example guide <tutorial_write_example>`.
71+
72+
6273
Suggesting enhancements
6374
~~~~~~~~~~~~~~~~~~~~~~~
6475

doc/development.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ facilitate learning on databases.
1414
vision
1515
about
1616
CONTRIBUTING
17+
tutorial_example
1718
RELEASE_PROCESS

doc/tutorial_example.rst

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
.. _tutorial_write_example:
2+
3+
.. |TableVectorizer| replace:: :class:`~skrub.TableVectorizer`
4+
5+
How to write an example for the gallery
6+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7+
8+
This tutorial explains to new contributors how to format their examples so that
9+
they are properly rendered in the skrub documentation gallery.
10+
11+
While examples are written in plain Python code, there are some quirks to be aware of
12+
when writing them, due to the way Sphinx and the sphinx-gallery extension work.
13+
This tutorial explains these quirks and how to work around them.
14+
15+
Location of the examples
16+
-----------------------
17+
18+
Once you decide on the subject of your example, start writing the code as a Python
19+
script. Place the script in the ``examples/`` folder of the repository. The example
20+
should be self-contained and runnable as a standalone script. The documentation is
21+
built by executing the code and generating additional content from it.
22+
23+
The name of the file should start with a number, followed by an underscore,
24+
and then a short description of the example. The number is used to order the examples
25+
in the documentation. For instance, if your example is about using the
26+
|TableVectorizer| class, you might want to name the file ``01_table_vectorizer.py``.
27+
28+
Note that the ``examples/`` folder is covered by ``pre-commit`` hooks, which run
29+
various checks on your code when you try to commit. These checks may block you from
30+
pushing.
31+
32+
Dealing with typos in the example
33+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
35+
If your code includes any kind of intentional typo, for example if you are trying
36+
to correct names by replacing a string with a typo with the new one, the
37+
``codespell`` hook will block your commit. To bypass this, update ``pyproject.toml``
38+
by adding the typo to the ``ignore-word-list`` entry in the ``tool.codespell``
39+
section. After this, commit the updated ``pyproject.toml`` file using
40+
``git commit --no-verify`` to bypass local checks so that following commits will
41+
ignore the typos.
42+
Note that without updating ``pyproject.toml``, the CI will still reject commits
43+
with typos, as it runs the same hooks that are run locally.
44+
45+
Writing the example
46+
-----------------------
47+
Your python script should start with a docstring that briefly explains what the example
48+
is about. This docstring can contain multiple paragraphs and will be rendered
49+
as a RST file in the documentation, so you can use RST syntax
50+
in it.
51+
52+
Importantly, the first line of the docstring should be the title of the example,
53+
not an RST directive (such as ``.. replace::`` or ``.. note::``). Sphinx
54+
adds a reference to the example at the top of the page using the file name as the
55+
title. Adding a directive at the top of the docstring would prevent proper HTML
56+
rendering.
57+
58+
This is an example of what the beginning of your example may look like:
59+
60+
.. code-block:: python
61+
62+
"""
63+
Title of the example
64+
====================
65+
66+
This is a brief description of the example. It can contain multiple paragraphs,
67+
and it can use RST syntax.
68+
69+
.. note::
70+
71+
You can use RST directives in the docstring, such as ``.. note::``,
72+
``.. warning::``, ``.. seealso::``, etc.
73+
74+
After the definition of the title, you may also add directives such as
75+
``.. replace::``, and they will be rendered properly. For example, you can add:
76+
77+
.. |TableVectorizer| replace:: :class:`~skrub.TableVectorizer`
78+
79+
80+
"""
81+
82+
Then, you can start writing the code for the example. The content of your Python script
83+
should be a sequence of code cells, each delimited by a line starting with ``# %%``.
84+
These code cells may contain comments, which will be rendered as rst in the final
85+
documentation.
86+
87+
After the docstring, write the code for your example as a sequence of code cells,
88+
each delimited by a line starting with ``# %%``. Comments in these cells will be
89+
rendered as RST in the final documentation.
90+
91+
.. code-block:: python
92+
93+
# %%
94+
# This is a comment that will be rendered as markdown in the final documentation.
95+
# You can use multiple lines for comments, and you can use RST syntax in them.
96+
97+
import pandas as pd
98+
from skrub import TableVectorizer
99+
100+
# %%
101+
# This is another code cell. You can write any python code here.
102+
df = pd.DataFrame({
103+
"A": [1, 2, 3],
104+
"B": ["a", "b", "c"]
105+
})
106+
tv = TableVectorizer()
107+
X = tv.fit_transform(df)
108+
print(X)
109+
110+
Running the example
111+
-------------------
112+
113+
Once you have written the code for the example (or while writing it), you can run
114+
it to see how it looks in the final documentation. Depending on your setup, you
115+
may need to install some dependencies. Refer to your IDE's documentation for more
116+
information on running interactive Python scripts. For example, VSCode documentation
117+
is available `here <https://code.visualstudio.com/docs/python/jupyter-support-py>`_.
118+
119+
Once you are happy with your example, you can submit a pull request to the repository,
120+
following the instructions in the :ref:`contributing guide <contributing>`.
121+
122+
Adding cross-references
123+
-----------------------
124+
125+
Adding cross-references to the documentation helps users find more information
126+
about the concepts and functions used in your example. This step is optional, and
127+
you may ask the maintainers for help on which cross-references to add. Good
128+
cross-references include relevant user guide sections, the documentation of the
129+
objects used in the example (like the |TableVectorizer|), or other examples.
130+
131+
You can add cross-references in the docstring and comments of your example in several ways:
132+
133+
- You can add references to the objects in the skrub API using the ``:class:`~skrub.ClassName```
134+
or ``:func:`~skrub.function_name``` directives.
135+
- If your example uses the same objects multiple times, you can define a replacement at the top
136+
of the docstring using the ``.. replace::`` directive, and then use the replacement
137+
instead of the full directive.
138+
- You can also add references to other sections of the documentation using the
139+
``:ref:`label``` directive, where ``label`` is the label of the section you want to reference.
140+
141+
142+
For example, if your example uses the |TableVectorizer| class multiple times, define
143+
a replacement at the top of the docstring. You may also want to add a reference
144+
to the user guide section about the |TableVectorizer| class. This can be done as follows:
145+
146+
.. code-block:: python
147+
148+
"""
149+
Title of the example
150+
====================
151+
152+
.. |TableVectorizer| replace:: :class:`~skrub.TableVectorizer`
153+
154+
This example demonstrates how to use the |TableVectorizer| class to vectorize a dataframe.
155+
156+
See the :ref:`user_guide_building_pipeline_index` guide for more information about the |TableVectorizer| class.
157+
"""
158+
159+
# %%
160+
import pandas as pd
161+
from skrub import TableVectorizer
162+
163+
df = pd.DataFrame({
164+
"A": [1, 2, 3],
165+
"B": ["a", "b", "c"]
166+
})
167+
tv = TableVectorizer()
168+
X = tv.fit_transform(df)
169+
print(X)
170+
171+
You may find more information on the cross-references in the
172+
`official Sphinx documentation <https://www.sphinx-doc.org/en/master/usage/referencing.html>`_.
173+
174+
175+
Generating the new documentation
176+
-------------------------------
177+
Once you have written your example and added any necessary cross-references, you can
178+
generate the new documentation to see how it looks. This can be done in two ways:
179+
180+
- You can run the commands ``make html`` or ``make html-noplot`` in the ``doc/``
181+
folder of the repository to generate the HTML documentation for the entire project.
182+
- Alternatively, you can use ``pixi run -e doc build-doc`` or ``pixi run -e doc build-doc-quick``
183+
from the root folder to generate the documentation. The advantage of using ``pixi`` is that
184+
it automatically sets up a virtual environment with the necessary dependencies, so you
185+
don't need to worry about installing them manually.
186+
187+
The ``make html`` and ``pixi run -e doc build-doc`` commands generate complete
188+
documentation by executing all example code. The ``-noplot`` (or ``-quick``)
189+
versions skip code execution, making documentation generation much faster. Use
190+
these faster versions to check formatting when you've already tested your example
191+
code locally.
192+
193+
The CI pipeline will always run the full documentation build, so you can safely
194+
use ``make html-noplot`` or ``pixi run -e doc build-doc-quick`` for local testing.
195+
196+
197+
After generating the documentation, open the ``index.html`` file in the ``doc/_build/html/``
198+
folder with a web browser to review the results. Check that:
199+
200+
- Section titles are properly formatted.
201+
- Any formatting in docstrings or comments is rendered as intended. For example,
202+
Sphinx uses spaces to delimit lists and code blocks, so if you have them in the
203+
example, make sure that they render correctly.
204+
- Cross-references are working. You can check the logs of the Sphinx
205+
generation to see if there are any broken references.
206+
207+
208+
Linking your work to examples already in the documentation
209+
----------------------------------------------------------
210+
After generating the documentation, you may want to add references to your example
211+
in other relevant parts of the documentation. This helps users find your example
212+
when reading about related topics.
213+
214+
215+
This step is done after generating the documentation because you need the final
216+
reference name, which is created dynamically from your file name. For example,
217+
if your file is named ``99_my_example.py``:
218+
219+
1. The generated files will be in ``doc/auto_examples``
220+
2. A reference file will be created at ``doc/auto_examples/99_my_example.rst``
221+
3. The reference label will be ``.. _sphx_glr_auto_examples_99_my_example.py``
222+
223+
To link to your example from other documentation pages, use:
224+
225+
.. code-block:: rst
226+
227+
:ref:`sphx_glr_auto_examples_99_my_example.py`
228+
229+
230+
231+
Merging your example
232+
-----------------------
233+
Finally, if everything looks good, commit your changes and submit a pull request
234+
to the repository. For more information, see the :ref:`contributing guide <contributing>`.
235+
236+
237+
Your PR will be reviewed by the maintainers, who may suggest changes or improvements.
238+
Once approved, it will be merged into the main branch, and your example will
239+
become part of the official documentation. Thank you!

0 commit comments

Comments
 (0)