:::note Generated reference Generated from honeyframeapi 0.1.8 — do not edit by hand. :::
honeyframeapi.project
Project handle — datasets, SQL, dashboards, recipes, scenarios and more for one project.
Every project-scoped call carries this project's id as the X-Project-Id
header, so a single client can drive many projects:
proj = client.get_project(1)
proj.list_datasets()
df = proj.get_dataset("fact_orders").get_dataframe()
dash = proj.create_dashboard("Ops Overview")
class Project
Project.get_summary()
get_summary() -> dict
Fetch (and cache) the project detail record.
Project.get_settings()
get_settings() -> dict
Project.list_datasets()
list_datasets(*, layer: Optional[str] = None, origin: Optional[str] = None, search: Optional[str] = None, tags: Optional[str] = None) -> list[dict]
List datasets in this project, with optional filters.
Project.get_dataset()
get_dataset(name: str) -> Dataset
Return a Dataset handle (does not fetch until used).
Project.ai_search()
ai_search(intent: str, *, tags: Optional[list] = None, limit: int = 10) -> dict
Rank this project's datasets against a natural-language intent.
Project-scoped HoneyframeClient.ai_search_datasets — returns
{"results": [...], "intent": ..., "count": n}. For the org-wide
(cross-project) search, call the client method with project_id=None.
Project.list_dataset_tags()
list_dataset_tags() -> list
Every distinct dataset tag in this project (GET /api/datasets/tags).
Union of the dedicated tags[] column and the legacy
settings.tags JSON path — both are live server-side.
Project.apply_dataset_tags()
apply_dataset_tags(names: list, *, add: Optional[list] = None, remove: Optional[list] = None) -> dict
Bulk-tag datasets: per dataset tags = (existing ∪ add) − remove.
POST /api/datasets/tags/apply. Writes both the tags[] column and
settings.tags so the list view and the settings modal agree. Returns
{"updated": n, "missing": [names not in this project]} — a name the
project doesn't have is reported, not an error. Needs org.admin.
Project.create_dataset()
create_dataset(name: str, *, dataset_type: str = 'sql_table', layer: str = 'source', friendly_name: str = '', description: str = '', connector_id: Optional[int] = None, connection_config: Optional[dict] = None, schema_config: Optional[dict] = None, sync_mode: str = 'batch', sync_interval: Optional[int] = None) -> Dataset
Create a dataset in this project and return its handle.
For an external SQL table, point at a connector +
connection_config={"schema_name": …, "table_name": …}. The
returned handle uses the name the server stored (it lowercases and
turns spaces/dashes into _).
Project.import_dataset()
import_dataset(name: str, *, unique_id: str = '', schema_name: str = '', layer: str = '') -> dict
Import an existing physical table as a dataset.
Project.register_source_table()
register_source_table(schema_name: str, table_name: str, *, connector_id: Optional[int] = None, friendly_name: str = '', name: Optional[str] = None) -> Dataset
Register an existing raw table as a discoverable source_table dataset.
Use this to surface a table that already lives in a connector's
database (e.g. a staging schema in the warehouse) in the dataset
picker, without copying any data. Unlike import_dataset
(which only finds tables already known to the dbt/native catalog),
this registers any physical schema.table directly.
The registered dataset is immediately queryable — the server records
schema_name + connection_config so the resolver runs
SELECT … FROM <schema_name>.<table_name> natively. To bulk-register
every table in a schema, see register_schema.
Returns a Dataset handle for the registered table.
Project.register_schema()
register_schema(schema_name: str, *, connector_id: int, search: str = '') -> list[Dataset]
Register every table in a connector schema as source_table datasets.
Lists the tables in schema_name via the connector, then registers
each one (see register_source_table). search filters the
table names server-side. Returns the list of registered
Dataset handles. Idempotent — re-registering an existing
table is a no-op.
Project.upload_dataframe()
upload_dataframe(name: str, df, *, friendly_name: str = '', description: str = '', replace: bool = False, materialize: bool = False) -> Dataset
Upload a pandas DataFrame as a managed dataset and return its handle.
The frame is serialised to CSV and sent to POST /api/datasets/file/upload,
which stores it as Parquet on the server (a managed, file-backed dataset).
Uploaded data is invisible to PG-backed consumers (dbt, dashboards,
agents) until materialised — pass materialize=True to copy it into
t<pid>_uploads.<name> right away, or call
Dataset.materialize later.
Project.upload_file()
upload_file(name: str, path, *, friendly_name: str = '', description: str = '', replace: bool = False, materialize: bool = False) -> Dataset
Upload a local .csv or .xlsx file as a managed dataset.
Project.sql()
sql(query: str, *, connector_id: Optional[int] = None, row_limit: int = 10000, params: Optional[dict] = None) -> Any
Run ad-hoc SQL in this project and return a pandas DataFrame.
Runs through the platform's governed POST /api/sql endpoint
(SELECT only, within the project's schemas, data policies applied).
params are named binds: sql("... WHERE d >= :p_start", params={"p_start": "2026-01-01"}).
When the server cut the result at row_limit (it reports
truncated), the SDK emits a UserWarning and sets
df.attrs["truncated"] = True ("truncated": True on the dict
returned without pandas). Raise row_limit (the server caps it at
50,000) or page the query yourself.
Only on an older platform where /api/sql does not exist does it
fall back to a hidden per-project scratch dashboard card (params
is not supported there).
Project.list_dashboards()
list_dashboards(tab: str = 'all') -> list[dict]
Dashboards of this project, as the server scopes them.
Sends project_id so the server lists this project's dashboards
(it 403s a project you cannot read). Org-level dashboards
(project_id null) are included, the same list the UI shows.
Project.create_dashboard()
create_dashboard(title: str, *, description: Optional[str] = None, is_public: bool = False, collection_id: Optional[int] = None) -> Dashboard
Create a dashboard owned by this project and return its handle.
Project.get_dashboard()
get_dashboard(dashboard_id: int) -> Dashboard
Project.list_connectors()
list_connectors() -> list[dict]
Project.dbt
property
dbt: DbtIDE
Authoring handle over /api/dbt/* — write/run/version dbt models.
Project.get_recipe()
get_recipe(model_name: str) -> Recipe
Return a Recipe handle for a flow model.
Project.run_dbt()
run_dbt(select: Optional[str] = None, *, wait: bool = False, timeout: float = 1800.0, poll_interval: float = 5.0) -> dict
Trigger a dbt build in this project (dbt run or --select).
Returns the trigger response ({"status": "triggered", …}) at once.
With wait=True it blocks until the build's run finishes and
returns that run (status success / failed), via
JobsAPI.trigger_and_wait.
Needs org admin.
Project.build_native()
build_native(select: Optional[str] = None, *, dry_run: bool = False, background: bool = False, wait: bool = False) -> dict
Build this project's native-engine recipes in dependency order —
the native dbt run (POST /api/flow/build-native).
Native-engine orgs only (a dbt org gets 409 and builds with
run_dbt). The server topo-sorts every target='sql' recipe
by its dataset I/O and runs them through the recipe runner, stopping
at the first failure.
select narrows the build dbt-style: model, model+,
+model, +model+, comma-separated. dry_run=True returns the
resolved order without executing (the native dbt ls --select) and
wins over background. background=True returns
{run_id, status:"running", …} immediately; add wait=True to
block on the run and return its detail instead.
Sync returns {ordered, results:[{model,status,error}], built, total, ok, selected}. A recipe saved with no SQL fails here with "has empty
inline_code" — land it first with Recipe.set_sql.
Project.change_recipe_engines()
change_recipe_engines(names: list, target: str, *, dry_run: bool = False) -> dict
Change the compute engine of one or more recipes at once (the UI's
"change recipe engines" bulk action). target ∈ sql (pin each to the
native in-database engine) | dbt (pin to dbt) | auto (clear pins
and reset to the org's default engine). A recipe that can't compile to
the requested engine is reported not-ok and left untouched.
dry_run=True reports the per-recipe outcome without writing. Returns
{results: [{name, ok, from, to, messages}], dry_run, target}. Needs
org admin. Read a single recipe's status via Recipe.engine_status.
Project.engine()
engine(*, refresh: bool = False) -> str
The catalog engine profile for this org: 'dbt' or 'native'.
'dbt'— dbt is installed; author transforms as dbt models viadbt(project.dbt.create_model/write_file+run).'native'— a standalone Honeyframe install with no dbt. There is no dbt IDE; author SQL transforms with the recipe API instead (get_recipe(name).save_prepare_steps(...)or.save(recipe_type='sql_query', steps=[...])). The server materialises them through the native engine automatically — the org's engine profile decides, so there is no per-calltargetflag.
Cached after the first call; pass refresh=True to re-read. Defaults
to 'dbt' on pre-migration servers that don't expose the field yet.
Project.uses_dbt()
uses_dbt() -> bool
True when this org authors transforms as dbt models (engine == 'dbt').
Project.dag()
dag() -> dict
The project's full lineage DAG as {nodes: [...], edges: [...]}.
Walks through the model catalog, so it works on both dbt and
native-engine tenants. For a single dataset's ancestors/dependents use
Dataset.upstream / Dataset.downstream.
Project.list_scenarios()
list_scenarios() -> list[dict]
Project.get_scenario()
get_scenario(scenario: int | str) -> Scenario
Return a Scenario handle by id or name.
Project.create_scenario()
create_scenario(name: str, *, display_name: Optional[str] = None, description: str = '', trigger_type: str = 'manual', steps: Optional[list] = None, is_active: bool = False, **extra) -> Scenario
Project.create_bundle()
create_bundle(*, label: str = '', **opts) -> Bundle
Snapshot this project as the next bundle version. opts are the
export include-flags (include_versions, include_managed_folder_files,
include_vector_stores, include_job_runs, include_form_submissions,
include_dbt_target).
Project.list_bundles()
list_bundles() -> list[dict]
Bundle versions for this project (newest first).
Project.bundle()
bundle(version: int) -> Bundle
Return a Bundle handle for a version.
Project.list_signoffs()
list_signoffs() -> dict
Deployment sign-off status + audit log for every bundle version of
this project — {mode, signoffs: {version: {status, blocking, reviewers, approver_user_id, log}}}. mode is the org's sign-off
policy (whether the gate blocks a deploy). Drive a version's gate from
the Bundle handle (Bundle.request_signoff etc.).
Project.list_bundle_activations()
list_bundle_activations() -> list[dict]
Activation history for this project's bundles ({activation_id, bundle_id, version, target_project_id, node_role, activated_by, activated_at, is_active}).
Project.list_models()
list_models(*, name: str | None = None) -> list[SavedModel]
Saved models in this project (name= narrows to one model's
version history). Created by train_model / cluster_model recipes.
Project.get_model()
get_model(model_id: int) -> SavedModel
Return a SavedModel handle (fetches lazily).
Project.list_experiments()
list_experiments() -> list[Experiment]
Experiments in this project. The Analysis Lab logs into these automatically; the SDK adds its own runs alongside.
Project.create_experiment()
create_experiment(name: str, *, description: str = '') -> Experiment
Create an experiment → an Experiment
handle. Names are unique per project (a duplicate raises).
Project.get_experiment()
get_experiment(experiment_id: int) -> Experiment
Return an Experiment handle
(fetches lazily).
Project.create_ml_recipe()
create_ml_recipe(name: str, recipe_type: str, *, inputs: list, config: dict, output_datasets=None) -> MlRecipe
Create an ML recipe of any type (train_model / score_model /
cluster_model / evaluate_model). Prefer the typed helpers below.
Project.train_model()
train_model(name: str, *, input_table: str, target_column: str, task_type: str, algorithm: str, features=None, hyperparams=None, test_size=None, max_rows=None, model_name=None, run: bool = True, wait: bool = True) -> MlRecipe
Train a supervised model — see ml.train_model.
Project.score_model()
score_model(name: str, *, input_table: str, model_id: int, output_table=None, output_schema=None, max_rows=None, run: bool = True, wait: bool = True) -> MlRecipe
Score rows with a trained model — see ml.score_model.
Project.cluster_model()
cluster_model(name: str, *, input_table: str, algorithm: str, features=None, hyperparams=None, output_table=None, output_schema=None, max_rows=None, model_name=None, run: bool = True, wait: bool = True) -> MlRecipe
Fit a clustering model — see ml.cluster_model.
Project.evaluate_model()
evaluate_model(name: str, *, input_table: str, target_column: str, model_id: int, max_rows=None, run: bool = True, wait: bool = True) -> MlRecipe
Evaluate a trained model — see ml.evaluate_model.
Project.create_plugin_recipe()
create_plugin_recipe(recipe_type: str, name: str, *, config: Optional[dict] = None, inputs: Optional[list] = None, output_datasets: Optional[list] = None, run: bool = False, wait: bool = False) -> PluginRecipe
Create a flow recipe of a plugin-contributed custom recipe_type —
see plugin_recipe.create_plugin_recipe. Discover
creatable types via
plugin_recipe_types.
Project.list_notebooks()
list_notebooks() -> list[dict]
List this project's notebooks (metadata + cell counts).
Project.create_notebook()
create_notebook(name: str, *, description: str = '', cells: Optional[list] = None, tags: Optional[list] = None) -> Notebook
Create a notebook → a Notebook handle.
cells items may be source strings or full cell dicts.
Project.get_notebook()
get_notebook(notebook_id: int) -> Notebook
Fetch a notebook by id → a populated Notebook.
Project.import_ipynb()
import_ipynb(src, *, name: Optional[str] = None, description: str = '', tags: Optional[list] = None) -> Notebook
Import a Jupyter .ipynb (path or parsed dict) as a platform
notebook. Round-trips with export_ipynb.
Project.list_wiki_pages()
list_wiki_pages() -> list[dict]
List this project's wiki pages (metadata; the body is omitted).
Project.create_wiki_page()
create_wiki_page(title: str, *, body: str = '') -> WikiPage
Create a wiki page → a WikiPage handle.
Project.get_wiki_page()
get_wiki_page(slug: str) -> WikiPage
Fetch a wiki page by slug → a populated WikiPage.
Project.list_comments()
list_comments(object_type: str, object_id: str) -> list[dict]
The threaded comments on an object (dataset / dashboard / recipe / …).
Project.comment_count()
comment_count(object_type: str, object_id: str) -> int
Number of comments on an object.
Project.add_comment()
add_comment(object_type: str, object_id: str, body: str, *, parent_id: Optional[int] = None) -> dict
Post a comment, or a reply when parent_id is set, on an object.
Project.edit_comment()
edit_comment(comment_id: int, body: str) -> dict
Edit a comment you authored.
Project.delete_comment()
delete_comment(comment_id: int) -> None
Delete a comment (author; an admin may delete any).
Project.list_folders()
list_folders() -> list[dict]
Managed folders visible to this project (project-scoped + org-wide).
Project.get_folder()
get_folder(folder_id: int) -> Folder
Return a Folder handle (does not fetch until used).
Project.create_folder()
create_folder(name: str, *, description: str = '', org_wide: bool = False) -> Folder
Create a managed folder in this project and return its handle.
Project.create_api_service()
create_api_service(asset_key: str, title: str, *, endpoints: Optional[list] = None, publish: bool = False, description: str = '', roles: Optional[list] = None, is_public: bool = False, icon: str = '') -> APIService
Create a project-scoped API service and return its handle.
Delegates to HoneyframeClient.create_api_service with this
project's scope. endpoints is a list from the endpoint builders
(sql_endpoint / lookup_endpoint /
model_endpoint); publish=True makes the endpoints callable now.
Project.get_preferences()
get_preferences() -> dict
Per-user project preferences blob (free-form JSON).
Distinct from project variables (see list_variables): preferences
are per-user UI state; variables are shared, typed, and referenced in
SQL as :name / ${name}.
Project.set_preferences()
set_preferences(prefs: dict) -> dict
Project.list_variables()
list_variables() -> dict
Resolved project variables as {name: value} (local overrides standard).
Project.set_variable()
set_variable(name: str, value, *, var_type: str = 'string', scope: str = 'standard') -> dict
Create/update a project variable. Referenced in SQL as :name / ${name}.
Project.delete_variable()
delete_variable(name: str, *, scope: str = 'standard') -> dict
Verified against honeyframeapi 0.1.8.