|
1 | | -"""Configuration models for PII redaction rules.""" |
| 1 | +"""Configuration models for PII redaction rules. |
2 | 2 |
|
3 | | -import re |
4 | | -from typing import Self |
| 3 | +Canonical definitions live in models.config; this module re-exports them |
| 4 | +for convenient access within the capabilities package. |
| 5 | +""" |
5 | 6 |
|
6 | | -from pydantic import Field, PrivateAttr, model_validator |
7 | | - |
8 | | -from models.config import ConfigurationBase |
9 | | -from pydantic_ai_lightspeed.capabilities.redaction.core import ( |
10 | | - CompiledPatterns, |
| 7 | +from models.config import ( |
| 8 | + RedactionConfig, |
| 9 | + RedactionRule, |
11 | 10 | ) |
12 | 11 |
|
13 | | - |
14 | | -class RedactionRule(ConfigurationBase): |
15 | | - """A single regex-based redaction rule. |
16 | | -
|
17 | | - Attributes: |
18 | | - pattern: Raw regex pattern string to match sensitive data. |
19 | | - replacement: Text to substitute for each match. |
20 | | - case_sensitive: Per-rule override for case sensitivity. |
21 | | - When None, the global ``RedactionConfig.case_sensitive`` |
22 | | - flag applies. |
23 | | - """ |
24 | | - |
25 | | - pattern: str = Field( |
26 | | - ..., |
27 | | - title="Pattern", |
28 | | - description="Regex pattern to match sensitive data", |
29 | | - ) |
30 | | - replacement: str = Field( |
31 | | - ..., |
32 | | - title="Replacement", |
33 | | - description="Replacement string for matched text", |
34 | | - ) |
35 | | - case_sensitive: bool | None = Field( |
36 | | - None, |
37 | | - title="Case sensitive", |
38 | | - description=( |
39 | | - "Per-rule case sensitivity override. " |
40 | | - "When None, the global config flag applies." |
41 | | - ), |
42 | | - ) |
43 | | - |
44 | | - |
45 | | -class RedactionConfig(ConfigurationBase): |
46 | | - """Configuration for PII redaction with regex-based rules. |
47 | | -
|
48 | | - Rules are validated and compiled at construction time. Invalid |
49 | | - regex patterns raise a ``ValueError`` immediately. |
50 | | -
|
51 | | - Attributes: |
52 | | - rules: Ordered list of redaction rules applied sequentially. |
53 | | - case_sensitive: When False, patterns are compiled with |
54 | | - ``re.IGNORECASE``. Defaults to False. |
55 | | - """ |
56 | | - |
57 | | - rules: list[RedactionRule] = Field( |
58 | | - default_factory=list, |
59 | | - title="Redaction rules", |
60 | | - description="Ordered list of PII redaction rules", |
61 | | - ) |
62 | | - case_sensitive: bool = Field( |
63 | | - False, |
64 | | - title="Case sensitive", |
65 | | - description=("When False, patterns are compiled with re.IGNORECASE"), |
66 | | - ) |
67 | | - |
68 | | - _compiled_patterns: CompiledPatterns = PrivateAttr( |
69 | | - default_factory=list, |
70 | | - ) |
71 | | - |
72 | | - @model_validator(mode="after") |
73 | | - def compile_patterns(self) -> Self: |
74 | | - """Compile regex patterns and reject invalid ones. |
75 | | -
|
76 | | - Per-rule ``case_sensitive`` overrides the global flag when set. |
77 | | -
|
78 | | - Raises: |
79 | | - ValueError: If any rule contains an invalid regex pattern. |
80 | | -
|
81 | | - Returns: |
82 | | - The validated configuration instance. |
83 | | - """ |
84 | | - global_case_sensitive = self.case_sensitive |
85 | | - compiled: CompiledPatterns = [] |
86 | | - for rule in self.rules: |
87 | | - effective = ( |
88 | | - rule.case_sensitive |
89 | | - if rule.case_sensitive is not None |
90 | | - else global_case_sensitive |
91 | | - ) |
92 | | - flags = 0 if effective else re.IGNORECASE |
93 | | - try: |
94 | | - pattern = re.compile(rule.pattern, flags) |
95 | | - except re.error as e: |
96 | | - raise ValueError(f"Invalid regex pattern: {rule.pattern}: {e}") from e |
97 | | - compiled.append((pattern, rule.replacement)) |
98 | | - self._compiled_patterns = compiled |
99 | | - return self |
100 | | - |
101 | | - @property |
102 | | - def compiled_patterns(self) -> CompiledPatterns: |
103 | | - """Pre-compiled (regex, replacement) pairs. |
104 | | -
|
105 | | - Returns a shallow copy to prevent mutation of internal state. |
106 | | - """ |
107 | | - return list(self._compiled_patterns) |
| 12 | +__all__ = ["RedactionConfig", "RedactionRule"] |
0 commit comments