# promrs

Fast [Prometheus](https://prometheus.io/) client for Python, backed by Rust.

**promrs** is an independent, MIT-licensed reimplementation of the
[prometheus_client](https://github.com/prometheus/client_python) Python API.
The core metric logic (counters, gauges, histograms, text encoding) runs in Rust
via [PyO3](https://pyo3.rs/), while the Python layer provides the familiar
`prometheus_client`-style interface: `Counter`, `Gauge`, `Histogram`, labels,
context managers, and `generate_latest`.

## Why?

| | promrs | prometheus_client |
|---|---|---|
| **License** | Apache 2.0 | Apache 2.0 |
| **Core language** | Rust | Python |
| **Output format** | OpenMetrics text | Prometheus / OpenMetrics text |

* **Performance** — metric recording and scrape encoding happen in Rust with
  no GIL overhead. The GIL is released during `generate_latest`.

## Installation

```bash
pip install promrs
```

Requires Python 3.12+. Pre-built wheels are available for Linux (x86_64, aarch64)
and macOS (x86_64, Apple Silicon).

## Quick start

```python
from promrs import Counter, Histogram, generate_latest, REGISTRY

# Counter
requests = Counter("http_requests_total", "Total HTTP requests", ["method", "path"])
requests.labels(method="GET", path="/api").inc()

# Histogram
latency = Histogram(
    "http_request_duration_seconds",
    "Request latency",
    ["method"],
    buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 5.0],
)
with latency.labels(method="GET").time():
    pass  # timed block

# Scrape
output: bytes = generate_latest()  # uses the default REGISTRY
```

## API

### Metric types

| Class | Methods | Context managers |
|---|---|---|
| `Counter` | `inc(amount=1.0)`, `labels(*args, **kwargs)` | `count_exceptions(exception=BaseException)` |
| `Gauge` | `set(value)`, `inc(amount=1.0)`, `dec(amount=1.0)`, `set_to_current_time()`, `labels(...)` | `time()`, `track_inprogress()` |
| `Histogram` | `observe(value)`, `labels(...)` | `time()` |

All metric constructors accept: `name`, `documentation`, `labelnames`, `namespace`,
`subsystem`, `unit`, `registry`.

### Registry

```python
from promrs import CollectorRegistry, Counter, generate_latest

registry = CollectorRegistry()
c = Counter("my_counter", "help", registry=registry)
c.inc()

output = generate_latest(registry)
```

A default global `REGISTRY` is provided and used when no `registry` argument is given.

### Content type

```python
from promrs import CONTENT_TYPE_LATEST

# "application/openmetrics-text; version=1.0.0; charset=utf-8"
```

## Development

Prerequisites: [Rust](https://rustup.rs/), [uv](https://docs.astral.sh/uv/).

```bash
make deps   # install Python deps + build the Rust extension
make lint   # ruff + pyright + cargo fmt + clippy
make test   # pytest
make bench  # pyperf benchmark vs prometheus_client
```

## License

[Apache 2.0](LICENSE)
