A Python library for building PromQL queries programmatically
Project description
promql-forge
A Python library for programmatically building PromQL queries providing an API to construct metric selectors, label matchers, aggregations, and functions, and renders them as either compact single-line or indented multi-line PromQL strings.
As opposed to promql-builder from Grafana Labs, this lirary API follows thw SQLAlchemy's fluent style of expression building, leveraging the operators overloading where possible, making the code look more intuitive and closer to the resulting PromQL.
Features
- Instant vector selectors with label matchers:
=,!=,=~,!~ - Range vectors and subqueries
- Offset modifier and
@timestamp modifier - Binary arithmetic and comparison operators (
+,-,*,/,%,^,>,<,>=,<=,==,!=) - Set operators:
and,or,unless - Vector matching:
.on(),.ignoring(),.group_left(),.group_right() - All standard PromQL aggregations:
sum,count,avg,min,max,topk,bottomk,quantile,stddev,stdvar,group,count_values,limitk— withby/withoutmodifiers - Full PromQL function library:
rate,increase,delta,histogram_quantile,label_replace,predict_linear, all*_over_timefunctions, math functions, and more - Grafana template variable interpolation via
GrafanaVar - Compact (single-line) and pretty-printed multi-line output
Installation
pip install promql-forge
Usage
All public names are importable directly from promql_forge.
Metric selectors
from promql_forge import Metric, Label, GrafanaVar, to_promql
# Simple selector
str(Metric("http_requests_total"))
# http_requests_total
# Label matchers via keyword arguments or Label objects
m = Metric("http_requests_total")
query = m.labels(
m.job == "api-server",
m.env.matches("prod|staging"), # =~
m.version.not_matches("v0.*"), # !~
status=GrafanaVar("status"), # Grafana template variable
)
str(query)
# http_requests_total{
# job="api-server",
# env=~"prod|staging",
# version!~"v0.*",
# status="${status}"
# }
to_promql(query, compact=True)
# http_requests_total{job="api-server",env=~"prod|staging",version!~"v0.*",status="${status}"}
Range vectors, offset, and timestamp
from promql_forge import Metric, Rate, to_promql
# Range vector — compact and pretty-printed
to_promql(Rate(Metric("http_requests_total").labels(job="api").over("5m")), compact=True)
# rate(http_requests_total{job="api"}[5m])
# offset and @ modifiers
str(Metric("foo").labels(env="prod").offset("1h"))
# foo{env="prod"} offset 1h
str(Metric("foo").at("start")) # foo @ start()
str(Metric("foo") @ 1712000000) # foo @ 1712000000
Aggregations
from promql_forge import Metric, Sum, Topk, to_promql
# sum by label
str(Sum(Metric("container_cpu_usage"), by="namespace"))
# sum(container_cpu_usage) by (namespace)
# topk with multiple grouping labels; modifier-first rendering
to_promql(Topk(5, Metric("http_requests_total"), by=("job", "status")), modifier_first=True)
# topk by (job, status) (
# 5,
# http_requests_total
# )
Binary expressions and vector matching
from promql_forge import Metric, Sum, Vector, to_promql
cpu_requests = Sum(Metric("kube_pod_container_resource_requests").labels(resource="cpu"))
cpu_capacity = Sum(Metric("kube_node_status_capacity").labels(resource="cpu"))
to_promql(cpu_requests * 100 / cpu_capacity, compact=True)
# (sum(kube_pod_container_resource_requests{resource="cpu"}) * 100) / sum(kube_node_status_capacity{resource="cpu"})
# Vector matching with many-to-one cardinality
to_promql((Metric("a") * Metric("b")).on("namespace").group_left("pod"), compact=True)
# a * on(namespace) group_left(pod) b
# Set operator fallback
to_promql(Sum(Metric("up")) | Vector(0), compact=True)
# sum(up) or vector(0)
Grafana template variables
GrafanaVar renders as ${name} and can be used anywhere a string value or duration is
accepted, including range selectors.
from promql_forge import Metric, Label, GrafanaVar, Sum, Increase, to_promql
query = Sum(
Increase(
Metric("kube_pod_container_status_restarts_total").labels(
Label("namespace").matches(GrafanaVar("namespace")),
)[GrafanaVar("__range")] # variable as range duration
)
)
to_promql(query, compact=True)
# sum(increase(kube_pod_container_status_restarts_total{namespace=~"${namespace}"}[${__range}]))
Compact vs. pretty-printed output
Every expression implements to_promql(compact=False) (default, multi-line) and
to_promql(compact=True) (single line). Passing the expression to str() is equivalent to
calling to_promql() with defaults.
from promql_forge import Metric, Sum, Count, to_promql
query = Count(Sum(Metric("kube_pod_container_status_running").labels(ns="default")).by("pod") >= 1)
to_promql(query, compact=True)
# count(sum(kube_pod_container_status_running{ns="default"}) by(pod) >= 1)
str(query)
# count(
# sum(
# kube_pod_container_status_running{ns="default"}
# ) by (pod) >= 1
# )
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file promql_forge-0.1.0.tar.gz.
File metadata
- Download URL: promql_forge-0.1.0.tar.gz
- Upload date:
- Size: 10.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f105f8e44962d2e5a266ab9aac2bc95e7e9b6a289417543510a1ca3440bcde5
|
|
| MD5 |
5f2fda28ad0096aa1bcc8c4c05913899
|
|
| BLAKE2b-256 |
a8c6b38569824e90137c8a9f13f453fd7abb504d94beed88bc59e04174d87b82
|
Provenance
The following attestation bundles were made for promql_forge-0.1.0.tar.gz:
Publisher:
publish.yml on vladimir-kotikov/promql-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promql_forge-0.1.0.tar.gz -
Subject digest:
2f105f8e44962d2e5a266ab9aac2bc95e7e9b6a289417543510a1ca3440bcde5 - Sigstore transparency entry: 1202902682
- Sigstore integration time:
-
Permalink:
vladimir-kotikov/promql-forge@ffd010e0cff78b7db5b06b55f98694a30c23c32f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vladimir-kotikov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ffd010e0cff78b7db5b06b55f98694a30c23c32f -
Trigger Event:
push
-
Statement type:
File details
Details for the file promql_forge-0.1.0-py3-none-any.whl.
File metadata
- Download URL: promql_forge-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5264f5ba4bb711b943a1327ba07cbd2fc56e0c70dec2e0e64d018715cd7f01b6
|
|
| MD5 |
b0e38d65b95d17f2bcf5279b35c200ef
|
|
| BLAKE2b-256 |
a96bd2cc54cb5b59f34bb7070a1d9b7df8b1d101bcb43b9cbf52a0be109e2378
|
Provenance
The following attestation bundles were made for promql_forge-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on vladimir-kotikov/promql-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promql_forge-0.1.0-py3-none-any.whl -
Subject digest:
5264f5ba4bb711b943a1327ba07cbd2fc56e0c70dec2e0e64d018715cd7f01b6 - Sigstore transparency entry: 1202902714
- Sigstore integration time:
-
Permalink:
vladimir-kotikov/promql-forge@ffd010e0cff78b7db5b06b55f98694a30c23c32f -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/vladimir-kotikov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ffd010e0cff78b7db5b06b55f98694a30c23c32f -
Trigger Event:
push
-
Statement type: