Generate Prometheus Text Exposition Format in Python

Mock a Prometheus metrics endpoint by formatting metrics into the text exposition format with HELP, TYPE, and sample lines.

Easy Python 3.9+ Aug 9, 2026 Observability & SRE 13 views 0 copies

Python code

35 lines
Python 3.9+
import time
from random import randint

# Mock a Prometheus metrics endpoint output
metrics = {
    "http_requests_total": {
        "help": "Total number of HTTP requests",
        "type": "counter",
        "samples": [
            {"labels": {"method": "get", "code": "200"}, "value": randint(1000, 9999)},
            {"labels": {"method": "post", "code": "201"}, "value": randint(100, 999)},
        ],
    },
    "process_cpu_seconds_total": {
        "help": "Total user and system CPU time spent in seconds",
        "type": "counter",
        "samples": [{"labels": {}, "value": round(time.process_time(), 3)}],
    }
}

def format_exposition(metrics):
    lines = []
    for metric_name, data in metrics.items():
        lines.append(f"# HELP {metric_name} {data['help']}")
        lines.append(f"# TYPE {metric_name} {data['type']}")
        for sample in data["samples"]:
            if sample["labels"]:
                labels = ",".join(f'{k}="{v}"' for k, v in sample["labels"].items())
                lines.append(f'{metric_name}{{{labels}}} {sample["value"]}')
            else:
                lines.append(f'{metric_name} {sample["value"]}')
    return "\n".join(lines)

if __name__ == "__main__":
    print(format_exposition(metrics))

Output

stdout
# HELP http_requests_total Total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total{method="get",code="200"} 4387
http_requests_total{method="post",code="201"} 532
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 0.123

How it works

The function iterates over each metric, emitting a HELP and TYPE line followed by sample lines. Labels are formatted as key=value pairs and enclosed in braces, with no spaces after commas per the exposition format spec. The output is joined with newlines, ready to be served by an HTTP endpoint. This pattern matches what Prometheus scrapers expect, enabling local testing of dashboards and alerts.

Common mistakes

  • Forgetting to escape double quotes in label values
  • Omitting the HELP or TYPE lines for each metric
  • Adding spaces after commas in label lists (Prometheus expects no spaces)
  • Not sorting label names for consistent output

Variations

  1. Use the prometheus_client library to generate exposition format directly
  2. Build the output incrementally with a list and join for large metric sets

Real-world use cases

  • Mocking a service's /metrics endpoint in integration tests without spinning a real Prometheus.
  • Generating sample metrics to validate alert rules and dashboard queries offline.
  • Serving custom application metrics in the Prometheus format from a lightweight HTTP server.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Observability & SRE

Related tutorials and quizzes for this topic.