Python SDK
Decorate a function, call it, and get the result back — Lakeshore handles the rest.
Install
The distribution is dreamlake-lakeshore (hyphen); the import path is
dreamlake.lakeshore (dot). import lakeshore is not a thing —
dreamlake is an implicit namespace package, so there is no top-level
lakeshore module.
Python 3.11 or newer. The runtime dependencies are small and pure-Python:
cloudpickle, httpx, msgpack, params-proto, python-ulid,
pyyaml, typing-extensions.
Verify the install, and read the version from importlib.metadata —
dreamlake.lakeshore.__version__ is a hardcoded "0.0.0" placeholder
that does not track releases:
Extras
| Extra | Pulls in |
|---|---|
test | pytest, pytest-xdist |
dev | test plus build, ruff |
server | nothing today — a reserved, deliberately empty extra |
all | test + server + dev |
pyproject.toml declares no [project.scripts]. There is no
lakeshore-daemon command — it was retired in 0.3.6. Run a worker with
python -m dreamlake.lakeshore.daemon, or through the TypeScript CLI
(lakeshore worker start, npm @dreamlake/lakeshore). See
Dispatch planes.
One pattern, end to end
The list comprehension is the spawn; the result loop is the barrier. There is no Future type — a pending job is its invocation id, a plain string you can persist and reconnect with from any process.
The SDK has no gather, no as_completed, and no Future class. Fan-out
is a comprehension of submit calls plus a loop of q.result; on the
async Queue, stdlib asyncio.gather composes over q.result coroutines.
Data UDFs in one breath
A data UDF reads and writes files through dls.run and returns plain
string keys. File bytes never ride the msgpack wire — only keys do.
Surfaces
| Surface | Read for |
|---|---|
@udf decorator | One decorator, four body kinds (sync / async / generator / async-gen), the dls.run I/O seam, the return-your-keys contract, and function transport. |
| Queue API | SyncQueue (blocking) and Queue (async) — submit / result / call / stream, worker verbs, and Topic pub/sub over the frame journal. |
| Invocation ids | The no-Future model: ids as durable handles, reconnect-by-id, fan-out + collect, and live streaming via q.stream. |
| Dispatch planes | The minimal local plane (Dispatch) for dev and tests, HttpDispatch against the Node control plane, and the run_worker loop. |
What's exported
dreamlake.lakeshore.__all__ is exactly these 22 names:
Imports are lazy (PEP 562): import dreamlake.lakeshore loads almost
nothing, and purely local code (bare @udf, dls.scope, dls.run)
never pulls in httpx or msgpack.
dls.run is the I/O proxy for the ambient run context —
dls.run.read / dls.run.write / dls.run.read_all /
dls.run.write_all / dls.run.prefix / dls.run.root. It does not run
anything. The entry points that execute work are UDF.__call__,
.submit, .remote, .local, the queue verbs, and dls.run_worker.
Runnable examples
The SDK repo ships seven zero-infrastructure examples that run on an
in-memory Dispatch(":memory:") plane — no control plane, no daemon:
| Example | Shows |
|---|---|
examples/00_hello_udf.py | submit → run_worker(once=True) → result |
examples/01_fan_out.py | N submits, collect by id |
examples/02_pipeline.py | two stages, the DAG is ordinary Python |
examples/03_body_kinds.py | sync / async / generator / async-generator |
examples/04_ids_not_futures.py | ids as durable handles |
examples/05_streams_topics.py | q.stream frames and Topic pub/sub |
examples/06_dynamic_graph.py | work discovered at run time |
Try it end-to-end
Walk the happy paths — five flows from "the decorator works, no network" up to storage access from a worker.