or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animations.mdcolors-markup.mdfile-loading.mdindex.mdterminal.mdutilities.mdwidgets.mdwindow-management.md

file-loading.mddocs/

0

# File Loading and Serialization

1

2

PyTermGUI provides comprehensive file loading and serialization capabilities for widget configuration management, including YAML and JSON support for creating widgets from configuration files and persisting widget states.

3

4

## Capabilities

5

6

### File Loaders

7

8

Base file loading system with support for different formats and widget namespace management.

9

10

```python { .api }

11

class FileLoader:

12

"""Base file loader for widget configuration."""

13

14

def __init__(self):

15

"""Initialize file loader."""

16

17

def load(self, path: str) -> "WidgetNamespace":

18

"""

19

Load widget configuration from file.

20

21

Parameters:

22

- path (str): Path to configuration file

23

24

Returns:

25

WidgetNamespace containing loaded widgets

26

"""

27

28

def save(self, namespace: "WidgetNamespace", path: str):

29

"""

30

Save widget namespace to file.

31

32

Parameters:

33

- namespace (WidgetNamespace): Widgets to save

34

- path (str): Output file path

35

"""

36

37

class YamlLoader(FileLoader):

38

"""YAML file loader for widget configuration."""

39

40

def load(self, path: str) -> "WidgetNamespace":

41

"""

42

Load widgets from YAML file.

43

44

Parameters:

45

- path (str): Path to YAML file

46

47

Returns:

48

WidgetNamespace with loaded widgets

49

50

Requires:

51

PyYAML package (pip install PyYAML)

52

"""

53

54

class JsonLoader(FileLoader):

55

"""JSON file loader for widget configuration."""

56

57

def load(self, path: str) -> "WidgetNamespace":

58

"""

59

Load widgets from JSON file.

60

61

Parameters:

62

- path (str): Path to JSON file

63

64

Returns:

65

WidgetNamespace with loaded widgets

66

"""

67

```

68

69

### Widget Namespace

70

71

Container for managing collections of loaded widgets with name-based access.

72

73

```python { .api }

74

class WidgetNamespace:

75

"""Container for loaded widget configurations."""

76

77

def __init__(self, widgets: dict[str, Widget] = None):

78

"""

79

Create widget namespace.

80

81

Parameters:

82

- widgets (dict, optional): Named widget collection

83

"""

84

85

def __getitem__(self, name: str) -> Widget:

86

"""Get widget by name."""

87

88

def __setitem__(self, name: str, widget: Widget):

89

"""Set named widget."""

90

91

def __contains__(self, name: str) -> bool:

92

"""Check if widget name exists."""

93

94

@property

95

def widgets(self) -> dict[str, Widget]:

96

"""Get all widgets as dictionary."""

97

98

def add(self, name: str, widget: Widget):

99

"""Add named widget to namespace."""

100

101

def remove(self, name: str) -> Widget:

102

"""Remove and return named widget."""

103

104

def list_names(self) -> list[str]:

105

"""Get list of all widget names."""

106

```

107

108

### Serialization System

109

110

Widget serialization for saving and loading widget states and configurations.

111

112

```python { .api }

113

class Serializer:

114

"""Widget serialization and deserialization system."""

115

116

def __init__(self):

117

"""Initialize serializer."""

118

119

def dump(self, widget: Widget) -> dict:

120

"""

121

Serialize widget to dictionary.

122

123

Parameters:

124

- widget (Widget): Widget to serialize

125

126

Returns:

127

Dictionary representation of widget

128

"""

129

130

def load(self, data: dict) -> Widget:

131

"""

132

Deserialize widget from dictionary.

133

134

Parameters:

135

- data (dict): Serialized widget data

136

137

Returns:

138

Reconstructed widget instance

139

"""

140

141

def dump_to_file(self, widget: Widget, filename: str):

142

"""Save widget to file."""

143

144

def load_from_file(self, filename: str) -> Widget:

145

"""Load widget from file."""

146

147

# Global serializer instance

148

serializer: Serializer

149

```

150

151

## Configuration File Formats

152

153

### YAML Configuration

154

155

Example YAML widget configuration format:

156

157

```yaml

158

# widgets.yaml

159

main_window:

160

type: Window

161

title: "My Application"

162

width: 60

163

height: 20

164

widgets:

165

- type: Label

166

value: "[bold]Welcome to PyTermGUI"

167

- type: Container

168

widgets:

169

- type: Button

170

label: "Click Me"

171

onclick: "handle_click"

172

- type: InputField

173

prompt: "Enter text:"

174

value: ""

175

176

settings_dialog:

177

type: Window

178

title: "Settings"

179

width: 40

180

height: 15

181

widgets:

182

- type: Checkbox

183

label: "Enable sound"

184

checked: true

185

- type: Slider

186

min_value: 0

187

max_value: 100

188

value: 50

189

```

190

191

### JSON Configuration

192

193

Example JSON widget configuration format:

194

195

```json

196

{

197

"main_form": {

198

"type": "Container",

199

"width": 50,

200

"widgets": [

201

{

202

"type": "Label",

203

"value": "[210 bold]User Registration"

204

},

205

{

206

"type": "InputField",

207

"prompt": "Username:",

208

"id": "username_field"

209

},

210

{

211

"type": "InputField",

212

"prompt": "Password:",

213

"id": "password_field"

214

},

215

{

216

"type": "Button",

217

"label": "Register",

218

"onclick": "handle_register"

219

}

220

]

221

}

222

}

223

```

224

225

## Usage Examples

226

