Skip to content

Repository files navigation

Eppo Metrics Sync

PyPI version Tests

A Python package for syncing metric definitions with Eppo's API. Manage your Eppo metrics as code using YAML files. Documentation is available in Eppo's documentation page.

Features

  • Sync metrics and fact sources to Eppo
  • Validate metric definitions locally
  • Support for dbt models
  • Dry-run capability for testing
  • Prefix support for testing in shared workspaces
  • Asynchronous syncing with status polling, so large syncs don't hit request timeouts

Installation

pip install eppo-metrics-sync

Usage

Basic usage

  1. Set required environment variables:
export EPPO_API_KEY="your-api-key"

export EPPO_SYNC_TAG="your-sync-tag" # optional

export EPPO_REFERENCE_URL="your-reference-url" # optional

export EPPO_SYNC_POLL_INTERVAL="5" # optional, seconds between status checks

export EPPO_SYNC_POLL_TIMEOUT="600" # optional, seconds to wait for the sync to finish
  1. Create your metrics YAML files (see Documentation)

  2. Run the sync:

python -m eppo_metrics_sync path/to/yaml/directory

CLI Options

python -m eppo_metrics_sync [OPTIONS] DIRECTORY

Options:

  • --dryrun Validate files without syncing to Eppo
  • --schema Schema type: eppo (default) or dbt-model
  • --sync-prefix Prefix for fact/metric names (useful for testing)
  • --dbt-model-prefix Warehouse/schema prefix for dbt models
  • --allow-upgrades Allow existing non-certified metrics/fact sources to become certified
  • --poll-interval Seconds between sync status checks (default: 5)
  • --poll-timeout Seconds to wait for the sync to complete before giving up (default: 600)

When to use --allow-upgrades

The --allow-upgrades flag is useful in the following scenarios:

  • Promoting existing metrics to certified status: If you have existing metrics or fact sources in Eppo that are not currently certified, this flag allows them to be upgraded to certified status during the sync process.
  • Migrating from manual to code-managed metrics: When transitioning from manually created metrics in the Eppo UI to managing them through YAML files, this flag enables the promotion of those metrics to certified status.
  • Avoiding conflicts during migration: Without this flag, attempting to sync metrics that already exist in a non-certified state may result in conflicts or the sync process not upgrading their certification status.

How syncing works

As of version 0.2.0, eppo_metrics_sync submits metrics to Eppo's asynchronous sync endpoint and then polls for the result:

  1. Local YAML files are loaded and validated.
  2. The payload is submitted to POST /api/v1/metrics/sync/async, which returns a sync id immediately with a status of pending.
  3. GET /api/v1/metrics/sync/{id} is polled every --poll-interval seconds until the sync reports success or failed, or until --poll-timeout is reached.

If the payload is identical to the last successful sync for the same sync tag, Eppo reports that there is nothing to do and the sync finishes immediately without polling. This is a success, so scheduled syncs of unchanged metrics exit zero.

Note that Eppo rate limits these endpoints: 12 sync submissions per minute and 60 status checks per minute. The default 5 second poll interval stays well inside the status limit; intervals below 1 second risk tripping it.

The process exits non-zero if the sync fails, and any errors reported by Eppo are printed. If the poll timeout is reached the process exits non-zero as well, but note that the sync may still be running in Eppo — the timeout stops the client from waiting, not the sync itself. You can raise --poll-timeout for large metric repositories.

EppoMetricsSync.sync() returns the final sync status as a dict, for example:

{"id": 1234, "sync_tag": "your-sync-tag", "status": "success"}

When the payload was unchanged, no sync is created, so there is no id and the dict is flagged instead:

{"sync_tag": "your-sync-tag", "status": "success", "unchanged": True}

Upgrading from 0.1.x: sync() previously returned the requests.Response from the synchronous endpoint. If you were inspecting that return value, read the status dict described above instead. The CLI interface is unchanged apart from the two new polling flags.

Validation Rules & Constraints

The following validation rules are enforced when syncing metrics. Understanding these constraints upfront can help avoid validation errors during development:

Winsorization Constraints

Winsorization parameters (winsorization_lower_percentile, winsorization_upper_percentile) can only be used with these aggregation operations:

  • ✅ sum
  • ✅ count
  • ✅ count_distinct
  • ✅ last_value
  • ✅ first_value

Not supported for:

  • ❌ distinct_entity - Binary metrics don't need winsorization
  • ❌ threshold - Threshold logic handles outliers differently
  • ❌ retention - Binary retention metrics don't need winsorization
  • ❌ conversion - Binary conversion metrics don't need winsorization

Advanced Aggregation Parameters

Each advanced aggregation type requires its specific parameter and cannot use others:

Threshold Metrics

  • Required: threshold_metric_settings object with:
    • comparison_operator: "gt" or "gte"
    • aggregation_type: "sum" or "count" (not count_distinct)
    • breach_value: numeric threshold value
  • Cannot use: retention_threshold_days, conversion_threshold_days
  • Cannot use: Timeframe parameters (aggregation_timeframe_start_value, aggregation_timeframe_end_value, aggregation_timeframe_unit)

Retention Metrics

  • Required: retention_threshold_days (numeric)
  • Cannot use: threshold_metric_settings, conversion_threshold_days

Conversion Metrics

  • Required: conversion_threshold_days (numeric)
  • Cannot use: threshold_metric_settings, retention_threshold_days
  • Cannot use: Timeframe parameters (aggregation_timeframe_start_value, aggregation_timeframe_end_value)

Timeframe Parameters

When using aggregation timeframe parameters:

  • Required: aggregation_timeframe_unit must be specified if any timeframe parameters are used
  • Supported units: "minutes", "hours", "days", "weeks", "calendar_days"
  • Not supported for: conversion operations (use conversion_threshold_days instead)

Denominator Constraints

For ratio metrics, denominators can only use these operations:

  • ✅ sum, count, count_distinct, distinct_entity, last_value, first_value
  • ❌ Cannot use: threshold, retention, conversion

Guardrail Cutoff Signs

When using guardrail metrics (is_guardrail: true with guardrail_cutoff):

  • If desired_change: "increase" → guardrail_cutoff must be negative
  • If desired_change: "decrease" → guardrail_cutoff must be positive

Note: The validation uses the metric's desired_change if specified, otherwise it falls back to the fact's desired_change. This allows you to override the fact-level direction when creating guardrail metrics.

Documentation

For detailed information about metric configuration, available options and constraints, see Eppo's documentation page.

Example YAML Configuration

fact_sources:
    - name: Revenue
      sql: |
          SELECT ts, user_id, amount
          FROM revenue_table
      timestamp_column: ts
      entities:
          - entity_name: User
            column: user_id
      facts:
          - name: Revenue
            column: amount

metrics:
    - name: Total Revenue
      description: Sum of Total Purchase Value in Purchases Fact Table
      entity: User
      numerator:
          fact_name: Revenue
          operation: sum
      desired_change: increase

Development

Setup

Create a virtual environment

python -m venv .venv
source .venv/bin/activate

Install dependencies

pip install -r requirements.txt

Running the tests

pytest tests

Running the package

export EPPO_API_KEY="your-api-key"
export EPPO_SYNC_TAG="your-sync-tag"
export EPPO_REFERENCE_URL="your-reference-url"
python -m eppo_metrics_sync path/to/yaml/directory

Building and Publishing

For package maintainers:

  1. Update version in pyproject.toml
  2. Build the package:
python -m build
  1. The package will be automatically published to PyPI when a new release is created on GitHub.

About

CLI for syncing metric yaml files to Eppo

Resources

Stars

1 star

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages