core.py
1 import abc 2 from typing import Dict 3 from typing import List 4 5 6 class GuardrailBase: 7 def __init__(self): 8 pass 9 10 def name(self) -> str: 11 return self.__class__.__name__ 12 13 @abc.abstractmethod 14 def validate(self, data: str): 15 """ 16 validate input to meet a criteria 17 Args: 18 data: input data to check against criteria 19 20 Returns: 21 None 22 Raises: 23 GuardException: raised if validation fails 24 """ 25 raise NotImplementedError() 26 27 28 class GuardException(Exception): 29 guard: GuardrailBase 30 31 def __init__(self, guard: GuardrailBase, message: str = "") -> None: 32 self.guard = guard 33 self.message = message 34 35 def __str__(self): 36 return f"Guard {self.guard.name()} validation failed: {self.message}" 37 38 39 class AggregationGuardrail(GuardrailBase): 40 def validate(self, data: str): 41 pass 42 43 def name(self) -> str: 44 return "Aggregation" 45 46 47 class GuardsException(GuardException): 48 guard = AggregationGuardrail() 49 failed_guards: Dict[GuardrailBase, GuardException] 50 51 def __init__(self, failed_guards: Dict[GuardrailBase, GuardException]): 52 self.failed_guards = failed_guards 53 54 def __str__(self): 55 return f"Multiple guards validation failed: {', '.join([g.name() for g in self.failed_guards.keys()])}." 56 57 58 def validate_guards(data: str, guards: List[GuardrailBase]): 59 failed = {} 60 for guard in guards: 61 try: 62 guard.validate(data) 63 except GuardException as e: 64 failed[e.guard] = e 65 if len(failed) > 0: 66 raise GuardsException(failed)