Python API¶
The Lakehouse Plumber (LHP) Python API exposes the same generation engine that
powers the lhp command-line interface. Import it to build custom tooling:
notebook integrations, CI/CD wrappers, programmatic validation in tests, or
embedding LHP inside a larger orchestrator. For day-to-day pipeline authoring,
prefer the CLI — the Python API trades convenience for control.
This page catalogs the public surface by stability tier and renders live docstrings via Sphinx autodoc. The tier table is the contract; the autodoc sections below it are the source-of-truth signatures pulled from the code at build time.
Stability tiers¶
LHP follows a four-tier stability model. The tier governs what level of change to expect between minor and major versions.
Tier |
Change policy |
Definition |
|---|---|---|
Stable |
Semantic versioning; breaking changes only at major releases. |
Public API in active use by external integrations. Method signatures, return shapes, and observable behavior are versioned. |
Beta |
May change between minor versions with a deprecation cycle of at least one release. |
Public API still settling. Suitable for production use if you pin LHP to a minor version. |
Experimental |
May change without notice at any release, including patch releases. |
Public API exposed for evaluation. Do not depend on it from long-lived code. |
Internal |
May change at any time. Not part of the API contract. |
Implementation detail. Importing it from outside |
If a symbol is not listed on this page, treat it as Internal regardless of its import path.
Public API by tier¶
Stable¶
No symbol is currently Stable. LHP is pre-1.0; the CLI is the stable contract. Python API consumers should treat the Beta tier as the recommended entry point and pin to a minor version of LHP.
Beta¶
These symbols are the recommended entry points for programmatic use.
Symbol |
Summary |
|---|---|
|
Public entry point; construct via |
|
Parses and validates LHP YAML files into Pydantic models. Use to load flowgroups, presets, and templates without invoking the full pipeline. |
|
Thread-safe caching wrapper around |
|
Loads presets from a directory and resolves inheritance chains. |
|
Synchronizes Databricks bundle resource files with generated pipeline code. |
|
Pydantic models for the on-disk YAML schema: |
|
Public exception hierarchy: |
Experimental¶
These symbols are exposed but may change without notice.
Symbol |
Summary |
|---|---|
|
Returns the installed LHP package version string. |
Internal¶
Everything else under lhp.* is Internal — including all of lhp.core.*,
lhp.generators.*, lhp.cli.*, lhp.schemas.*, lhp.templates.*,
lhp.resources.*, and any lhp.utils.* module not listed under Beta or
Experimental above. Drive LHP through the facade, not these modules.
Important
Importing from an Internal namespace works today but provides no guarantees. Patch releases may move, rename, or remove these symbols without a deprecation notice.
Detailed reference¶
The sections below render docstrings, type hints, and signatures directly from the source code. Refer to the tier table above for stability guarantees on each symbol.
Package root: lhp¶
Lakehouse Plumber - YAML-driven framework for Databricks Lakeflow Spark Declarative Pipelines.
Application facade: lhp.api.facade¶
Application facade — single entry point for LHP runtime operations.
Composes seven sub-facades (generation, validation, inspection, bundle,
wheel, sandbox, dependency) that group related operations. Constructed exclusively via
LakehousePlumberApplicationFacade.for_project(); the composition
root lives in lhp.core.coordination.layers.
- stability:
provisional
- class lhp.api.LakehousePlumberApplicationFacade(orchestrator)[source]¶
Bases:
objectTop-level application facade.
Composes seven sub-facades that group related operations:
generation— batch generation runs.validation— config validation.inspection— read-only project introspection.bundle— Asset Bundle operations.wheel— built-wheel inspection / extraction.sandbox— developer-sandbox scope inspection.dependency— dependency-graph analysis and output generation.
Constructed exclusively via
for_project(). The bare__init__(...)form is internal — external callers must route through the classmethod so the composition-root logic (singleConfigValidator, threaded collaborators) is enforced (§4.5).The public
orchestratorattribute is intentionally absent (§1.10, §9.23); callers must use the sub-facade methods.- Stability:
stable
- Parameters:
orchestrator (_Orchestrator)
- classmethod for_project(project_root, *, pipeline_config_path=None, enforce_version=True, max_workers=None, no_cache=False)[source]¶
Construct a fully-wired facade from a project root.
Centralises service-graph construction so no service reaches into another’s private attributes; builds the single
ConfigValidatorthat threads through validation and flowgroup-resolution (closes the §9.24 leak).no_cachedisables the persistent on-disk parse cache (<project_root>/.lhp/cache/parse) for this facade; the cache is also disabled when theLHP_NO_CACHEenvironment variable is truthy ("1","true","yes"). The cache is delete-safe: results are identical with or without it.- Stability:
provisional
- Raises:
lhp.errors.LHPError –
LHP-CFG-*iflhp.yamlis absent, malformed, or fails project-config validation;LHP-VAL-*ifenforce_versionis set and thelhp_versionconstraint rejects the installed package;LHP-FILE-*for missing-path conditions discovered during composition.- Parameters:
- Return type:
- generate_pipelines(*, pipeline_filter=None, pipeline_fields=(), env, output_dir, specific_flowgroups=None, include_tests=False, apply_formatting=None, bundle_enabled=False, pre_discovered_all_flowgroups=None, max_workers=None, progress=None, sandbox=False)[source]¶
Shortcut for
self.generation.generate_pipelines(...).Restates the canonical signature (§4.2) and forwards every parameter unchanged via
yield from(§1.4, §5.7).apply_formattingis the tri-state formatting override (None= use the project’slhp.yamlapply_formattingsetting;True/Falseoverride it), resolved downstream in the orchestrator.progressis an optionalProgressSinkthe run advances as flowgroups complete; read itstotal/donefields while iterating the stream to observe live progress.sandboxswitches the run to developer-sandbox mode: scope and namespace come from the personal.lhp/profile.yamlplus the teamsandbox:policy inlhp.yaml. CANNOT be combined withpipeline_filter/pipeline_fields.- Stability:
provisional
- Raises:
ValueError – if
sandbox=Trueis combined withpipeline_filterorpipeline_fields(API misuse).lhp.errors.LHPError – same families as
GenerationFacade.generate_pipelines()—LHP-VAL-*,LHP-CFG-*,LHP-FILE-*,LHP-MULT-*,LHP-TPL-*; plus the sandbox preflight errors on asandbox=Truerun —LHP-IO-025,LHP-CFG-064,LHP-CFG-065,LHP-VAL-064.
- Parameters:
pipeline_filter (Optional[str])
pipeline_fields (Sequence[str])
env (str)
output_dir (Optional[Path])
specific_flowgroups (Optional[List[str]])
include_tests (bool)
apply_formatting (bool | None)
bundle_enabled (bool)
pre_discovered_all_flowgroups (Optional[Sequence['FlowGroup']])
max_workers (Optional[int])
progress (ProgressSink | None)
sandbox (bool)
- Return type:
Iterator[LHPEvent]
- validate_pipelines(*, pipeline_filter=None, pipeline_fields=(), env, max_workers=None, include_tests=True, bundle_enabled=False, pre_discovered_all_flowgroups=None, progress=None, sandbox=False)[source]¶
Shortcut for
self.validation.validate_pipelines(...).Restates the canonical signature (§4.2) and forwards every parameter unchanged via
yield from(§1.4, §5.7).progressis an optionalProgressSinkthe run advances as flowgroups complete; read itstotal/donefields while iterating the stream to observe live progress.sandboxswitches the run to developer-sandbox mode: scope and namespace come from the personal.lhp/profile.yamlplus the teamsandbox:policy inlhp.yaml. CANNOT be combined withpipeline_filter/pipeline_fields.- Stability:
provisional
- Raises:
ValueError – if
sandbox=Trueis combined withpipeline_filterorpipeline_fields(API misuse).lhp.errors.LHPError – same families as
ValidationFacade.validate_pipelines()—LHP-VAL-*,LHP-CFG-*,LHP-FILE-*,LHP-MULT-*,LHP-TPL-*; plus the sandbox preflight errors on asandbox=Truerun —LHP-IO-025,LHP-CFG-064,LHP-CFG-065,LHP-VAL-064.
- Parameters:
- Return type:
Iterator[LHPEvent]
YAML parsing: lhp.parsers.yaml_parser¶
- class lhp.parsers.yaml_parser.YAMLParser[source]¶
Bases:
object- can_seed = False¶
True on parsers whose caches can be warmed/seeded from a persistent store (the caching wrapper overrides this).
- Type:
Capability marker
- reserve_capacity(n)[source]¶
No-op: a non-caching parser has no cache to size.
Present so callers can size any parser uniformly without a capability check. The caching subclass overrides this.
- Parameters:
n (int)
- Return type:
None
- warm(path)[source]¶
No-op: nothing to warm (returns False). Mirrors
reserve_capacity().
- sweep_parse_cache(live_paths)[source]¶
No-op: a non-caching parser has no persistent shards to sweep.
- parse_flowgroups_from_file(file_path)[source]¶
Supports both multi-document syntax (—) and flowgroups array syntax.
- class lhp.parsers.yaml_parser.CachingYAMLParser(base_parser=None, max_cache_size=500, *, persistent_cache=None)[source]¶
Bases:
objectThread-safe caching wrapper for YAMLParser.
Uses file path + modification time as cache key to automatically invalidate cache when files change. With a
persistent_cacheattached, parse results also round-trip through on-disk shards (PersistentParseCache) so a later process can warm its in-memory sub-caches without re-reading unchanged files.- Parameters:
base_parser (YAMLParser | None)
max_cache_size (int)
persistent_cache (PersistentParseCache | None)
- can_seed = True¶
Capability marker mirroring
YAMLParser.can_seed.
- reserve_capacity(n)[source]¶
Grow-only size hint (
max(current, n)): both discovery passes call this with their own glob size; a monotonic max ensures neither pass can shrink the ceiling mid-workload. FIFO eviction in_cached_loadstill guards against unbounded growth.- Parameters:
n (int)
- Return type:
None
- parse_flowgroups_from_file(path)[source]¶
On a
_cachemiss, documents are obtained viaload_documents_allso the raw read populates_documents_cachetoo; the instance pass then hits that entry instead of re-reading the file.With a persistent store attached,
warm()first tries to seed both in-memory sub-caches from the on-disk shard, and a successful fresh parse writes the shard back. Files whose parse raises never get a shard — fatal errors re-raise identically on every run.
- load_documents_all(path, error_context=None)[source]¶
Mtime-keyed cached load; hit/miss counters shared with the flowgroup sub-cache.
- warm(path)[source]¶
Try to satisfy a future parse of
pathwithout reading the file.Order: in-memory flowgroups sub-cache, then the persistent store. A full shard seeds both in-memory sub-caches; a doc-only shard (
flowgroups is None) additionally builds the flowgroups from the cached documents and rewrites the shard as a full payload. Never raises; any failure returns False (fresh parse).
Presets: lhp.presets.preset_manager¶
Preset management with hierarchical inheritance.
Bundle integration: lhp.bundle.manager¶
- class lhp.bundle.manager.BundleManager(project_root, pipeline_config_path=None, project_config=None, event_log_name_transform=None)[source]¶
Bases:
objectManages Databricks Asset Bundle resource files.
Wipe-and-regenerate contract:
resources/lhp/is fully wiped by the CLI before sync, and BundleManager re-renders one resource file per pipeline undergenerated/<env>/. databricks.yml is never read or mutated. Catalog and schema must come from pipeline_config.yaml (per-pipeline or via the top-levelproject_defaultsblock).- Parameters:
- sync_resources_with_generated_files(output_dir, env)[source]¶
Wipe-and-regenerate contract: callers must clear
resources/lhp/before invoking this method. BundleManager only writes files for pipelines that exist underoutput_dir— it does not preserve, back up, or delete any pre-existing files.
- get_resource_file_path(pipeline_name)[source]¶
Return the path where this pipeline’s resource file is written.
Under the wipe-and-regenerate contract,
resources/lhp/is empty when sync starts and BundleManager always writes the canonical<pipeline>.pipeline.ymlfilename, so no existence probing is needed.
- generate_resource_file_content(pipeline_name, output_dir, env)[source]¶
Generate content for a bundle resource file using Jinja2 template.
Applies LHP token substitution to ALL fields in pipeline_config.yaml, enabling environment-specific configuration for node types, policies, emails, and all other pipeline settings. Catalog and schema MUST be defined in pipeline_config.yaml (either per-pipeline or via the top-level
project_defaultsblock); they are never read fromdatabricks.yml.Catalog/schema validation is performed upstream by
bundle.preflight.validate_catalog_schemabefore any wipes occur. The guard here is a defense-in-depth assertion that fires only if a non-CLI caller invokes this method without running preflight first.- Parameters:
- Returns:
YAML content for the resource file with fully substituted pipeline config
- Raises:
LHPConfigError –
LHP-GEN-001if preflight was bypassed and catalog/schema is still missing/empty at the bundle-write phase.- Return type:
- emit_wheels_bundle_file(output_dir, env)[source]¶
Write the LHP-owned
resources/lhp/_wheels.bundle.ymlforenv.Self-derives the wheel-mode pipeline list from
output_dir(symmetric with_inject_wheel_dependency— the API layer passes nothing extra): every generated pipeline directory whose resolved packaging mode is"wheel". The emitted fragment setstargets.<env>.workspace.artifact_pathto the resolved UC volume (so DAB uploads the wheels referenced byenvironment.dependenciesthere) and excludes the_wheels/staging dir from the bundle file sync. It declares NOartifacts:block: each wheel reaches Databricks as a prebuilt local library reference that DAB uploads and rewrites itself (R2).No-op when there are zero wheel pipelines: nothing is written and the method returns early, so source-only projects gain no bundle file.
${bundle.target}in the sync-exclude is a Databricks bundle runtime variable, emitted literally — it is NOT an LHP token and is never substituted here.
Configuration models: lhp.models¶
Pydantic models that mirror the on-disk YAML schema. Import these to type your own loaders or to construct configurations programmatically.
Configuration models for LHP (project, action, flowgroup, blueprint, monitoring, test).
Each model is defined in an underscore-prefixed sub-module so the public surface is explicit and the package contract is auditable. Import every public class from lhp.models directly; sub-module paths are internal and may change.
- class lhp.models.Action(*, name, type, source=None, target=None, description=None, readMode=None, write_target=None, transform_type=None, sql=None, sql_path=None, operational_metadata=None, expectations_file=None, mode=None, quarantine=None, schema_inline=None, schema_file=None, enforcement=None, module_path=None, depends_on=None, function_name=None, parameters=None, custom_datasource_class=None, once=None, test_type=None, on_violation=None, tolerance=None, columns=None, filter=None, reference=None, source_columns=None, reference_columns=None, required_columns=None, column=None, min_value=None, max_value=None, lookup_table=None, lookup_columns=None, lookup_result_columns=None, expectations=None, test_id=None)[source]¶
Bases:
BaseModel- Parameters:
name (str)
type (ActionType)
source (str | List[str | Dict[str, Any]] | Dict[str, Any] | None)
target (str | None)
description (str | None)
readMode (str | None)
write_target (WriteTarget | Dict[str, Any] | None)
transform_type (TransformType | None)
sql (str | None)
sql_path (str | None)
expectations_file (str | None)
mode (str | None)
quarantine (QuarantineConfig | None)
schema_inline (str | None)
schema_file (str | None)
enforcement (str | None)
module_path (str | None)
function_name (str | None)
custom_datasource_class (str | None)
once (bool | None)
test_type (str | None)
on_violation (str | None)
tolerance (int | None)
filter (str | None)
reference (str | None)
column (str | None)
min_value (Any | None)
max_value (Any | None)
lookup_table (str | None)
test_id (str | None)
- class lhp.models.Blueprint(*, name, version='1.0', description=None, parameters=[], flowgroups)[source]¶
Bases:
BaseModelA reusable collection of flowgroups instantiated once per BlueprintInstance.
Distinguishing fields from a regular flowgroup file are parameters and flowgroups (the array of BlueprintFlowgroupSpec). looks_like_blueprint() keys on the presence of both fields together with the absence of actions.
- Parameters:
name (str)
version (str)
description (str | None)
parameters (List[BlueprintParameter])
flowgroups (List[BlueprintFlowgroupSpec])
- class lhp.models.BlueprintFlowgroupSpec(*, pipeline, flowgroup, job_name=None, variables=None, presets=[], use_template=None, template_parameters=None, actions=[], operational_metadata=None)[source]¶
Bases:
BaseModelA flowgroup template inside a blueprint.
Same shape as FlowGroup, but pipeline and flowgroup are templates that contain %{var} placeholders resolved at expansion time against instance parameter values.
- class lhp.models.BlueprintInstance(*, use_blueprint=None, parameters=None, overrides=None, blueprint=None)[source]¶
Bases:
BaseModelAn instance of a blueprint with concrete parameter values.
Two input shapes are accepted:
New (preferred):
use_blueprint:references the blueprint and a nestedparameters:block holds parameter values; an optionaloverrides:block is reserved for future use. This shape mirrors theuse_template:/template_parameters:pattern operators already know.Legacy (deprecated, removed in V0.9):
blueprint:plus flat top-level parameter keys. A deprecation warning is emitted once per file when this form is encountered.
A model_validator(mode=’before’) is the single normalization point: it converts both shapes into the canonical (use_blueprint, parameters) form so all downstream code reads from one place. Mixing the two forms in the same file raises LHP-CFG-061.
- Parameters:
- class lhp.models.BlueprintParameter(*, name, required=False, default=None, description=None)[source]¶
Bases:
BaseModel
- class lhp.models.EventLogConfig(*, enabled=True, catalog=None, schema=None, name_prefix='', name_suffix='')[source]¶
Bases:
BaseModelProject-level event log configuration for pipeline resource generation.
- class lhp.models.FlowGroup(*, pipeline, flowgroup, job_name=None, variables=None, presets=[], use_template=None, template_parameters=None, actions=[], operational_metadata=None)[source]¶
Bases:
BaseModel
- class lhp.models.FlowGroupContext(flowgroup, source_yaml, synthetic=False, auxiliary_files=<factory>)[source]¶
Bases:
objectEnvelope carrying per-flowgroup provenance across the worker boundary.
- class lhp.models.MetadataColumnConfig(*, expression, description=None, applies_to=['streaming_table', 'materialized_view'], additional_imports=None, enabled=True)[source]¶
Bases:
BaseModel
- class lhp.models.MonitoringConfig(*, enabled=True, pipeline_name=None, catalog=None, schema=None, streaming_table='all_pipelines_event_log', checkpoint_path='', job_config_path=None, max_concurrent_streams=10, materialized_views=None, enable_job_monitoring=False)[source]¶
Bases:
BaseModelProject-level monitoring pipeline configuration.
Generates two artifacts:
A standalone notebook that runs N independent streaming queries (one per pipeline event log) appending into a user-created Delta table.
A DLT pipeline with materialized views only, reading from that Delta table.
A Databricks Workflow job chains: notebook_task (union) → pipeline_task (MVs).
- class lhp.models.MonitoringMaterializedViewConfig(*, name, sql=None, sql_path=None)[source]¶
Bases:
BaseModelConfiguration for a single monitoring materialized view.
- class lhp.models.OperationalMetadataSelection(*, enabled=True, preset=None, columns=None, include_columns=None, exclude_columns=None)[source]¶
Bases:
BaseModel
- class lhp.models.Preset(*, name, version='1.0', extends=None, description=None, defaults=None)[source]¶
Bases:
BaseModel
- class lhp.models.ProjectConfig(*, name, version='1.0', description=None, author=None, created_date=None, include=None, blueprint_include=None, instance_include=None, operational_metadata=None, event_log=None, monitoring=None, required_lhp_version=None, test_reporting=None, uc_tagging=None, wheel=None, sandbox=None, apply_formatting=True)[source]¶
Bases:
BaseModelProject-level configuration loaded from lhp.yaml.
- Parameters:
name (str)
version (str)
description (str | None)
author (str | None)
created_date (str | None)
operational_metadata (ProjectOperationalMetadataConfig | None)
event_log (EventLogConfig | None)
monitoring (MonitoringConfig | None)
required_lhp_version (str | None)
test_reporting (TestReportingConfig | None)
uc_tagging (UCTaggingConfig | None)
wheel (WheelConfig | None)
sandbox (SandboxConfig | None)
apply_formatting (bool)
- class lhp.models.ProjectOperationalMetadataConfig(*, columns, presets=None, defaults=None)[source]¶
Bases:
BaseModel- Parameters:
columns (Dict[str, MetadataColumnConfig])
presets (Dict[str, MetadataPresetConfig] | None)
- class lhp.models.QuarantineConfig(*, dlq_table, source_table)[source]¶
Bases:
BaseModelConfiguration for quarantine mode in data quality transforms.
- class lhp.models.SandboxConfig(*, strategy='table', table_pattern='{namespace}_{table}', allowed_envs=None)[source]¶
Bases:
BaseModelTeam-level sandbox policy from the
sandbox:block inlhp.yaml.
- class lhp.models.SandboxProfile(*, namespace, pipelines)[source]¶
Bases:
BaseModelPersonal sandbox profile from gitignored
.lhp/profile.yaml.Explicit opt-in only: the namespace and pipeline scope are always stated by the developer — never auto-detected.
- class lhp.models.Template(*, name, version='1.0', description=None, presets=[], parameters=[], actions=[])[source]¶
Bases:
BaseModel- Parameters:
- model_post_init(context, /)¶
This function is meant to behave like a BaseModel method to initialize private attributes.
It takes context as an argument since that’s what pydantic-core passes when calling it.
- Parameters:
self (BaseModel) – The BaseModel instance.
context (Any) – The context.
- Return type:
None
- class lhp.models.TestReportingConfig(*, module_path, function_name, config_file=None)[source]¶
Bases:
BaseModel
- class lhp.models.UCTaggingConfig(*, enabled=True, remove_undeclared_tags=False, tag_update_concurrency=16)[source]¶
Bases:
BaseModelProject-level
uc_taggingconfiguration from lhp.yaml.The feature is on by default: an absent
uc_taggingblock behaves as these defaults (enabled). Users opt IN simply by declaringtagson a table or column — the hook is emitted only when some write action or schema column declarestags(auto-detection). To disable the feature, setuc_tagging.enabled: falsein lhp.yaml.remove_undeclared_tagsselects the reconcile behavior: when False (default) tag setting is purely additive (create/update only); when True the hook also deletes any existing tag whose key is not in the declared set for a managed entity (reconcile to the declared state).tag_update_concurrencyis the max concurrent tag operations (the hook’s ThreadPoolExecutormax_workersfor the one-shot pass over all tables/columns); defaults to 16.
- class lhp.models.ViolationAction(*values)[source]¶
-
Actions to take when test expectations are violated.
- class lhp.models.WheelConfig(*, artifact_volume=None)[source]¶
Bases:
BaseModelPer-project wheel packaging configuration.
- Parameters:
artifact_volume (str | None)
- class lhp.models.WriteTarget(*, type, catalog=None, schema=None, database=None, table=None, create_table=True, comment=None, table_properties=None, tags=None, tags_file=None, partition_columns=None, cluster_columns=None, cluster_by_auto=None, spark_conf=None, table_schema=None, row_filter=None, temporary=False, path=None, refresh_schedule=None, refresh_policy=None, sql=None, sql_path=None, sink_type=None, sink_name=None, bootstrap_servers=None, topic=None, module_path=None, custom_sink_class=None, batch_handler=None, options=None)[source]¶
Bases:
BaseModelWrite target configuration for streaming tables, materialized views, and sinks.
- Parameters:
type (WriteTargetType)
catalog (str | None)
schema (str | None)
database (str | None)
table (str | None)
create_table (bool)
comment (str | None)
tags_file (str | None)
cluster_by_auto (bool | None)
table_schema (str | None)
row_filter (str | None)
temporary (bool)
path (str | None)
refresh_schedule (str | None)
refresh_policy (str | None)
sql (str | None)
sql_path (str | None)
sink_type (str | None)
sink_name (str | None)
bootstrap_servers (str | None)
topic (str | None)
module_path (str | None)
custom_sink_class (str | None)
batch_handler (str | None)
Errors and exceptions: lhp.errors¶
Catch LHPError for any LHP-originated failure. The concrete subclasses
disambiguate configuration, validation, and I/O failures and carry an error
code that maps to an entry in the error reference.
Domain error types and text formatting for LHP.
No Rich/colorama/click dependencies — Rich rendering lives in
lhp.cli.error_panel.render_error_panel.
- exception lhp.errors.LHPConfigError(category, code_number, title, details, suggestions=None, example=None, context=None, doc_link=None)[source]¶
Bases:
LHPError,ValueErrorLHPError subclass for configuration errors.
Also a ValueError for backward compatibility with existing
except ValueErrorhandlers.
- exception lhp.errors.LHPError(category, code_number, title, details, suggestions=None, example=None, context=None, doc_link=None)[source]¶
Bases:
ExceptionUser-friendly error with formatting support.
Base class for all LHP-specific exceptions. Subclasses use dual inheritance (e.g.
LHPValidationError(LHPError, ValueError)) so that existingexcept ValueErrorhandlers still catch them.- Parameters:
- classmethod from_unexpected_exception(exc, operation)[source]¶
Wrap a non-LHP, non-Bundle exception as an LHPError for CLI rendering.
Used by
cli_error_boundary()to surface generic fallback failures through the project’s unified Rich panel UX rather than as plain stderr lines. The full Python traceback is intentionally NOT carried on the returned LHPError; callers are expected tologger.exception(...)so the traceback lands in the log file only.- Parameters:
exc (BaseException)
operation (str)
- Return type:
- exception lhp.errors.LHPFileError(category, code_number, title, details, suggestions=None, example=None, context=None, doc_link=None)[source]¶
Bases:
LHPError,FileNotFoundErrorLHPError subclass that is also a FileNotFoundError.
Use when replacing a bare FileNotFoundError so that existing
except FileNotFoundErrorhandlers continue to catch it.
- exception lhp.errors.LHPValidationError(category, code_number, title, details, suggestions=None, example=None, context=None, doc_link=None)[source]¶
Bases:
LHPError,ValueErrorLHPError subclass that is also a ValueError.
Use when replacing a bare ValueError so that existing
except ValueErrorhandlers continue to catch it.
Version (Experimental): lhp.utils.version¶
Version utilities for LakehousePlumber.
Notes on usage¶
All public classes log through
logging.getLogger("lhp.<module>"). Configure thelhplogger to control LHP output independently of your application’s logging.LHP raises
LHPError(or a subclass) for every recoverable failure. Unexpected exceptions indicate a bug; file an issue with the traceback.Pydantic v2 powers
lhp.models. Treat the models as immutable once constructed; usemodel_copy(update=...)for derived instances.Construct one
LakehousePlumberApplicationFacadeper run; it is not thread-safe.CachingYAMLParseris thread-safe and shared internally.
Most users should drive LHP through the CLI reference rather than the Python API. For the design rationale behind the engine, see the How Lakehouse Plumber works concept page.