Sitelet https://github.com/deepnote/deepnote/tree/main/packages/cloud
Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

@deepnote/cloud

Client for the Deepnote Cloud API (preview): create notebooks, trigger a run, poll it to completion, fetch its execution snapshot, and publish existing project files as Streamlit apps.

Used by deepnote run --cloud (@deepnote/cli) and by @deepnote/local-runner.

An app is HTML, CSS, and JavaScript hosted by Deepnote and run in the browser. A Streamlit app is a Python UI that runs on project hardware.

The client accepts IDs and plain objects. Map notebook content to ProjectSpec when creating a project.

Installation

npm install @deepnote/cloud

Usage

import {
  triggerNotebookRun,
  pollRunUntilComplete,
  waitForRunSnapshot,
} from "@deepnote/cloud";

const started = await triggerNotebookRun(baseUrl, token, {
  notebookId,
  inputs,
  detachedRunStorageMode: "readonly",
});
const run = await pollRunUntilComplete(baseUrl, token, started.runId, {
  snapshotDelivery: "inline",
});
const { content: snapshotYaml } = await waitForRunSnapshot(baseUrl, token, run);

Auth is Authorization: Bearer <token>. Endpoints: POST {baseUrl}/v2/runs and GET {baseUrl}/v2/runs/{runId}. Response schemas are permissive (.passthrough()) because the API is in preview and its exact shape may drift. Failures throw ApiError (from @deepnote/database-integrations).

Full-notebook runs are detached by default and do not update outputs in the live editor. detachedRunStorageMode: "readonly" additionally prevents writes to persistent project storage; it does not isolate databases, integrations, external APIs, or other systems the notebook accesses. Block-scoped runs use live mode because the API does not support blockIds on detached runs, and therefore cannot use detachedRunStorageMode.

API reference

Export Description
createProject(baseUrl, token, spec, opts?) Create a project, its notebooks, and their blocks; returns the ids Deepnote assigned. See below.
triggerNotebookRun(baseUrl, token, body) POST /v2/runs — start a run of an existing notebook. Returns the normalized run.
getRun(baseUrl, token, runId, options?) GET /v2/runs/{runId} — fetch a run's current state.
pollRunUntilComplete(baseUrl, token, runId, opts?) Poll until the run reaches a terminal status. Retries transient failures; enforces a deadline.
fetchSnapshotContent(run, options) Return the run's snapshot YAML, from inline content or a downloadUrl. null if it has none.
waitForRunSnapshot(baseUrl, token, run, opts?) Return a SettledRunSnapshot after bounded settling. Its content is null if none is produced; an unreadable snapshot throws.
describeRunError(run) A human-readable message for a failed run, if the API supplied one.
isTerminalStatus / isSuccessStatus / isFailedStatus Status classifiers. Unknown statuses are treated as non-terminal, so a drifting API cannot hang.
RUN_STATUSES, RunStatus The known run statuses.
RunTimeoutError Thrown when pollRunUntilComplete exceeds its deadline. Carries the runId — the run may still be executing.
NormalizedRun, TriggerRunBody, GetRunOptions, PollOptions, FetchSnapshotOptions, SettledRunSnapshot, WaitForRunSnapshotOptions Types.
listAllProjects(baseUrl, token, opts?) GET /v2/projects — every project in the workspace, walking pagination to exhaustion.
getProjectDetail(baseUrl, token, projectId, opts?) GET /v2/projects/{id} — one project, including its working-directory file inventory and app settings when supported by the server.
updateProjectStaticFiles(baseUrl, token, projectId, update, opts?) PATCH /v2/projects/{id} — update app sharing and/or API access; returns the settings and canonical app URL.
exportProject(baseUrl, token, projectId, opts?) GET /v2/projects/{id}/export — the project's notebooks as deterministic .deepnote documents (unzipped from the export ZIP, one per notebook). See below.
importProject(baseUrl, token, projectId, files, opts?) POST /v2/projects/{id}/import — reconcile a ZIP of .deepnote documents (the exact inverse of export) into the project. See below.
uploadProjectFile(baseUrl, token, projectId, path, bytes, opts?) POST /v2/files — upload one working-directory file (multipart). Does not overwrite; delete first. Buffered transfers are limited to 100 MiB.
deleteProjectFile(baseUrl, token, projectId, path, opts?) DELETE /v2/files — delete one working-directory file; false if it did not exist.
downloadProjectFile(baseUrl, token, projectId, path, opts?) GET /v2/files/download — raw bytes of one working-directory file. Buffered transfers are limited to 100 MiB.
createStreamlitApp(baseUrl, token, body, opts?) POST /v2/streamlit-apps — serve an existing project-relative file as a hosted Streamlit app. Returns the StreamlitApp record; url is its address.
listStreamlitApps(baseUrl, token, projectId, opts?) GET /v2/streamlit-apps?projectId= — the project's Streamlit apps (unpaginated).
getStreamlitAppStatus(baseUrl, token, appId, opts?) GET /v2/streamlit-apps/{id}/status — running, starting, or unavailable.
waitForStreamlitApp(baseUrl, token, appId, opts?) Poll until running; unavailable is not terminal. Retries transient failures; throws StreamlitAppTimeoutError after timeoutMs (default 10 minutes).
StreamlitAppTimeoutError Thrown when waitForStreamlitApp exceeds its deadline. Carries streamlitAppId and lastStatus; the app may still be starting.
StreamlitApp, StreamlitAppStatus, CreateStreamlitAppBody, StreamlitAppRequestOptions, WaitForStreamlitAppOptions Types.

