Lakeshore
Lakeshore runs Python functions somewhere other than the machine in
front of you. You decorate a function with @udf, call it, and the
result comes back — Lakeshore packs the arguments, hands the work to a
queue, and a worker somewhere else runs it and returns the value.
You'd reach for it when the work doesn't fit locally: a GPU job, a long sweep, a fan-out of identical calls. You write Python; Lakeshore owns the queueing, the transport, and the worker side.
Material that describes Lakeshore as part of DreamLake has moved to the Lakeshore tab at docs.dreamlake.ai/lakeshore — the provider pages, the Python architecture overview, and the newer pages on declaring access, mounting storage, host setup and queues.
This site remains the reference for the SDK, the CLI, the daemon, and the control-plane API. Old URLs redirect, so nothing you have bookmarked breaks.
Install
Pick the surface you are starting from — each page below covers the authentication and first-run check for that one.
| You are… | Install | Then read |
|---|---|---|
| Writing Python | pip install dreamlake-lakeshore (0.3.7) | Python SDK |
| Operating a fleet | npm i -g @dreamlake/lakeshore (0.2.0) | CLI installation |
| Bringing up a compute host | normally installed through the CLI — lakeshore daemon install <ssh-alias> | Daemon installation |
The CLI is optional for the local tier and required once you manage providers, daemons, or a hosted control plane. See Release notes for the CLI changelog.
The CLI and the SDK each need a server URL, a namespace, and a token. Get them from whoever runs your control plane, or stand one up yourself with Admin setup.
Two tiers, one decorator
A bare @udf is a local call — an ordinary in-process function call
with a run context wrapped around it. Nothing touches the network, and
the HTTP/msgpack stack is never even imported.
Adding queue= makes the same function remote. A plain call now
submits to that queue and blocks for the result; .submit() returns the
invocation id instead, so you can walk away and reconnect later.
Point the SDK at a control plane with LAKESHORE_URL (plus
LAKESHORE_CLIENT_TOKEN and LAKESHORE_NAMESPACE when the plane
requires auth). With LAKESHORE_URL unset, submits go to a local
SQLite plane under LAKESHORE_HOME (default ~/.lakeshore) — handy for
trying the remote tier without any server at all.
Something has to drain the queue. The simplest drainer is a native Python worker on your own machine:
lakeshore worker deliberately does not read the credentials written by
lakeshore auth login. The plane a worker drains must come from --url
or LAKESHORE_URL, so a stray login can never redirect a worker.
The three pieces
| Piece | What it is | Where it runs |
|---|---|---|
lakeshore CLI | Node binary on npm. Providers, secrets, queues, daemons. | Your laptop |
| Control plane | Fastify 5 + Prisma + MongoDB. Owns the registry and the dispatch loop. | A server (Heroku today) |
nymph daemon | Rust binary. Long-polls the control plane, runs invocations. | The compute host |
Every wire call is daemon-initiated and outbound. The control plane never opens a connection to a worker, so a worker needs no inbound port, no port forward, and no firewall change.
Where to go next
| You want to… | Start here |
|---|---|
| Run your first function | Quick start |
| Install the CLI and connect a provider | CLI installation |
| Understand what's running where | Architecture |
| Follow a longer tutorial | Tutorials |
| Understand queues and scheduling | Queues |
| Run a fleet daemon on a remote host | Install a remote daemon |