227

### Loading Widgets from YAML

228

229

```python

230

import pytermgui as ptg

231

232

# Load widgets from YAML file

233

loader = ptg.YamlLoader()

234

namespace = loader.load("widgets.yaml")

235

236

# Access loaded widgets by name

237

main_window = namespace["main_window"]

238

settings_dialog = namespace["settings_dialog"]

239

240

# Use in window manager

241

with ptg.WindowManager() as manager:

242

manager.add(main_window)

243

```

244

245

### Loading Widgets from JSON

246

247

```python

248

import pytermgui as ptg

249

250

# Load from JSON configuration

251

loader = ptg.JsonLoader()

252

namespace = loader.load("forms.json")

253

254

# Get specific widget

255

form = namespace["main_form"]

256

257

# Add to application

258

with ptg.WindowManager() as manager:

259

window = ptg.Window(form, title="Registration")

260

manager.add(window)

261

```

262

263

### Widget Serialization

264

265

```python

266

import pytermgui as ptg

267

268

# Create widget hierarchy

269

container = ptg.Container(

270

"[bold]Settings Panel",

271

"",

272

ptg.Checkbox(checked=True, label="Enable notifications"),

273

ptg.Slider(value=75, min_value=0, max_value=100),

274

ptg.Button("Save", lambda btn: print("Saved")),

275

width=40

276

)

277

278

# Serialize widget to dictionary

279

widget_data = ptg.serializer.dump(container)

280

print(widget_data)

281

282

# Save to file

283

ptg.serializer.dump_to_file(container, "settings.json")

284

285

# Later, load widget back

286

restored_container = ptg.serializer.load_from_file("settings.json")

287

```

288

289

### Dynamic Widget Creation

290

291

```python

292

import pytermgui as ptg

293

294

def create_form_from_config(config_file):

295

"""Create form widgets from configuration."""

296

loader = ptg.JsonLoader()

297

namespace = loader.load(config_file)

298

299

forms = {}

300

for name, widget in namespace.widgets.items():

301

if isinstance(widget, ptg.Container):

302

forms[name] = widget

303

304

return forms

305

306

# Load multiple forms

307

forms = create_form_from_config("forms.json")

308

309

# Create tabbed interface

310

current_form = "login"

311

312

def switch_form(form_name):

313

global current_form

314

current_form = form_name

315

# Update display logic here

316

317

# Use forms in application

318

with ptg.WindowManager() as manager:

319

window = ptg.Window(

320

forms[current_form],

321

title="Forms Demo"

322

)

323

manager.add(window)

324

```

325

326

### Configuration with Callbacks

327

328

```python

329

import pytermgui as ptg

330

331

# Define callback functions

332

def handle_submit(button):

333

print("Form submitted!")

334

335

def handle_cancel(button):

336

print("Form cancelled!")

337

338

# Callback registry for configuration files

339

CALLBACKS = {

340

"handle_submit": handle_submit,

341

"handle_cancel": handle_cancel

342

}

343

344

def load_with_callbacks(config_file):

345

"""Load widgets and bind callbacks."""

346

loader = ptg.JsonLoader()

347

namespace = loader.load(config_file)

348

349

# Process widgets to bind callbacks

350

for widget in namespace.widgets.values():

351

bind_callbacks_recursive(widget)

352

353

return namespace

354

355

def bind_callbacks_recursive(widget):

356

"""Recursively bind callbacks to widgets."""

357

if hasattr(widget, 'onclick') and isinstance(widget.onclick, str):

358

# Replace string callback name with actual function

359

callback_name = widget.onclick

360

if callback_name in CALLBACKS:

361

widget.onclick = CALLBACKS[callback_name]

362

363

# Process child widgets

364

if hasattr(widget, 'widgets'):

365

for child in widget.widgets:

366

bind_callbacks_recursive(child)

367

368

# Usage

369

namespace = load_with_callbacks("interface.json")

370

```

371

372

### Saving Widget State

373

374

```python

375

import pytermgui as ptg

376

377

class StatefulForm:

378

"""Form that can save and restore its state."""

379

380

def __init__(self):

381

self.form = ptg.Container(

382

"[bold]Stateful Form",

383

"",

384

ptg.InputField(prompt="Name:", id="name"),

385

ptg.InputField(prompt="Email:", id="email"),

386

ptg.Checkbox(id="newsletter", label="Newsletter"),

387

"",

388

ptg.Button("Save State", self.save_state),

389

ptg.Button("Load State", self.load_state),

390

width=50

391

)

392

393

def save_state(self, button):

394

"""Save current form state."""

395

ptg.serializer.dump_to_file(self.form, "form_state.json")

396

print("State saved!")

397

398

def load_state(self, button):

399

"""Restore form state."""

400

try:

401

restored_form = ptg.serializer.load_from_file("form_state.json")

402

# Update current form with restored values

403

self.update_form_values(restored_form)

404

print("State loaded!")

405

except FileNotFoundError:

406

print("No saved state found")

407

408

def update_form_values(self, restored_form):

409

"""Update form with restored values."""

410

# Implementation depends on specific widget ID matching

411

for widget in restored_form.widgets:

412

if hasattr(widget, 'id') and widget.id:

413

current_widget = self.find_widget_by_id(widget.id)

414

if current_widget:

415

# Copy values from restored widget

416

if hasattr(widget, 'value'):

417

current_widget.value = widget.value

418

if hasattr(widget, 'checked'):

419

current_widget.checked = widget.checked

420

421

# Usage

422

form = StatefulForm()

423

```