Skip to main content

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.

Metadata

Release files for eppo-metrics-sync 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for eppo-metrics-sync 0.2.0
File Size Uploaded Provenance
eppo_metrics_sync-0.2.0.tar.gz 24.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for eppo-metrics-sync 0.2.0
File Interpreter ABI Platform
eppo_metrics_sync-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 41.8 kB

Release files / eppo_metrics_sync-0.2.0.tar.gz

Download URL eppo_metrics_sync-0.2.0.tar.gz
Size 24.6 kB
Tags Source
SHA-256 checksum
How to use checksums
64fbb06edc658720b2f248d526e88b6d3c6104ac46ca954bbd3e94c3263897a9
BLAKE2b-256 checksum
How to use checksums
3f14aa777fc164e1c68c0e5df3c99bdb286aafc6aa7b1594c7634a8bda1c09ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release files / eppo_metrics_sync-0.2.0-py3-none-any.whl

Download URL eppo_metrics_sync-0.2.0-py3-none-any.whl
Size 17.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
95e3a4c831e5ec24802c963c30623705001439ad4fa70f3caf692250a3013e09
BLAKE2b-256 checksum
How to use checksums
01d3331862fcd0fb51001eee35f1da5b47cbef9ae37b3e2a629576739fe1fa1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Security for eppo-metrics-sync 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for eppo_metrics_sync-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page