-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathengine.py
More file actions
67 lines (54 loc) · 2.08 KB
/
Copy pathengine.py
File metadata and controls
67 lines (54 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""The rule engine: run a set of rules over one event and roll up the result."""
from __future__ import annotations
import time
from collections.abc import Sequence
from pydantic import BaseModel, ConfigDict
from veritas.domain.models import ResolvedEvent, Verdict
from veritas.rules.base import RecordStatus, Rule, RuleContext, rollup_status
from veritas.rules.metrics import (
NullMetricsSink,
RuleMetric,
RuleMetricsSink,
severity_for,
)
class RuleReport(BaseModel):
"""All rule verdicts for one event plus the record-level rollup."""
model_config = ConfigDict(extra="forbid")
event_id: str
status: RecordStatus
verdicts: list[Verdict]
class RuleEngine:
"""Runs an ordered set of rules. Stateless except for any state a rule owns
(e.g. the duplicate rule's seen-set), so one engine instance is one run."""
def __init__(
self,
rules: Sequence[Rule],
metrics: RuleMetricsSink | None = None,
) -> None:
self._rules: tuple[Rule, ...] = tuple(rules)
# Depends only on the Protocol; defaults to the no-op sink.
self._metrics: RuleMetricsSink = metrics if metrics is not None else NullMetricsSink()
@property
def rules(self) -> tuple[Rule, ...]:
return self._rules
def evaluate(self, event: ResolvedEvent, ctx: RuleContext) -> RuleReport:
verdicts: list[Verdict] = []
for rule in self._rules:
start = time.perf_counter()
verdict = rule.evaluate(event, ctx)
latency_ms = (time.perf_counter() - start) * 1000.0
if verdict is not None:
verdicts.append(verdict)
self._metrics.record(
RuleMetric(
rule_name=rule.name,
verdict=verdict.status,
severity=severity_for(verdict.status),
latency_ms=latency_ms,
)
)
return RuleReport(
event_id=event.event_id,
status=rollup_status(verdicts),
verdicts=verdicts,
)