0
# Jupyter Notebook Support
1
2
Conversion tools and command-line interface for working with Jupyter notebooks. Sphinx-Gallery provides bidirectional conversion between Python example scripts and Jupyter notebooks, enabling flexible documentation workflows.
3
4
## Capabilities
5
6
### Command-Line Interface
7
8
Main command-line interface for converting Python scripts to Jupyter notebooks.
9
10
```python { .api }
11
def python_to_jupyter_cli(args=None, namespace=None, sphinx_gallery_conf=None):
12
"""
13
Command-line interface for converting Python scripts to Jupyter notebooks.
14
15
Converts Python example scripts to Jupyter notebook format, preserving
16
code structure, comments, and output. Supports batch conversion of
17
multiple files and directories.
18
19
Parameters:
20
- args: list, command line arguments (optional, uses sys.argv if None)
21
- namespace: Namespace, parsed arguments object (optional)
22
- sphinx_gallery_conf: dict, gallery configuration for conversion options
23
24
Returns:
25
int: Exit code (0 for success, non-zero for error)
26
"""
27
```
28
29
#### Command-Line Usage
30
31
```bash
32
# Convert single file
33
sphinx_gallery_py2jupyter my_example.py
34
35
# Convert with output notebook name
36
sphinx_gallery_py2jupyter my_example.py -o output_notebook.ipynb
37
38
# Convert multiple files
39
sphinx_gallery_py2jupyter example1.py example2.py example3.py
40
41
# Convert with specific configuration
42
sphinx_gallery_py2jupyter my_example.py --gallery-conf-path ./conf.py
43
```
44
45
### Programmatic Conversion
46
47
Direct Python function for converting scripts to notebooks.
48
49
```python { .api }
50
def python_to_jupyter(python_src_file, example_nb_path, gallery_conf, target_dir):
51
"""
52
Convert Python script to Jupyter notebook.
53
54
Converts a Python example script to Jupyter notebook format,
55
parsing code blocks, markdown sections, and preserving structure.
56
57
Parameters:
58
- python_src_file: str, path to input Python script
59
- example_nb_path: str, path for output Jupyter notebook
60
- gallery_conf: dict, gallery configuration options
61
- target_dir: str, target directory for notebook
62
63
Returns:
64
str: Path to created notebook file
65
"""
66
```
67
68
#### Usage Example
69
70
```python
71
from sphinx_gallery.notebook import python_to_jupyter
72
73
gallery_conf = {
74
'first_notebook_cell': '# %% [markdown]\n# # Example Notebook\n',
75
'last_notebook_cell': '# %% [markdown]\n# ## Conclusion\n',
76
}
77
78
notebook_path = python_to_jupyter(
79
'examples/plot_example.py',
80
'notebooks/example.ipynb',
81
gallery_conf,
82
'notebooks/'
83
)
84
```
85
86
### Notebook Structure Creation
87
88
Function for creating basic Jupyter notebook structure.
89
90
```python { .api }
91
def jupyter_notebook_skeleton():
92
"""
93
Create basic Jupyter notebook structure.
94
95
Creates a minimal Jupyter notebook dictionary with proper
96
metadata and structure for adding cells.
97
98
Returns:
99
dict: Basic Jupyter notebook structure with metadata
100
"""
101
```
102
103
#### Generated Structure
104
105
```python
106
{
107
"cells": [],
108
"metadata": {
109
"kernelspec": {
110
"display_name": "Python 3",
111
"language": "python",
112
"name": "python3"
113
},
114
"language_info": {
115
"name": "python",
116
"version": "3.x.x"
117
}
118
},
119
"nbformat": 4,
120
"nbformat_minor": 4
121
}
122
```
123
124
### Cell Conversion Functions
125
126
Functions for converting between different cell types and formats.
127
128
```python { .api }
129
def split_code_and_text_blocks(source_file, plot_gallery, gallery_conf):
130
"""
131
Split Python script into code and text blocks.
132
133
Parses a Python script and separates executable code from
134
documentation text blocks (docstrings and comments).
135
136
Parameters:
137
- source_file: str, path to Python script
138
- plot_gallery: bool, whether to include plot execution
139
- gallery_conf: dict, gallery configuration
140
141
Returns:
142
list: List of code and text block dictionaries
143
"""
144
145
def text_to_notebook_cell(text_block):
146
"""
147
Convert text block to Jupyter markdown cell.
148
149
Parameters:
150
- text_block: str, text content for cell
151
152
Returns:
153
dict: Jupyter markdown cell structure
154
"""
155
156
def code_to_notebook_cell(code_block):
157
"""
158
Convert code block to Jupyter code cell.
159
160
Parameters:
161
- code_block: str, Python code for cell
162
163
Returns:
164
dict: Jupyter code cell structure
165
"""
166
```
167
168
## Configuration Options
169
170
### Notebook Customization
171
172
Configure notebook generation through `sphinx_gallery_conf`:
173
174
```python
175
sphinx_gallery_conf = {
176
# Add custom first cell
177
'first_notebook_cell': '''# %%
178
# Example Notebook
179
# ================
180
# This notebook was generated from a Python script.
181
''',
182
183
# Add custom last cell
184
'last_notebook_cell': '''# %%
185
# ## Next Steps
186
# Try modifying the code above and re-running the cells.
187
''',
188
189
# Control Jupyter magic promotion
190
'promote_jupyter_magic': True,
191
192
# Download format options
193
'download_all_examples': True, # Enables notebook downloads
194
}
195
```
196
197
### Cell Format Options
198
199
```python
200
sphinx_gallery_conf = {
201
# Remove configuration comments from code cells
202
'remove_config_comments_from_code': True,
203
204
# Handle special code constructs
205
'promote_jupyter_magic': True, # Convert # %% to Jupyter magic
206
207
# Preserve module imports
208
'prefer_full_module': [], # Modules to import fully rather than from import
209
}
210
```
211
212
## Advanced Usage
213
214
### Custom Cell Processing
215
216
```python
217
def custom_notebook_processor(notebook_dict, gallery_conf):
218
"""
219
Custom processor for notebook modification.
220
221
Parameters:
222
- notebook_dict: dict, Jupyter notebook structure
223
- gallery_conf: dict, gallery configuration
224
225
Returns:
226
dict: Modified notebook structure
227
"""
228
# Add custom metadata
229
notebook_dict['metadata']['custom'] = {
230
'generated_by': 'sphinx-gallery',
231
'source': 'python_script'
232
}
233
234
# Modify cells
235
for cell in notebook_dict['cells']:
236
if cell['cell_type'] == 'code':
237
# Add execution count
238
cell['execution_count'] = None
239
240
elif cell['cell_type'] == 'markdown':
241
# Process markdown content
242
cell['source'] = process_markdown(cell['source'])
243
244
return notebook_dict
245
```
246
247
### Batch Conversion
248
249
```python
250
import os
251
from sphinx_gallery.notebook import python_to_jupyter
252
253
def convert_directory(src_dir, dest_dir, gallery_conf):
254
"""Convert all Python files in directory to notebooks."""
255
256
for filename in os.listdir(src_dir):
257
if filename.endswith('.py'):
258
src_path = os.path.join(src_dir, filename)
259
nb_name = filename.replace('.py', '.ipynb')
260
dest_path = os.path.join(dest_dir, nb_name)
261
262
python_to_jupyter(src_path, dest_path, gallery_conf, dest_dir)
263
print(f"Converted {filename} to {nb_name}")
264
265
# Usage
266
gallery_conf = {'first_notebook_cell': '# Generated Notebook\n'}
267
convert_directory('examples/', 'notebooks/', gallery_conf)
268
```
269
270
### Integration with Build Process
271
272
```python
273
# conf.py
274
def custom_notebook_build(app, env, docnames):
275
"""Custom notebook generation during Sphinx build."""
276
277
gallery_conf = app.config.sphinx_gallery_conf
278
279
# Convert specific examples to notebooks
280
examples = ['plot_basic.py', 'plot_advanced.py']
281
282
for example in examples:
283
src_path = os.path.join('examples', example)
284
nb_path = os.path.join('_build/notebooks', example.replace('.py', '.ipynb'))
285
286
python_to_jupyter(src_path, nb_path, gallery_conf, '_build/notebooks')
287
288
# Connect to Sphinx events
289
def setup(app):
290
app.connect('env-before-read-docs', custom_notebook_build)
291
```
292
293
## File Format Support
294
295
### Python Script Format
296
297
Sphinx-Gallery expects Python scripts with specific structure:
298
299
```python
300
"""
301
Example Title
302
=============
303
304
This is the example description that becomes the first markdown cell.
305
306
Multiple paragraphs are supported and will be converted to markdown.
307
"""
308
309
# This comment becomes a markdown cell
310
# You can have multiple lines of comments
311
312
import matplotlib.pyplot as plt
313
import numpy as np
314
315
# Generate data
316
x = np.linspace(0, 10, 100)
317
y = np.sin(x)
318
319
# Create plot - this code becomes a code cell
320
plt.figure(figsize=(8, 6))
321
plt.plot(x, y)
322
plt.title('Sine Wave')
323
plt.show()
324
325
# %%
326
# This is a cell separator that creates explicit cell boundaries
327
# Anything after %% starts a new cell
328
329
print("This will be in a separate code cell")
330
```
331
332
### Jupyter Magic Support
333
334
Automatic conversion of Jupyter magic commands:
335
336
```python
337
# Input Python script:
338
# %matplotlib inline
339
import matplotlib.pyplot as plt
340
341
# Output notebook cell:
342
# %matplotlib inline
343
# import matplotlib.pyplot as plt
344
```
345
346
### Markdown Processing
347
348
RST-style formatting is converted to Markdown:
349
350
```python
351
"""
352
Example with RST
353
================
354
355
This section demonstrates:
356
357
* List items
358
* **Bold text**
359
* ``Code snippets``
360
361
.. note::
362
This note will be converted to markdown.
363
"""
364
```
365
366
Becomes:
367
368
```markdown
369
# Example with RST
370
371
This section demonstrates:
372
373
* List items
374
* **Bold text**
375
* `Code snippets`
376
377
> **Note:** This note will be converted to markdown.
378
```
379
380
## Troubleshooting
381
382
### Common Issues
383
384
**Cell Separation**: Use `# %%` comments to explicitly separate cells
385
**Magic Commands**: Enable `promote_jupyter_magic` for proper magic handling
386
**Image Paths**: Notebook image paths may need adjustment for relative references
387
**Execution Order**: Code cells are created in script execution order
388
389
### Debug Configuration
390
391
```python
392
sphinx_gallery_conf = {
393
'log_level': {'examples_log_level': 'DEBUG'},
394
'only_warn_on_example_error': True, # Continue on conversion errors
395
'abort_on_example_error': False, # Don't stop build on errors
396
}
397
```
398
399
### Validation
400
401
```python
402
def validate_notebook(notebook_path):
403
"""Validate generated notebook structure."""
404
import json
405
406
with open(notebook_path, 'r') as f:
407
notebook = json.load(f)
408
409
# Check required fields
410
required_fields = ['cells', 'metadata', 'nbformat', 'nbformat_minor']
411
for field in required_fields:
412
assert field in notebook, f"Missing field: {field}"
413
414
# Check cell structure
415
for i, cell in enumerate(notebook['cells']):
416
assert 'cell_type' in cell, f"Cell {i} missing cell_type"
417
assert 'source' in cell, f"Cell {i} missing source"
418
419
print(f"Notebook {notebook_path} is valid")
420
```