or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-widget.mdexperimental.mdfile-management.mdindex.mdipython-integration.md

ipython-integration.mddocs/

0

# IPython Integration

1

2

Cell magic support for creating virtual files and managing widget development workflows within Jupyter notebooks. This integration provides seamless development experiences with inline content management and dynamic file creation.

3

4

## Capabilities

5

6

### Extension Loading

7

8

Function to load the anywidget IPython extension, enabling cell magic functionality.

9

10

```python { .api }

11

def load_ipython_extension(ipython):

12

"""

13

Load the IPython extension for anywidget magics.

14

15

Registers the AnyWidgetMagics class with the IPython shell,

16

enabling cell magic commands for virtual file management.

17

18

Parameters:

19

ipython: IPython.core.interactiveshell.InteractiveShell instance

20

21

Usage:

22

%load_ext anywidget

23

"""

24

```

25

26

### AnyWidgetMagics Class

27

28

IPython magics class providing cell magic commands for virtual file management and widget development.

29

30

```python { .api }

31

class AnyWidgetMagics(Magics):

32

"""

33

A set of IPython magics for working with virtual files.

34

35

Provides cell magic commands that enable inline definition

36

of ES modules and CSS for widget development within notebooks.

37

"""

38

39

def __init__(self, shell):

40

"""

41

Initialize the magics with IPython shell reference.

42

43

Parameters:

44

shell: InteractiveShell instance

45

"""

46

```

47

48

### Virtual File Cell Magic

49

50

Cell magic for creating virtual files from notebook cell contents.

51

52

```python { .api }

53

def vfile(self, line: str, cell: str):

54

"""

55

Create a virtual file with the contents of the cell.

56

57

Cell magic that captures cell content and creates a virtual file

58

that can be referenced by widgets using the vfile: protocol.

59

60

Parameters:

61

line (str): Magic line containing file name argument

62

cell (str): Cell contents to store as virtual file

63

64

Usage:

65

%%vfile my-widget.js

66

function render({ model, el }) {

67

el.innerHTML = "<h1>Hello from virtual file!</h1>";

68

}

69

export default { render };

70

"""

71

```

72

73

### Virtual File Management

74

75

Line magic for clearing virtual file registry.

76

77

```python { .api }

78

def clear_vfiles(self, line: str):

79

"""

80

Clear all virtual files from the registry.

81

82

Line magic that removes all virtual files created with %%vfile,

83

useful for cleaning up development environment.

84

85

Parameters:

86

line (str): Magic line (unused)

87

88

Usage:

89

%clear_vfiles

90

"""

91

```

92

93

## Usage Examples

94

95

### Loading the Extension

96

97

```python

98

# Load anywidget IPython extension

99

%load_ext anywidget

100

101

# Alternative: Load programmatically

102

import anywidget

103

anywidget.load_ipython_extension(get_ipython())

104

```

105

106

### Basic Virtual File Creation

107

108

```python

109

# Create virtual JavaScript file

110

%%vfile counter.js

111

function render({ model, el }) {

112

let count = () => model.get("value");

113

let btn = document.createElement("button");

114

btn.innerHTML = `Count: ${count()}`;

115

116

btn.addEventListener("click", () => {

117

model.set("value", count() + 1);

118

});

119

120

model.on("change:value", () => {

121

btn.innerHTML = `Count: ${count()}`;

122

});

123

124

el.appendChild(btn);

125

}

126

export default { render };

127

```

128

129

```python

130

# Create virtual CSS file

131

%%vfile counter.css

132

button {

133

background: #007cba;

134

color: white;

135

border: none;

136

padding: 10px 20px;

137

border-radius: 5px;

138

cursor: pointer;

139

font-size: 16px;

140

transition: background-color 0.2s;

141

}

142

143

button:hover {

144

background: #005a8b;

145

}

146

```

147

148

```python

149

# Use virtual files in widget

150

import anywidget

151

import traitlets as t

152

153

class CounterWidget(anywidget.AnyWidget):

154

_esm = "vfile:counter.js" # Reference virtual file

155

_css = "vfile:counter.css" # Reference virtual file

156

157

value = t.Int(0).tag(sync=True)

158

159

widget = CounterWidget()

160

widget # Displays counter with styling from virtual files

161

```