Note on exportProject: the export is a ZIP with one .deepnote document per notebook, each carrying the full project envelope and a shared metadata.modifiedAt. exportProject unzips it and returns the documents ({ filename, content }[], sorted by filename). The documents are byte-deterministic for an unchanged project — the ZIP container is not — so compute change fingerprints over the documents, not the archive.

Note on importProject: sends a ZIP with one .deepnote document per notebook, matching the export shape. Pass the export's metadata.modifiedAt as baseModifiedAt to detect structural changes (notebooks created/deleted/renamed, other imports), and a content hash as baseContentHash to also detect editor block edits, which never advance the timestamp; on either mismatch the server rejects the import with a 409 (lost-update protection), and force skips both checks. Imports reconcile by notebook id (unmatched notebooks are created, missing ones are deleted only with deleteMissingNotebooks; an empty ZIP imports no notebooks, or deletes every notebook under that flag). Every document must belong to the target project and agree on project name and integration attachments. The shared name is applied, and a present project.integrations list reconciles the project's attachments ([] detaches all; an absent field leaves them unchanged). Integration credentials and settings.requirements are never imported.

Terminal status can arrive before its snapshot is attached. Prefer waitForRunSnapshot after polling: it retries attachment briefly, returns content: null when no artifact is ever produced, and preserves download/read failures as errors rather than mistaking them for an empty run.

Note on snapshot downloads: the bearer token is sent only when the download URL is same-origin with baseUrl. A cross-origin URL (e.g. a presigned S3 link) is fetched without auth, so the token is never leaked to a third-party host.

Cloud-run and content-creation requests keep their deadline active even when the caller supplies a cancellation signal. The deadline includes consuming the response body, and timeout/caller-abort errors remain distinguishable from ApiError responses.

Note on createProject: this is the headless counterpart to uploadNotebook, which uses the unauthenticated /v1/import endpoint and therefore has to be finished in a browser. With a token, prefer createProject — it returns the new ids, so you can run the notebook immediately.

Two API details leak through it. POST /v2/projects seeds a new project with an empty placeholder notebook, which createProject deletes once yours exist (there is no endpoint to rename one); a placeholder it cannot delete is reported via onWarning rather than failing the create. And there is no bulk block endpoint, so blocks cost one sequential request each — use onProgress to report that on a large notebook. A create that fails midway leaves partial content: there is no transaction.

License

Apache-2.0