Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/policy_engine/condition_evaluator.py: 82%

30 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 12:01 +0000

1""" 

2Condition Evaluator - Evaluates policy conditions. 

3 

4Supports model-based conditions with exact match or regex patterns. 

5""" 

6 

7import re 

8 

9from litellm._logging import verbose_proxy_logger 

10from litellm.types.proxy.policy_engine import ( 

11 PolicyCondition, 

12 PolicyMatchContext, 

13) 

14 

15 

16class ConditionEvaluator: 

17 """ 

18 Evaluates policy conditions against request context. 

19 

20 Supports model conditions with: 

21 - Exact string match: "gpt-4" 

22 - Regex pattern: "gpt-4.*" 

23 - List of values: ["gpt-4", "gpt-4-turbo"] 

24 """ 

25 

26 @staticmethod 

27 def evaluate( 

28 condition: PolicyCondition | None, 

29 context: PolicyMatchContext, 

30 ) -> bool: 

31 """ 

32 Evaluate a policy condition against a request context. 

33 

34 Args: 

35 condition: The condition to evaluate (None = always matches) 

36 context: The request context with team, key, model 

37 

38 Returns: 

39 True if condition matches, False otherwise 

40 """ 

41 # No condition means always matches 

42 if condition is None: 42 ↛ 43line 42 didn't jump to line 43 because the condition on line 42 was never true

43 return True 

44 

45 # Check model condition 

46 if condition.model is not None: 

47 if not ConditionEvaluator._evaluate_model_condition( 

48 condition=condition.model, 

49 model=context.model, 

50 ): 

51 verbose_proxy_logger.debug( 

52 "Condition failed: model=%s did not match %s", context.model, condition.model 

53 ) 

54 return False 

55 

56 return True 

57 

58 @staticmethod 

59 def _evaluate_model_condition( 

60 condition: str | list[str], 

61 model: str | None, 

62 ) -> bool: 

63 """ 

64 Evaluate a model condition. 

65 

66 Args: 

67 condition: String (exact or regex) or list of strings 

68 model: The model name to check 

69 

70 Returns: 

71 True if model matches condition, False otherwise 

72 """ 

73 if model is None: 

74 return False 

75 

76 # Handle list of values 

77 if isinstance(condition, list): 77 ↛ 78line 77 didn't jump to line 78 because the condition on line 77 was never true

78 return any(ConditionEvaluator._matches_pattern(pattern, model) for pattern in condition) 

79 

80 # Single value - check as pattern 

81 return ConditionEvaluator._matches_pattern(condition, model) 

82 

83 @staticmethod 

84 def _matches_pattern(pattern: str, value: str) -> bool: 

85 """ 

86 Check if value matches pattern (exact match or regex). 

87 

88 Args: 

89 pattern: Pattern to match (exact string or regex) 

90 value: Value to check 

91 

92 Returns: 

93 True if matches, False otherwise 

94 """ 

95 # First try exact match 

96 if pattern == value: 

97 return True 

98 

99 # Try as regex pattern 

100 try: 

101 if re.fullmatch(pattern, value): 101 ↛ 102line 101 didn't jump to line 102 because the condition on line 101 was never true

102 return True 

103 except re.error: 

104 # Invalid regex, treat as literal string (already checked above) 

105 pass 

106 

107 return False