162

163

### Dynamic Widget Development

164

165

```python

166

# Define widget template

167

%%vfile template.js

168

function render({ model, el }) {

169

let template = model.get("template");

170

let data = model.get("data");

171

172

// Simple template rendering

173

let html = template.replace(/\{\{(\w+)\}\}/g, (match, key) => {

174

return data[key] || match;

175

});

176

177

el.innerHTML = html;

178

179

model.on("change", () => {

180

let newTemplate = model.get("template");

181

let newData = model.get("data");

182

let newHtml = newTemplate.replace(/\{\{(\w+)\}\}/g, (match, key) => {

183

return newData[key] || match;

184

});

185

el.innerHTML = newHtml;

186

});

187

}

188

export default { render };

189

```

190

191

```python

192

import anywidget

193

import traitlets as t

194

195

class TemplateWidget(anywidget.AnyWidget):

196

_esm = "vfile:template.js"

197

198

template = t.Unicode("<h1>{{title}}</h1><p>{{message}}</p>").tag(sync=True)

199

data = t.Dict({"title": "Hello", "message": "World"}).tag(sync=True)

200

201

widget = TemplateWidget()

202

widget.data = {"title": "Dynamic Title", "message": "This content updates!"}

203

```

204

205

### Interactive Development Workflow

206

207

```python

208

# Create interactive chart widget

209

%%vfile chart.js

210

function render({ model, el }) {

211

// Simple bar chart implementation

212

let data = model.get("data");

213

let options = model.get("options");

214

215

let renderChart = () => {

216

el.innerHTML = "";

217

218

let container = document.createElement("div");

219

container.style.display = "flex";

220

container.style.alignItems = "end";

221

container.style.height = "200px";

222

container.style.padding = "20px";

223

container.style.background = options.background || "#f9f9f9";

224

225

data.forEach((value, index) => {

226

let bar = document.createElement("div");

227

bar.style.width = "30px";

228

bar.style.height = `${value * 2}px`;

229

bar.style.background = options.barColor || "#007cba";

230

bar.style.margin = "0 2px";

231

bar.style.display = "flex";

232

bar.style.alignItems = "end";

233

bar.style.justifyContent = "center";

234

bar.style.color = "white";

235

bar.style.fontSize = "12px";

236

bar.textContent = value;

237

238

container.appendChild(bar);

239

});

240

241

el.appendChild(container);

242

};

243

244

model.on("change", renderChart);

245

renderChart();

246

}

247

export default { render };

248

```

249

250

```python

251

import anywidget

252

import traitlets as t

253

254

class ChartWidget(anywidget.AnyWidget):

255

_esm = "vfile:chart.js"

256

257

data = t.List([]).tag(sync=True)

258

options = t.Dict({}).tag(sync=True)

259

260

# Create chart

261

chart = ChartWidget(

262

data=[10, 25, 15, 30, 45, 20],

263

options={"background": "#f0f0f0", "barColor": "#e74c3c"}

264

)

265

chart

266

267

# Update data interactively

268

chart.data = [5, 35, 25, 40, 15, 50]

269

chart.options = {"background": "#ffffff", "barColor": "#2ecc71"}

270

```

271

272

### Prototyping Complex Widgets

273

274

