Time & subqueries
Set windows, evaluation time, offsets and subquery resolution.
A range selects raw samples from a selector. A subquery repeatedly evaluates a computed expression. Neither is a client request: DatabaseClient.query_range() is the I/O operation.
from metricraft import QueryBuilder as Q
query = (Q.from_metric("requests_total").rate("5m")
.subquery("1h", "1m").max_over_time())
print(query.build(mode="promql"))
Use positive duration strings such as 5m or 1h30m. Explicit feature opt-ins are required for supported Prometheus duration expressions and extended range selectors. A server must enable the matching feature too.
Methods and parameters
QueryBuilder
anchored()Extend an eligible Prometheus range selector with an anchored boundary sample. Only supported rollups accept it.PromQL only
QueryBuilder.anchored() -> QueryBuilder
Requires features=('promql-extended-range-selectors',) and matching server support. Eligible rollups include rate, increase, delta, changes and resets.
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
at()Evaluate a selector or subquery at a fixed Unix timestamp or at the enclosing query's start/end.
QueryBuilder.at(timestamp: Union[Number, str, datetime, QueryBuilder]) -> QueryBuilder
| Parameter / type | Meaning and accepted values |
|---|---|
timestampint | float | str | datetime | QueryBuilderRequired | Finite Unix seconds, timezone-aware datetime/ISO string, 'start'/'end' (also 'start()'/'end()'), or a supported typed scalar expression. Naive datetimes and bool are rejected. |
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
Example
from metricraft import QueryBuilder as Q
Q.from_metric("up").at("2026-01-01T00:00:00Z").build(mode="promql")end()Create a scalar for the enclosing query's end timestamp.
QueryBuilder.end() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
from_end()Create a scalar for the enclosing query's end timestamp.
QueryBuilder.from_end() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
from_now()Create a MetricsQL scalar representing current wall-clock time on the backend.MetricsQL only
QueryBuilder.from_now() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
from_start()Create a scalar for the enclosing query's start timestamp.
QueryBuilder.from_start() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
from_time()Create a scalar representing the evaluation timestamp in Unix seconds.
QueryBuilder.from_time() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
now()Create a MetricsQL scalar representing current wall-clock time on the backend.MetricsQL only
QueryBuilder.now() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
offset()Shift a selector or subquery in time. Positive offsets look into the past; negative offsets look forward.
QueryBuilder.offset(duration: Window) -> QueryBuilder
| Parameter / type | Meaning and accepted values |
|---|---|
durationstr | QueryBuilderRequired | Signed duration such as '1h' or '-5m', including zero. Typed duration expressions require dialect/feature support. |
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
query_range()Create the Prometheus range() scalar for the duration of the enclosing query. This is not a client range request.PromQL only
QueryBuilder.query_range() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
range()Select a lookbehind range of raw samples. For a computed PromQL vector, use subquery() instead.
QueryBuilder.range(window: Optional[Window]=None, *, duration: Optional[Window]=None) -> QueryBuilder
With no arguments this defaults to '5m'. For a computed PromQL expression use subquery() instead.
| Parameter / type | Meaning and accepted values |
|---|---|
windowstr | QueryBuilder | NoneDefault: None | Positive lookbehind duration, e.g. '5m' or '1h30m'. None preserves an existing range or uses MetricsQL implicit rollup; a bare selector without a window cannot build as PromQL. Duration expressions need the relevant dialect/feature support. |
durationstr | QueryBuilder | NoneDefault: None | Lookbehind duration, e.g. '5m'. Where window is also accepted, pass one name only. None preserves the current range or requests MetricsQL implicit rollup. |
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
smoothed()Extend an eligible Prometheus range selector with smoothed boundary handling. Only supported rollups accept it.PromQL only
QueryBuilder.smoothed() -> QueryBuilder
Requires features=('promql-extended-range-selectors',) and matching server support. Eligible rollups include rate, increase and delta.
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
start()Create a scalar for the enclosing query's start timestamp.
QueryBuilder.start() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
start_timestamp()Return native histogram start timestamps where available.PromQL only
QueryBuilder.start_timestamp() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
step()Create a scalar for the enclosing query's evaluation step in seconds.
QueryBuilder.step() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
subquery()Evaluate a computed expression repeatedly over a lookbehind interval, producing a range vector.
QueryBuilder.subquery(window: Optional[Window]=None, step: Optional[Window]=None, *, range_duration: Optional[Window]=None, resolution: Optional[Window]=None) -> QueryBuilder
PromQL requires an explicit positive window; MetricsQL can omit it. Duration-expression forms need the relevant feature opt-in.
| Parameter / type | Meaning and accepted values |
|---|---|
windowstr | QueryBuilder | NoneDefault: None | Positive lookbehind duration, e.g. '5m' or '1h30m'. None preserves an existing range or uses MetricsQL implicit rollup; a bare selector without a window cannot build as PromQL. Duration expressions need the relevant dialect/feature support. |
stepstr | QueryBuilder | NoneDefault: None | Positive subquery evaluation step, e.g. '30s'. None uses the backend's default subquery resolution. |
range_durationstr | QueryBuilder | NoneDefault: None | Alias of window for subquery(). Do not supply both names. |
resolutionstr | QueryBuilder | NoneDefault: None | Alias of step for subquery(). Do not supply both names. |
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.
Example
from metricraft import QueryBuilder as Q
Q.from_metric("requests_total").rate("5m").subquery("1h", "1m").max_over_time().build(mode="promql")time()Create a scalar representing the evaluation timestamp in Unix seconds.
QueryBuilder.time() -> QueryBuilder
No parameters.
Returns QueryBuilder — a new immutable expression sharing unchanged native subtrees. The receiver is unchanged; no data is queried.