0
# IPython Integration
1
2
Seamless integration with IPython and Jupyter notebooks through magic commands and extension loading, enabling automatic C-level output capture in interactive environments.
3
4
## Capabilities
5
6
### Extension Loading
7
8
Register wurlitzer as an IPython extension for automatic C output forwarding.
9
10
```python { .api }
11
def load_ipython_extension(ip):
12
"""Register wurlitzer as an IPython extension
13
14
Args:
15
ip: IPython instance
16
17
Note:
18
Captures all C output during execution and forwards to sys.
19
Does nothing on terminal IPython.
20
"""
21
```
22
23
Usage with magic command:
24
25
```python
26
# In IPython or Jupyter notebook
27
%load_ext wurlitzer
28
29
# All subsequent cell executions will capture C-level output
30
```
31
32
### Extension Unloading
33
34
Disable wurlitzer extension and restore original output behavior.
35
36
```python { .api }
37
def unload_ipython_extension(ip):
38
"""Unload wurlitzer IPython extension
39
40
Args:
41
ip: IPython instance
42
"""
43
```
44
45
Usage:
46
47
```python
48
# Disable the extension
49
%unload_ext wurlitzer
50
51
# C-level output is no longer captured
52
```
53
54
### Automatic Execution Hooks
55
56
The extension automatically hooks into IPython's execution cycle:
57
58
- **pre_execute**: Enables C output forwarding before each cell/command
59
- **post_execute**: Disables C output forwarding after each cell/command
60
61
This ensures C-level output appears in notebook cells without manual context managers.
62
63
## Usage Patterns
64
65
### Jupyter Notebook Setup
66
67
Enable wurlitzer in a notebook for the entire session:
68
69
```python
70
# First cell - setup
71
%load_ext wurlitzer
72
73
# Verify it's working
74
import ctypes
75
libc = ctypes.CDLL(None)
76
libc.printf(b"Hello from C!\n") # This will appear in cell output
77
```
78
79
### Scientific Computing Workflows
80
81
Capture output from scientific libraries with C extensions:
82
83
```python
84
# With wurlitzer extension loaded
85
import numpy as np
86
import scipy
87
88
# NumPy/SciPy C-level warnings and output appear in cells
89
result = np.linalg.solve(large_matrix, vector)
90
scipy_result = scipy.optimize.minimize(objective_function, initial_guess)
91
```
92
93
### Data Analysis Notebooks
94
95
Clean output capture for data processing pipelines:
96
97
```python
98
# Extension enabled at notebook start
99
%load_ext wurlitzer
100
101
import pandas as pd
102
import matplotlib.pyplot as plt
103
from some_c_library import process_data
104
105
# All C-level output from data processing appears inline
106
processed_data = process_data(raw_dataframe)
107
plt.plot(processed_data) # Any C output from matplotlib backends captured
108
```
109
110
### Development and Debugging
111
112
Interactive development with C extensions:
113
114
```python
115
# Debug session in Jupyter
116
%load_ext wurlitzer
117
118
# Test C extension interactively
119
import my_c_extension
120
121
# C debug output, warnings, and errors appear in notebook
122
my_c_extension.debug_function()
123
my_c_extension.test_algorithm(test_data)
124
```
125
126
## Environment Detection
127
128
The extension includes smart environment detection:
129
130
### Jupyter Kernel Detection
131
132
Only activates in Jupyter environments, not terminal IPython:
133
134
```python
135
# This code runs automatically when extension loads
136
if not getattr(ip, 'kernel', None):
137
warnings.warn("wurlitzer extension doesn't do anything in terminal IPython")
138
return
139
140
# Extension only works in Jupyter kernels
141
```
142
143
### Stream Validation
144
145
Validates that sys streams are available for forwarding:
146
147
```python
148
# Automatic validation during extension loading
149
for name in ("__stdout__", "__stderr__"):
150
if getattr(sys, name) is None:
151
warnings.warn(f"sys.{name} is None. Wurlitzer can't capture output without it.")
152
return
153
```
154
155
## Advanced Integration Patterns
156
157
### Conditional Loading
158
159
Load the extension based on environment or configuration:
160
161
```python
162
import os
163
164
# Load only in specific environments
165
if os.getenv('JUPYTER_ENABLE_WURLITZER', '').lower() == 'true':
166
%load_ext wurlitzer
167
print("Wurlitzer enabled for C output capture")
168
```
169
170
### Notebook Configuration
171
172
Add to IPython profile for automatic loading:
173
174
```python
175
# In ~/.ipython/profile_default/ipython_config.py
176
c.InteractiveShellApp.extensions = ['wurlitzer']
177
178
# Or in startup files
179
# ~/.ipython/profile_default/startup/00-wurlitzer.py
180
get_ipython().magic('load_ext wurlitzer')
181
```
182
183
### Custom Extension Integration
184
185
Combine with other IPython extensions:
186
187
```python
188
# Custom extension that includes wurlitzer
189
from IPython.core.magic import Magics, line_magic, magics_class
190
from wurlitzer import load_ipython_extension, unload_ipython_extension
191
192
@magics_class
193
class CustomMagics(Magics):
194
195
@line_magic
196
def enable_c_capture(self, line):
197
"""Enable C output capture"""
198
load_ipython_extension(self.shell)
199
print("C output capture enabled")
200
201
@line_magic
202
def disable_c_capture(self, line):
203
"""Disable C output capture"""
204
unload_ipython_extension(self.shell)
205
print("C output capture disabled")
206
207
# Register the custom extension
208
get_ipython().register_magic_function(CustomMagics)
209
```
210
211
### Widget Integration
212
213
Use with Jupyter widgets for interactive applications:
214
215
```python
216
import ipywidgets as widgets
217
from IPython.display import display
218
219
# Extension loaded
220
%load_ext wurlitzer
221
222
def on_button_click(b):
223
with widgets.Output():
224
# C output appears in widget output area
225
c_processing_function()
226
display("Processing complete")
227
228
button = widgets.Button(description="Run C Function")
229
button.on_click(on_button_click)
230
output = widgets.Output()
231
232
display(button, output)
233
```
234
235
## Error Handling
236
237
### Extension Loading Failures
238
239
Handle cases where extension cannot be loaded:
240
241
```python
242
try:
243
%load_ext wurlitzer
244
print("Wurlitzer extension loaded successfully")
245
except Exception as e:
246
print(f"Failed to load wurlitzer extension: {e}")
247
print("C output may not be captured in this environment")
248
```
249
250
### Fallback Strategies
251
252
Provide fallbacks when extension is not available:
253
254
```python
255
def setup_c_output_capture():
256
try:
257
get_ipython().magic('load_ext wurlitzer')
258
return True
259
except:
260
# Fallback to manual context managers
261
print("Using manual wurlitzer context managers")
262
return False
263
264
# Usage
265
auto_capture = setup_c_output_capture()
266
267
if not auto_capture:
268
# Manual capture when extension not available
269
from wurlitzer import sys_pipes
270
with sys_pipes():
271
c_function_call()
272
else:
273
# Extension handles capture automatically
274
c_function_call()
275
```
276
277
### State Management
278
279
Track extension state for complex notebooks:
280
281
```python
282
import wurlitzer
283
284
def check_extension_state():
285
"""Check if wurlitzer extension is currently active"""
286
return wurlitzer._extension_enabled
287
288
# Usage
289
if check_extension_state():
290
print("Wurlitzer extension is active")
291
# C output will be automatically captured
292
else:
293
print("Wurlitzer extension is not active")
294
# Need manual capture or load extension
295
```