:::note Generated reference Generated from honeyframeapi 0.1.8 — do not edit by hand. :::
honeyframeapi.dataset
Dataset handle — read a platform dataset into pandas.
ds = project.get_dataset("fact_orders")
df = ds.get_dataframe() # full table via /explore pagination
head = ds.head(20) # quick preview
stats = ds.profile() # per-column stats
ds.statistics.univariate("age") # EDA cards — see honeyframeapi.statistics
get_dataframe and head return pandas.DataFrame when pandas is
installed (pip install honeyframeapi[pandas]); otherwise they return a
plain {"columns": [...], "rows": [...]} dict so the core SDK stays
dependency-light.
class Dataset
Dataset.get_metadata()
get_metadata() -> dict
Full dataset record: columns, types, layer, row_count, …
Dataset.get_schema()
get_schema() -> list[dict]
Just the column definitions (name/data_type/semantic_type).
Dataset.profile()
profile() -> list[dict]
Per-column profiling stats (distinct, null %, min/max).
Dataset.statistics
property
statistics: DatasetStatistics
The dataset's statistics surface — the 17 EDA card types and the saved worksheets the Statistics tab shows.
profile() is the cheap per-column summary; this is the analysis
surface on top of it:
ds.statistics.correlation(["age", "order_value"])
ds.statistics.anova_1way("order_value", "store_key")
See statistics.
Dataset.get_settings()
get_settings() -> dict
Editable settings for this dataset (GET /{name}/settings).
{managed, friendly_name, description, sync_mode, sync_interval, semantic_overrides, column_descriptions, masking, tags, partitioning}.
managed is False when the dataset has no honeyframe.datasets row
yet — the values are then catalog defaults, and the first
update_settings creates the row.
Dataset.update_settings()
update_settings(*, friendly_name: Optional[str] = None, description: Optional[str] = None, tags: Optional[list] = None, semantic_overrides: Optional[dict] = None, column_descriptions: Optional[dict] = None, masking: Optional[dict] = None, sync_mode: Optional[str] = None, sync_interval: Optional[int] = None, partitioning: Optional[dict] = None, catalog: Optional[dict] = None) -> dict
Patch dataset settings — only the fields you pass are written.
PUT /{name}/settings; returns {"ok": True, "name": ...}. Needs
org.admin. Every argument left at None is omitted from the
request and the stored value is untouched — passing None is NOT a
way to clear a field (the server skips null fields outright; to empty
partitioning send {"dimensions": []}).
semantic_overrides = {column: semantic_type},
column_descriptions = {column: text}, masking =
{column: {sensitivity, strategy, unmask_roles, unmask_project_roles}},
partitioning = {"dimensions": [{name, type, period?}]}
(server-validated against the live columns; a bad spec is a 400).
catalog is the authored data-catalog block a published app's Katalog
page reads back through
Webapp.catalog() — it
lands in settings.catalog and is the only writer for that surface.
The block's field names and enum VALUES are Indonesian because the
platform stores and validates them that way; send them verbatim:
{"grain": "1 row = 1 order",
"period_column": "order_date",
"refresh": "harian",
"status": "dipakai",
"sumber": ["ERP"], "sumber_teknis": "raw_erp.orders",
"caveats": [{"level": "perhatian", "teks": "...", "bukti": "..."}]}
Fields: sumber = sources, sumber_teknis = technical source,
caveats[].teks = text, caveats[].bukti = evidence. The enums
are server-validated, so a typo is a 400 rather than a silent blank in
the client: refresh ∈ harian (daily) | bulanan (monthly) |
snapshot-harian (daily snapshot) | sekali-muat (one-off load) |
tidak-dibangun (not built), status ∈ dipakai (in use) |
blok-bangunan (building block) | tidak-dibangun (not built),
and each caveats[].level ∈ info | perhatian (warning) |
kritis (critical) with a non-empty teks. Unknown keys are kept, so a seeder can add a
field without a backend release. Written whole — send the full block,
not a patch.
Dataset.tags()
tags() -> list
This dataset's tags, as the settings surface reports them.
Dataset.apply_tags()
apply_tags(*, add: Optional[list] = None, remove: Optional[list] = None) -> dict
Add and/or remove tags on this dataset: (existing ∪ add) − remove.
Single-dataset call of the bulk POST /api/datasets/tags/apply
(Project.apply_dataset_tags), so it writes both the tags[]
column and settings.tags. Returns {"updated": n, "missing": [...]}
— updated: 0 means this project has no dataset by that name. Needs
org.admin.
Dataset.upstream()
upstream() -> dict
Ancestors — everything this dataset depends on (recursive walk up).
Dataset.downstream()
downstream() -> dict
Dependents — everything that reads from this dataset (recursive).
Dataset.head()
head(n: int = 100, *, as_dataframe: bool = True) -> Any
Return up to n preview rows (server caps preview at 100).
Dataset.get_dataframe()
get_dataframe(*, page_size: int = 500, max_rows: Optional[int] = None, as_dataframe: bool = True) -> Any
Read the whole dataset (or up to max_rows) via paginated /explore.
Pages through GET /api/datasets/{name}/explore until the reported
total is reached. Set max_rows to cap large pulls.
Dataset.to_csv()
to_csv(path, *, max_rows: Optional[int] = None) -> str
Export the dataset to a local CSV file and return the path.
Reads through the same paginated /explore path as
get_dataframe, so server-side data-policy / PII masking is
applied — the export can't see more than the caller can browse. Works
without pandas (writes via the stdlib csv module). Round-trips with
Project.upload_file.
Dataset.to_parquet()
to_parquet(path, *, max_rows: Optional[int] = None) -> str
Export the dataset to a local Parquet file (needs pandas + pyarrow).
Same masked /explore read path as to_csv.
Dataset.ask()
ask(question: str, *, row_limit: int = 100) -> dict
Natural-language query over this dataset (Genie /ask).
Dataset.materialize()
materialize(*, refresh: bool = False, timeout: Optional[float] = None) -> dict
Copy a file-backed dataset into t<pid>_uploads.<name> so dbt /
dashboards / agents can read it natively. refresh=True overwrites.
timeout (seconds) overrides the client default for this call.
Dataset.list_metrics()
list_metrics() -> list[dict]
Metric definitions on this dataset.
Dataset.add_metric()
add_metric(name: str, *, metric_type: str, column: Optional[str] = None, sql_expr: Optional[str] = None, unit: str = '') -> dict
Define a metric. metric_type ∈ row_count | distinct_count |
null_pct | min | max | mean | custom_sql. Column metrics need
column; custom_sql needs a single-scalar read-only sql_expr.
Dataset.delete_metric()
delete_metric(name: str) -> dict
Delete a metric (and its history + checks) by name.
Dataset.compute_metrics()
compute_metrics() -> list[dict]
Compute every active metric on this dataset now. Returns
[{name, value, breaches}] — the breached threshold checks per metric.
Dataset.metric_history()
metric_history(name: str, *, limit: int = 200) -> list[dict]
Time series of computed values for a metric (oldest→newest).
Dataset.add_metric_check()
add_metric_check(name: str, *, operator: str, threshold: float, severity: str = 'warning') -> dict
Add a threshold check over a metric. operator ∈ < <= > >= == != ;
a breach is when the condition does NOT hold (e.g. < 5 breaches at ≥5).
Dataset.metrics_status()
metrics_status() -> list[dict]
Status payload: each metric + latest value + trend + check verdict.
Dataset.schema_contract()
schema_contract() -> Optional[dict]
The current captured schema contract (baseline), or None if unset.
Dataset.capture_schema_contract()
capture_schema_contract(*, enforcement: str = 'warn', note: Optional[str] = None) -> dict
Snapshot the dataset's live schema as the baseline to diff future
drift against. enforcement ∈ off | warn | enforce. Returns the new
contract (carrying its version).
Dataset.set_schema_enforcement()
set_schema_enforcement(enforcement: str) -> dict
Change the current contract's enforcement (off|warn|enforce) without re-baselining.
Dataset.schema_drift()
schema_drift() -> dict
Live schema diffed against the current contract. Returns
{status, is_breaking, diff: {added, removed, type_changed, …}};
status ∈ no_contract | ok | drift | breaking_drift | unreadable.
Dataset.meanings()
meanings() -> dict
The detected meaning (semantic type) per column — {column: meaning}
— as the org registry classified the live schema.
Dataset.validate_meaning()
validate_meaning(column: str, *, sample: int = 200) -> dict
Detect column's meaning and measure how many of up to sample
non-null values breach its value rule. Returns {meaning, validatable, total, mismatched, pct_mismatch, examples}. The trendable + gateable
full-table version is a meaning_mismatch metric — add_metric(..., metric_type='meaning_mismatch', column=column).
Dataset.versions()
versions() -> list[dict]
Snapshot versions of this dataset, newest first ({id, snapshot_table, row_count, size_bytes, created_at, is_pinned, note, retention_policy, dq_summary, …}).
Dataset.preview_version()
preview_version(version_id: int, *, limit: int = 50) -> dict
Read the data as of a snapshot version — Databricks-style
time-travel, non-destructively. Applies the SAME role/column masking as
live Explore (the preview never sees more than the caller can browse).
Returns {is_snapshot, version_id, schema, table, columns, rows, row_count, masking}. Table-backed marts only. Never mutates — for a
live rollback use rollback_version.
Dataset.rollback_version()
rollback_version(version_id: int) -> dict
Restore the live table to a snapshot version. Destructive
(TRUNCATE + INSERT in one txn); table-backed marts only (not
external/uploaded-file datasets). Returns {rows_restored, …}.
Dataset.update_version()
update_version(version_id: int, *, is_pinned: Optional[bool] = None, note: Optional[str] = None, retention_policy: Optional[str] = None) -> dict
Pin / annotate / retention-tag a snapshot version — only the fields you pass change. Pinning exempts a version from retention pruning.
Dataset.delete()
delete(*, managed: bool = False) -> dict
Verified against honeyframeapi 0.1.8.