Tutorial 1: Interactive safety
You are collecting arcade sensor readings that must stay valid integers while you experiment.
Omnipy models continuously validate data and type-mimic the wrapped Python type.
A Pydantic model is a use-once-then-discard validator; an Omnipy model is a continuous static-type repairman in a dynamic environment.
Setup
Parse and inspect
╭──────────────────╮
│ Model[list[int]] │
│ │
│ [120, 135, 142] │
╰──────────────────╯
Error + rollback demonstration
>>> before_error = readings.copy()
>>> try:
... readings.append('bonus-ticket')
... except Exception as err:
... print(type(err).__name__)
>>> after_error = readings
>>> print(before_error == after_error)
>>> readings
ValidationError
True
╭──────────────────╮
│ Model[list[int]] │
│ │
│ [120, 135, 142] │
╰──────────────────╯
Interactive mode framing
Choose based on trade-offs, not environment:
runtime.config.data.model.interactive = True: snapshot + rollback robustness.runtime.config.data.model.interactive = False: lower memory overhead and raw write speed, but no rollback after validation errors.
>>> om.runtime.config.data.model.interactive = False
>>> fast_mode = om.Model[list[int]]([10, 20, 30])
>>> try:
... fast_mode.append('VIP')
... except Exception as err:
... print(type(err).__name__)
>>> fast_mode
ValidationError
With interactive=False, Omnipy still raises a validation exception immediately, but the invalid
value remains in the model state ([10, 20, 30, 'VIP']).
╭─────────────────────╮
│ Model[list[int]] │
│ │
│ [10, 20, 30, 'VIP'] │
╰─────────────────────╯
What you learned
- Continuous validation + type mimicking keep model edits safe.
- Rollback behavior is controlled via
runtime.config.data.model.interactive.
Common pitfalls
- Assuming non-interactive mode is "strictly safer" because it still raises errors. It raises, but it does not roll back invalid mutations.
Next steps
- Continue with Tutorial 2: Nested JSON to tables.