Skip to main content

Notebooks, folders and wiki

Notebooks​

Platform notebooks are lists of code and markdown cells stored in a project. The SDK edits their content; running cells happens in the platform UI.

nb = project.create_notebook("explore_orders", cells=[
"import pandas as pd",
{"type": "markdown", "source": "## Orders by store"},
])
nb.append_cell("print('next step')")
print([c["source"] for c in nb.cells])

nb.update(description="Exploration of fact_orders", tags=["exploration"])
nb.set_cells(["print('start over')"])
project.list_notebooks()
nb = project.get_notebook(nb.notebook_id)
nb.delete()

A cell is either a source string (a code cell) or a dict with type (code or markdown) and source.

Jupyter files (0.1.8+)​

nb = project.import_ipynb("explore_orders.ipynb") # a path or a parsed dict
nb.export_ipynb("explore_orders_copy.ipynb")
as_dict = nb.to_ipynb() # nbformat 4.5

Markdown and raw cells import as markdown, code cells as code; Jupyter outputs are dropped on import, and platform outputs are not exported.

Managed folders​

A managed folder stores arbitrary files for a project (or, with org_wide=True, for the organization).

folder = project.create_folder("contracts", description="Signed supplier contracts")
folder.upload("scan.pdf") # → contracts/scan.pdf
folder.upload("q3.xlsx", dest="2026/q3") # into a subdirectory
folder.upload_bytes("notes.txt", b"hello")
folder.mkdir("archive")

for item in folder.list_files(): # {name, type, path, size, …}
print(item["type"], item["path"])

folder.download("scan.pdf", "local_scan.pdf") # written readable by you only
data = folder.read_bytes("notes.txt")
folder.delete_file("notes.txt")

project.list_folders() lists the folders visible to the project, project.get_folder(folder_id) opens one, and folder.get_info() returns its record.

Wiki pages​

Each project has a flat set of Markdown wiki pages addressed by slug. Reading needs project.view, writing project.edit.

page = project.create_wiki_page("Runbook", body="# Steps\n1. Refresh\n2. Check")
page.update(body="# Steps\n1. Refresh\n2. Check\n3. Publish") # title is kept
print(page.title, page.body)

for p in project.list_wiki_pages(): # metadata, no body
print(p["slug"], p["title"])

page = project.get_wiki_page(page.slug)
page.delete()

Bundles​

A bundle is a versioned snapshot of a project that you can download, activate as a new project, deploy over an existing one, or push to another Honeyframe installation. See Bundles.

b = project.create_bundle(label="release candidate", include_versions=True)
project.list_bundles() # newest first
b = project.bundle(3)

b.download("sales_v3.hsproj.zip")
b.activate(target_name="Sales (staging)", target_slug="sales-staging")
b.deploy(target_project_id=12) # replace an existing project's contents
  • create_bundle(*, label="", **opts) takes the export include flags: include_versions, include_managed_folder_files, include_vector_stores, include_job_runs, include_form_submissions, include_dbt_target.
  • activate clones the version into a new project; connectors are matched against the target organization, not bundled.
  • deploy replaces an existing project's contents with the version and archives the previous contents. The project keeps its slug and name but gets a new id.
  • push(*, node_id, target_name, target_slug, target_org_id=None) sends the version to a remote installation registered with client.register_node(name, base_url, api_key), where api_key is a PAT issued on that installation. client.list_nodes() and client.delete_node(node_id) manage registrations; the stored token is never returned.

Deployment sign-off​

When your organization requires sign-off before a deploy, drive it from the bundle:

b.request_signoff(note="Q3 release", feedback_givers=[17, 23], approver_user_id=5)
b.submit_feedback(verdict="approve", note="Numbers tie out") # approve | reject | comment
b.submit_for_approval()
b.approve(note="Go") # or b.reject(...), b.abandon(...)
b.governance_status() # {status, blocking, detail}
project.list_signoffs() # every version's sign-off state and log

Feedback never changes the status; the final approval is the gate. project.list_bundle_activations() lists where versions were activated.

Statistics worksheets (0.1.8+)​

dataset.statistics runs the platform's statistical analysis cards against a dataset and manages saved worksheets, the same ones the dataset's Statistics tab shows. See Statistics.

stats = project.get_dataset("fact_orders").statistics

stats.univariate("amount") # summary and histogram
stats.correlation(["amount", "quantity", "discount"])
stats.ttest_2samp("amount", "channel")
stats.pca(["amount", "quantity", "discount"], n_components=2)
stats.compute("shapiro_wilk", column="amount") # any card type, by name

ws = stats.create_worksheet("Order value analysis")
ws.add_card("univariate", column="amount")
ws.add_card("anova_1way", column="amount", group="store_key")
for entry in ws.compute_all():
print(entry["card"]["type"], entry["result"])

There is one method per card type: univariate, correlation, scatter_fit, quantile_table, cdf_plot, fit_distribution, shapiro_wilk, chi2_independence_test, ttest_2samp, mann_whitney_u, paired_ttest, anova_1way, levene_test, ks_test_2samp, acf_plot, mann_kendall_test and pca. The list is also honeyframeapi.CARD_TYPES; an unknown type raises ValueError before any request. Worksheets also support cards, update_card, remove_card, set_cards, rename, compute_card, reload and delete; stat_card(card_type, **params) builds one validated card config.

Two limits: worksheets exist only on installations that have run the worksheet migration (elsewhere list_worksheets() returns [], while ad-hoc compute still works), and analysis runs on warehouse and uploaded-file datasets only; other datasets raise HoneyframeValidationError with the platform's reason.

Code environments (0.1.8+)​

Organization admins declare managed Python environments and build them.

env = client.create_code_environment(
"analytics", python_version="3.11",
packages=["pandas==2.2.2", "scikit-learn==1.5.0"],
)
client.validate_code_environment(env["id"]) # parses every spec; installs nothing
state = client.build_code_environment(env["id"], wait=True, timeout=1800)
print(state["build_state"]) # built | stale | failed
  • client.code_environment_build_availability() says whether this installation can build environments at all, and what is missing if not.
  • build_code_environment returns at once unless wait=True. A response with started: False means builds are unavailable here (the message says why) — nothing was built, and it is not an error. With wait=True it polls until the build leaves building and raises TimeoutError after timeout seconds (the build continues on the server).
  • Branch on build_state (not_built, building, built, stale, failed) rather than status. Editing a built environment's packages marks it stale until rebuilt.
  • list_code_environments(), get_code_environment(id), update_code_environment(id, **fields), delete_code_environment(id) and code_environment_build_log(id) complete the set. Packages are PEP 508 specs, optionally hash-pinned; source builds are off unless allow_source_builds=True.

Verified against honeyframeapi 0.1.8.