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.activateclones the version into a new project; connectors are matched against the target organization, not bundled.deployreplaces 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 withclient.register_node(name, base_url, api_key), whereapi_keyis a PAT issued on that installation.client.list_nodes()andclient.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_environmentreturns at once unlesswait=True. A response withstarted: Falsemeans builds are unavailable here (themessagesays why) — nothing was built, and it is not an error. Withwait=Trueit polls until the build leavesbuildingand raisesTimeoutErroraftertimeoutseconds (the build continues on the server).- Branch on
build_state(not_built,building,built,stale,failed) rather thanstatus. Editing a built environment's packages marks itstaleuntil rebuilt. list_code_environments(),get_code_environment(id),update_code_environment(id, **fields),delete_code_environment(id)andcode_environment_build_log(id)complete the set. Packages are PEP 508 specs, optionally hash-pinned; source builds are off unlessallow_source_builds=True.
Verified against honeyframeapi 0.1.8.