Skip to main content

roz-remembers

A small, message-driven state management library for Python, inspired by the predictable state-container pattern popularized by Redux. It gives you a centralized, observable bag of state that you read and write through simple dot-path keys (e.g. "job.bins"), with change events you can subscribe to and optional JSON persistence.

It ships two front ends over the same dot-path engine:

  • Store — a synchronous store. Best for ordinary synchronous code that just wants central, observable runtime state without an event loop.
  • RozRemembers — an asyncio, Redux-style store driven by an action queue and an event queue. Best for long-running async applications.

Both share the exported helpers get_nested_value(path, data) and set_nested_value(path, value, data).

Installation

pip install roz-remembers

The import name is roz_remembers:

from roz_remembers import Store, RozRemembers, get_nested_value, set_nested_value

Dot-path convention

State is a nested dict, and every read/write addresses a value by a dot-separated path:

  • "user.theme" → state["user"]["theme"]
  • numeric segments index into lists: "items.0.name" → state["items"][0]["name"]
  • reads of a missing or non-traversable path return None (or your supplied default on Store.get).
  • writes auto-create intermediate dicts as needed. A write fails (returns False) only if a segment can't be traversed or assigned — e.g. a list index out of range, or trying to descend into a scalar.

Quickstart — Store (synchronous)

from roz_remembers import Store

store = Store({"job": {"bins": 10, "sorted": 0}})

# read / write by dot-path
store.set("job.sorted", 1)            # -> True
store.get("job.sorted")               # -> 1
store.get("job.missing", default=0)   # -> 0 (missing path falls back)

# writes auto-create intermediate dicts
store.set("machine.state", "CARD_READY")
store.get_state()                     # deep copy of the whole state

# subscribe to change events; subscribe() returns an unsubscribe function
def on_change(event):
    print(event["path"], event["old_value"], "->", event["new_value"])

unsubscribe = store.subscribe(on_change)
store.set("job.sorted", 2)            # -> on_change fires
unsubscribe()                         # stop receiving events

Persistence

Store reads and writes plain JSON:

store.save("state.json")                 # write current state to disk
restored = Store(state_file="state.json")  # load state at construction
restored.get("job.bins")                 # -> 10

# a Store created with state_file remembers it, so save() needs no argument
live = Store(state_file="state.json")
live.set("job.sorted", 5)
live.save()                              # persists back to state.json

Loading a missing file or malformed JSON starts from an empty state (a warning is logged) rather than raising, so a first run "just works".

Quickstart — RozRemembers (asynchronous)

RozRemembers processes actions off a queue and emits events onto another queue. You dispatch SET_STATE actions and consume STATE_CHANGED events.

import asyncio
from roz_remembers import RozRemembers

async def main():
    store = RozRemembers("initial_state.json")
    await store.load_initial_state()      # empty state if the file is absent
    store.start_processing()              # start the background action processor

    # observe state changes
    events = store.subscribe_events()     # an asyncio.Queue of event dicts

    await store.dispatch({
        "type": RozRemembers.ACTION_TYPE_SET_STATE,   # "SET_STATE"
        "path": "user.theme",
        "value": "dark",
    })

    event = await events.get()
    # {'type': 'STATE_CHANGED', 'path': 'user.theme',
    #  'old_value': None, 'new_value': 'dark', 'action_source': {...}}
    print(event["path"], "->", event["new_value"])
    print(store.get_current_state())      # deep copy of the whole state

    await store.stop_processing()

asyncio.run(main())

The subscribe / events model

  • Store notifies synchronously: each set() that changes state calls every subscriber callback with a STATE_CHANGED event ({"type", "path", "old_value", "new_value"}). A raising subscriber is logged and isolated — it won't break the store or other subscribers.
  • RozRemembers is asynchronous: subscribe_events() returns an asyncio.Queue. Each applied SET_STATE puts a STATE_CHANGED event (which also carries action_source) on that queue for your consumer coroutine to await. Actions with no path, unknown action types, and writes that can't be applied are ignored and emit no event.

Development

This is a Poetry (PEP 621) project. Tests run under pytest with a coverage gate:

pip install pytest pytest-asyncio pytest-cov
pytest        # runs the suite and enforces >=90% line coverage

pythonpath = ["src"] is set in pyproject.toml, so tests import roz_remembers directly without a manual PYTHONPATH.

License

MIT

Metadata

Release files for roz-remembers 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for roz-remembers 0.2.0
File Size Uploaded Provenance Actions
roz_remembers-0.2.0.tar.gz 7.1 kB Without provenance Details for roz_remembers-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for roz-remembers 0.2.0
File Interpreter ABI Platform Actions
roz_remembers-0.2.0-py3-none-any.whl Python 3 none any Details for roz_remembers-0.2.0-py3-none-any.whl

Total release size: 14.8 kB

Release files / roz_remembers-0.2.0.tar.gz

Download URL roz_remembers-0.2.0.tar.gz
Size 7.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4d667db39dcd6e5fadbf88398e2e552e0a382839211d652c9a7103d817896a44
BLAKE2b-256 checksum
How to use checksums
10fbad8bee5042c75e3b87cd9a9c7568ef258d764e72027a976b52e32cb307fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.04","id":"plucky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / roz_remembers-0.2.0-py3-none-any.whl

Download URL roz_remembers-0.2.0-py3-none-any.whl
Size 7.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
13120f1cee4dd1d426d3509a8887140cb29f16d44f3d55f6a48f49bcd082b15e
BLAKE2b-256 checksum
How to use checksums
712e63a9d33d7f3960ff7ae1483591338808402552debc1984ae38a4ebea0fb9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"25.04","id":"plucky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for roz-remembers 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page