meridian_tools.runner

Pipeline orchestration for meridian-tools.

Module: meridian_tools.runner

Functions

run_pipeline

def run_pipeline(
    run_config: PipelineRunConfig,
    *,
    progress_callback: Callable | None = None,
) -> PipelineRunResult

Execute the full meridian-tools staged pipeline.

The pipeline proceeds through the following stages in order:

  1. 00_run_metadata — Archive source and resolved configs and write input_data_provenance.json.
  2. 10_validation — Write validation spec (if validation-aware).
  3. 20_model_fit — Build input data, construct the Meridian model, sample prior and posterior.
  4. 30_model_assessment — Export diagnostics, model summary, and model selection outputs.
  5. 40_decomposition — Export summary metrics.
  6. 60_response_curves — Export response curves (if configured).
  7. 70_optimisation — Export optimisation results (if configured).

The manifest is written to disk after each stage, so a failure mid-pipeline leaves a readable partial manifest.

Before creating the dated run directory, the runner enforces three separate pre-run checks:

  1. dependency preflight (google-meridian[schema], optional plot support)
  2. validation-execution contract checks for incompatible single-run validation combinations
  3. a narrow wrapper-owned config/data preflight over the resolved input file and authored column mapping

The wrapper-owned preflight checks exactly:

  • resolved data.path exists and is a regular file
  • the CSV header row can be read
  • the parsed header is non-empty
  • no parsed header cell is blank after trimming whitespace
  • every authored scalar entry in data.coord_to_columns exists in the header
  • every authored list member in data.coord_to_columns exists in the header
  • every authored key in media_to_channel, media_spend_to_channel, reach_to_channel, frequency_to_channel, rf_spend_to_channel, organic_reach_to_channel, and organic_frequency_to_channel exists in the header
  • authored list-valued coord families are non-empty
  • authored mapping fields above are non-empty
  • supported media/RF family groups are complete when authored

Header matching is exact and case-sensitive. Anything outside this closed matrix remains Meridian-owned validation.

Parameters:

  • run_config — A PipelineRunConfig specifying the execution config path, output directory, run name, optional validation spec, and optional source_config_path for metadata archival.
  • progress_callback — Optional callable invoked on stage lifecycle events. The callback receives keyword arguments:
    • stage_name (str) — stage identifier.
    • event (str) — one of "started", "completed", "skipped", or "failed".
    • stage_index (int) — 1-based position in the pipeline.
    • stage_count (int) — total number of stages.
    • elapsed_seconds (float) — wall-clock time (present for "completed" and "failed" events).
    • message (str) — human-readable detail (present for "skipped" and "failed" events).

Returns: A PipelineRunResult with the run directory and manifest path.

Raises:

  • RuntimeError if Meridian schema support is unavailable (checked at preflight before the run directory is created).
  • RuntimeError if exports.export_plots is true but vl-convert-python is not installed (also checked at preflight).
  • ValidationExecutionContractError if the requested single-run validation execution path is incompatible with the authored config.
  • ConfigPreflightError if wrapper-owned config/data preflight fails before run-directory creation.
  • PipelineRunFailure if any exception occurs after the dated run directory already exists.

Example:

from pathlib import Path
from meridian_tools.config import PipelineRunConfig
from meridian_tools.runner import run_pipeline

result = run_pipeline(
    PipelineRunConfig(
        config_path=Path("project.yml"),
        output_dir=Path("runs"),
    )
)

print(result.run_dir)
print(result.manifest_path)

Classes

PipelineRunResult

@dataclass(frozen=True)
class PipelineRunResult

Disk locations for one completed meridian-tools run.

Attribute Type Description
run_dir Path Absolute path to the run directory.
manifest_path Path Absolute path to run_manifest.json.

ValidationExecutionContractError

class ValidationExecutionContractError(ValueError)

Raised when the requested single-run validation execution path is incompatible with the authored config. Current examples include direct rolling_origin execution through run_pipeline(...) and combining PipelineRunConfig.validation_spec with authored model_spec.kwargs.holdout_id.


ConfigPreflightError

class ConfigPreflightError(ValueError)

Raised when the wrapper-owned Phase 10 preflight fails before run-directory creation. This covers only the closed wrapper preflight boundary, not full Meridian model validation.


PipelineRunFailure

class PipelineRunFailure(RuntimeError)

Raised when a run fails after the dated run directory already exists. The original underlying exception is preserved via __cause__.

Attribute Type Description
run_dir Path Absolute failed run directory.
manifest_path Path Absolute path to the failed run manifest.
stage_name str | None Failing stage name when one is available.

Constants

Stage names

Constant Value
STAGE_RUN_METADATA "00_run_metadata"
STAGE_VALIDATION "10_validation"
STAGE_MODEL_FIT "20_model_fit"
STAGE_MODEL_ASSESSMENT "30_model_assessment"
STAGE_DECOMPOSITION "40_decomposition"
STAGE_RESPONSE_CURVES "60_response_curves"
STAGE_OPTIMISATION "70_optimisation"

PIPELINE_STAGE_ORDER

PIPELINE_STAGE_ORDER: tuple[str, ...] = (
    "00_run_metadata",
    "10_validation",
    "20_model_fit",
    "30_model_assessment",
    "40_decomposition",
    "60_response_curves",
    "70_optimisation",
)

The numbering gap at 50 is intentional, reserving space for future stages.