Skip to content

Commit 923357a

Browse files
committed
refactor: Remove duplicated escape helper logic
1 parent 6a324d6 commit 923357a

2 files changed

Lines changed: 19 additions & 30 deletions

File tree

src/ai/backend/common/dto/manager/v2/prometheus_query_preset/validators.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,31 @@
66

77
from ai.backend.common.exception import InvalidMetricPresetTemplate
88

9-
__all__ = ("validate_query_template",)
9+
__all__ = (
10+
"PLACEHOLDER_NAMES",
11+
"escape_non_placeholders",
12+
"validate_query_template",
13+
)
14+
15+
PLACEHOLDER_NAMES = frozenset({"labels", "window", "group_by"})
1016

11-
_PLACEHOLDER_NAMES = frozenset({"labels", "window", "group_by"})
1217
_BRACE_BLOCK_RE = re.compile(r"\{([^{}]*)\}")
1318
_UNSUPPORTED_TEMPLATE_VAR_RE = re.compile(r"\$\{[^}]+\}|\$[A-Za-z_][A-Za-z0-9_]*")
1419

1520

16-
def _escape_non_placeholders(template: str) -> str:
21+
def escape_non_placeholders(template: str) -> str:
22+
"""Normalize each ``{X}`` so ``str.format`` produces a single PromQL ``{value}``
23+
regardless of how many braces the user wrote.
24+
"""
25+
1726
def repl(match: re.Match[str]) -> str:
1827
name = match.group(1)
1928
start, end = match.span()
2029
text = match.string
2130
already_wrapped = (
2231
start > 0 and text[start - 1] == "{" and end < len(text) and text[end] == "}"
2332
)
24-
if name not in _PLACEHOLDER_NAMES:
33+
if name not in PLACEHOLDER_NAMES:
2534
return match.group(0) if already_wrapped else "{{" + name + "}}"
2635
if name != "labels":
2736
return match.group(0)
@@ -36,13 +45,13 @@ def validate_query_template(template: str) -> str:
3645
raise InvalidMetricPresetTemplate("Template must not be empty.")
3746
unsupported_vars = _UNSUPPORTED_TEMPLATE_VAR_RE.findall(template)
3847
if unsupported_vars:
39-
placeholders = ", ".join(f"{{{name}}}" for name in sorted(_PLACEHOLDER_NAMES))
48+
placeholders = ", ".join(f"{{{name}}}" for name in sorted(PLACEHOLDER_NAMES))
4049
raise InvalidMetricPresetTemplate(
4150
f"Unsupported template variables: {unsupported_vars}. "
4251
f"Use placeholders {placeholders} or literal PromQL values."
4352
)
4453
try:
45-
_escape_non_placeholders(template).format(labels="", window="", group_by="")
54+
escape_non_placeholders(template).format(labels="", window="", group_by="")
4655
except (ValueError, KeyError, IndexError) as e:
4756
raise InvalidMetricPresetTemplate(
4857
f"Failed to render PromQL template ({type(e).__name__}: {e}): {template!r}"

src/ai/backend/manager/clients/prometheus/preset.py

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,13 @@
1-
import re
21
from collections.abc import Mapping, Set
32
from dataclasses import dataclass, field
43
from enum import StrEnum
54
from typing import Self
65

6+
from ai.backend.common.dto.manager.v2.prometheus_query_preset.validators import (
7+
escape_non_placeholders,
8+
)
79
from ai.backend.common.exception import InvalidMetricPresetTemplate
810

9-
_PLACEHOLDER_NAMES = frozenset({"labels", "window", "group_by"})
10-
_BRACE_BLOCK_RE = re.compile(r"\{([^{}]*)\}")
11-
12-
13-
def _escape_non_placeholders(template: str) -> str:
14-
# Normalize each `{X}` so str.format produces a single PromQL `{value}`
15-
# regardless of how many braces the user wrote.
16-
def repl(match: re.Match[str]) -> str:
17-
name = match.group(1)
18-
start, end = match.span()
19-
text = match.string
20-
already_wrapped = (
21-
start > 0 and text[start - 1] == "{" and end < len(text) and text[end] == "}"
22-
)
23-
if name not in _PLACEHOLDER_NAMES:
24-
return match.group(0) if already_wrapped else "{{" + name + "}}"
25-
if name != "labels":
26-
return match.group(0)
27-
return match.group(0) if already_wrapped else "{{" + match.group(0) + "}}"
28-
29-
return _BRACE_BLOCK_RE.sub(repl, template)
30-
3111

3212
class LabelOperator(StrEnum):
3313
EQUAL = "="
@@ -80,7 +60,7 @@ def render(self) -> str:
8060
for key, value in self.labels.items()
8161
)
8262
try:
83-
return _escape_non_placeholders(self.template).format(
63+
return escape_non_placeholders(self.template).format(
8464
labels=label_str,
8565
window=self.window,
8666
group_by=",".join(sorted(self.group_by)),

0 commit comments

Comments
 (0)