```python

275

# Create data table widget

276

%%vfile datatable.js

277

function render({ model, el }) {

278

let columns = model.get("columns");

279

let rows = model.get("rows");

280

281

let renderTable = () => {

282

let table = document.createElement("table");

283

table.style.width = "100%";

284

table.style.borderCollapse = "collapse";

285

table.style.fontFamily = "Arial, sans-serif";

286

287

// Header

288

let thead = document.createElement("thead");

289

let headerRow = document.createElement("tr");

290

headerRow.style.background = "#f8f9fa";

291

292

columns.forEach(col => {

293

let th = document.createElement("th");

294

th.textContent = col;

295

th.style.padding = "12px";

296

th.style.textAlign = "left";

297

th.style.borderBottom = "2px solid #dee2e6";

298

headerRow.appendChild(th);

299

});

300

301

thead.appendChild(headerRow);

302

table.appendChild(thead);

303

304

// Body

305

let tbody = document.createElement("tbody");

306

307

rows.forEach((row, index) => {

308

let tr = document.createElement("tr");

309

tr.style.background = index % 2 === 0 ? "#ffffff" : "#f8f9fa";

310

311

columns.forEach(col => {

312

let td = document.createElement("td");

313

td.textContent = row[col] || "";

314

td.style.padding = "12px";

315

td.style.borderBottom = "1px solid #dee2e6";

316

tr.appendChild(td);

317

});

318

319

tbody.appendChild(tr);

320

});

321

322

table.appendChild(tbody);

323

324

el.innerHTML = "";

325

el.appendChild(table);

326

};

327

328

model.on("change", renderTable);

329

renderTable();

330

}

331

export default { render };

332

```

333

334

```python

335

import anywidget

336

import traitlets as t

337

338

class DataTableWidget(anywidget.AnyWidget):

339

_esm = "vfile:datatable.js"

340

341

columns = t.List([]).tag(sync=True)

342

rows = t.List([]).tag(sync=True)

343

344

# Sample data

345

data_table = DataTableWidget(

346

columns=["Name", "Age", "City", "Score"],

347

rows=[

348

{"Name": "Alice", "Age": 30, "City": "New York", "Score": 85},

349

{"Name": "Bob", "Age": 25, "City": "San Francisco", "Score": 92},

350

{"Name": "Charlie", "Age": 35, "City": "Chicago", "Score": 78},

351

{"Name": "Diana", "Age": 28, "City": "Austin", "Score": 88}

352

]

353

)

354

data_table

355

```

356

357

### Virtual File Management

358

359

```python

360

# Clear all virtual files

361

%clear_vfiles

362

363

# Verify files are cleared

364

print("Virtual files cleared")

365

366

# Re-create files as needed

367

%%vfile simple.js

368

function render({ model, el }) {

369

el.innerHTML = "<p>Simple widget after clearing files</p>";

370

}

371

export default { render };

372

```

373

374

### Advanced Virtual File Patterns

375

376

```python

377

# Create reusable component library

378

%%vfile components.js

379

// Reusable UI components

380

export function createButton(text, onClick) {

381

let btn = document.createElement("button");

382

btn.textContent = text;

383

btn.style.cssText = `

384

background: #007cba;

385

color: white;

386

border: none;

387

padding: 8px 16px;

388

border-radius: 4px;

389

cursor: pointer;

390

margin: 4px;

391

`;

392

btn.addEventListener("click", onClick);

393

return btn;

394

}

395

396

export function createInput(placeholder, onChange) {

397

let input = document.createElement("input");

398

input.placeholder = placeholder;

399

input.style.cssText = `

400

padding: 8px;

401

border: 1px solid #ccc;

402

border-radius: 4px;

403

margin: 4px;

404

`;

405

input.addEventListener("input", (e) => onChange(e.target.value));

406

return input;

407

}

408

```

409

410

```python

411

# Use component library in widget

412

%%vfile app.js

413

import { createButton, createInput } from "vfile:components.js";

414

415

function render({ model, el }) {

416

let value = model.get("value");

417

418

let input = createInput("Enter text", (newValue) => {

419

model.set("value", newValue);

420

});

421

422

let button = createButton("Clear", () => {

423

model.set("value", "");

424

input.value = "";

425

});

426

427

let display = document.createElement("div");

428

display.style.cssText = "margin: 10px; padding: 10px; background: #f0f0f0;";

429

430

let updateDisplay = () => {

431

display.textContent = `Current value: ${model.get("value")}`;

432

};

433

434

model.on("change:value", updateDisplay);

435

updateDisplay();

436

437

el.appendChild(input);

438

el.appendChild(button);

439

el.appendChild(display);

440

}

441

export default { render };

442

```

443

444

```python

445

import anywidget

446

import traitlets as t

447

448

class ComponentWidget(anywidget.AnyWidget):

449

_esm = "vfile:app.js"

450

451

value = t.Unicode("").tag(sync=True)

452

453

widget = ComponentWidget()

454

widget

455

```