Python state, React UI.
Project description
RemoteState - Python Library
remotestate is the Python runtime for RemoteState apps. It owns the state store, service methods, and server that expose Python state to React.
If you want the high-level product overview, start with the repository root README: RemoteState
Install
pip install remotestate
Or with pixi:
pixi add remotestate
Development
- Python
>= 3.12 - from the package directory:
cd remotestate-py - install dependencies with
pixi install - run tests with
pixi run tests - lint with
pixi run lint - format with
pixi run format - reorder imports with
pixi run isort - type-check with
pixi run mypy - build a wheel with
pixi run build
Quick Start
import remotestate as rs
class CounterService(rs.Service):
def __init__(self) -> None:
super().__init__(rs.Store({"count": 0, "user": {"name": "forman"}}))
@rs.action
async def increment(self) -> None:
self.store.set("count", self.store.get("count") + 1)
@rs.query
async def compute(self, x: float) -> float:
self.notify(name="Computing", detail="reading current count", progress=50)
return x * self.store.get("count")
rs.serve(CounterService(), ui_dist="my-ui/dist")
API Overview
The public Python API is exported from remotestate:
StoreServiceServeResultactionqueryservepath
Store
Store(initial, *, default_factory=None) holds the Python-side application state.
-
the root state is a mapping
-
nested dicts, lists, Pydantic models, and dataclasses are all supported
-
default_factoryreceives the missing prefix as ars.path.Pathtuple -
get(path, require=False)reads a value from a path such asuser.nameoritems[0].label -
set(path, value)writes a value and notifies subscribers -
subscribe(callback)receives batched path-to-value updates after changes flush -
default_factorycan materialize missing parents while setting nested values
import remotestate as rs
class User:
def __init__(self, name: str = "", city: str = "") -> None:
self.name = name
self.city = city
def defaults(path: rs.path.Path):
if path == (rs.path.Property("user"),):
return User()
if path == (rs.path.Property("items"),):
return []
return {}
store = rs.Store({}, default_factory=defaults)
store.set("user.city", "Hamburg")
store.set("items[0].label", "foo")
assert store.get("user.city") == "Hamburg"
assert store.get("items") == [{"label": "foo"}]
get() never calls the default factory. Reads stay side-effect free, and missing
values return None unless require=True is passed.
Actions and Queries
Use @action for state-changing service methods and @query for read-only methods.
@actionbatchesstore.set()calls and flushes them as oneaction_resultmessage.@queryis read-only; mutating the store inside a query raisesPermissionError- sync and async methods are both supported
class Counter(rs.Service):
def __init__(self) -> None:
super().__init__(rs.Store({"count": 0}))
@rs.action
def increment(self) -> None:
self.store.set("count", self.store.get("count") + 1)
@rs.query
async def multiply(self, x: float) -> float:
self.notify(name="Working", progress=25)
return x * self.store.get("count")
Service Helpers
Service also provides built-in methods that power the generic TypeScript bridge:
get(path)reads a store value by pathset(path, value)writes a store value by pathnotify(name=None, detail=None, progress=None)emitsupdate_taskprogress messages for tracked calls
The reserved service method names are get, set, and notify. Do not reuse those names
for custom actions or queries.
Service._init_app(app) can be overridden to customize the FastAPI app when serve()
creates one.
Serving
serve(service, *, ui_dist, mounts, app, display, width, height, host, port, **uvicorn_settings)
starts the RemoteState server and connects it to a frontend bundle.
serviceis aServiceinstanceui_distcan be a local React build directory or an HTTP(S) URLmountsadds additional static pathsapplets you supply your own FastAPI appdisplaycontrols how the UI is shown:"auto","browser","notebook","none", or a callbackhostandportconfigure the backend server
By default, RemoteState chooses a free port, opens a browser outside notebooks, and renders inline inside notebooks. Re-running the same notebook cell restarts the server automatically.
serve() returns a ServeResult with the resolved URLs and server handles:
result = rs.serve(CounterService(), ui_dist="my-ui/dist", display="none")
print("Server URL: ", result.server_url)
print("WebSocket URL: ", result.ws_url)
print("UI Base URL: ", result.ui_base_url)
Paths
remotestate.path exposes the parsed path types used by Store.default_factory and other
advanced integrations:
PathPropertyIndex
RemoteState paths use a simplified JSONPath
subset without the "$." prefix:
- the root segment is an identifier
- later segments may be dotted identifiers, bracketed integer indices, or bracketed JSON string keys
- bracketed string keys may use either single or double quotes; canonical output uses double quotes
- the whole string must match the grammar; prefix parsing is not allowed
| Example | Valid? | Notes |
|---|---|---|
user |
yes | root identifier only |
items[0].label |
yes | dotted identifier plus integer index |
user["display name"] |
yes | bracketed string key |
$.user |
no | "$." prefix is not part of the syntax |
["root"] |
no | root must be an identifier |
items[01] |
no | indices are canonical integers without leading zeroes |
Use parse_path() and format_path() when you need to inspect, validate, or construct paths.
More Docs
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file remotestate-0.2.0.tar.gz.
File metadata
- Download URL: remotestate-0.2.0.tar.gz
- Upload date:
- Size: 71.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b9cb4291de2e7cb04a54c3e2a98bbc2af9d239764aa8f3b07bd3f4f5665b6fa
|
|
| MD5 |
ebc03cf02231305fc00bc32c7e8d67b3
|
|
| BLAKE2b-256 |
eb50bd94bec07b0df2e108bd31a3df33e77c43bb69491042c3dd852ecd6a8dfc
|
File details
Details for the file remotestate-0.2.0-py3-none-any.whl.
File metadata
- Download URL: remotestate-0.2.0-py3-none-any.whl
- Upload date:
- Size: 21.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3167cab9a3b8156018d765177d076bfd25bb24db3dfe590a3b1b6e3e3b8e941
|
|
| MD5 |
85b49a88253539726261831994f1fa72
|
|
| BLAKE2b-256 |
463b7855608a710a9c32927d2c747e581590da170133632c8dd2a56602304494
|