Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions components/persistent_data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,46 @@ settings file, or for host-side tests of migrations. It is not in the Python
bindings: `PersistentData` is a class template over the application's own
types, which the generated bindings cannot instantiate generically.

## Python

The espp Python package ships `espp.persistent_data`, a pure-Python (stdlib
only) counterpart that reads and writes the same files: schema versions are
dataclasses, newest first, with width aliases for the numeric fields and a
`migrate()` classmethod per version, exactly mirroring the C++ type list. The
layout fingerprint is derived from the annotations by the grammar above, so a
file written in Python verifies on the device and vice versa.

```python
from dataclasses import dataclass, field
from typing import ClassVar
from espp.persistent_data import PersistentData, u8, u32, f32

@dataclass
class SettingsV1:
VERSION: ClassVar[int] = 1
brightness: u8 = 50
device_name: str = "espp"

@dataclass
class Settings:
VERSION: ClassVar[int] = 2
device_name: str = "espp"
brightness: f32 = 0.5
favorites: list[str] = field(default_factory=list)

@classmethod
def migrate(cls, v1: SettingsV1) -> "Settings":
return cls(device_name=v1.device_name, brightness=v1.brightness / 100)

settings = PersistentData([Settings, SettingsV1], "settings.bin")
data = settings.load_or_create(Settings()) # migrates a v1 file and rewrites it
settings.update(lambda s: s.favorites.append("red"))
```

Errors are `PersistentDataError` with an `errc` matching `PersistentDataErrc`.
The codec is byte-checked against vectors generated by the C++ codec in
`python/persistent_data_test.py`.

## Host test

The file format, version list, migration chain and file helpers live in
Expand Down
4 changes: 4 additions & 0 deletions lib/python_bindings/espp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
# ``espp.rtps.Publisher`` / ``espp.rtps.Subscriber``).
from . import rtps # noqa: F401,E402

# Pure-Python counterpart of the persistent_data component: reads / writes the
# firmware's versioned settings files from dataclasses (``espp.persistent_data``).
from . import persistent_data # noqa: F401,E402

# The pure-python ODrive legacy-native protocol CLIENT (espp_odrive, sourced
# from components/odrive_native/python) ships alongside this package in the
# wheel / installed prefix; expose it as ``espp.odrive`` for convenience. The
Expand Down
Loading
Loading