Coverage for presidio_analyzer / input_validation / schemas.py: 100%
63 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-29 09:03 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-29 09:03 +0000
1from pathlib import Path
2from typing import Any, Dict, List, Union
4from pydantic import ValidationError
6from . import validate_language_codes
7from .yaml_recognizer_models import RecognizerRegistryConfig
10class ConfigurationValidator:
11 """Class for validating configurations using Pydantic-enabled classes."""
13 @staticmethod
14 def validate_language_codes(languages: List[str]) -> List[str]:
15 """Validate language codes format.
17 :param languages: List of languages to validate.
18 """
19 validate_language_codes(languages)
20 return languages
22 @staticmethod
23 def validate_file_path(file_path: Union[str, Path]) -> Path:
24 """Validate file path exists and is readable.
26 :param file_path: Path to validate.
27 """
28 path = Path(file_path)
29 if not path.exists():
30 raise ValueError(f"Configuration file does not exist: {path}")
31 if not path.is_file():
32 raise ValueError(f"Path is not a file: {path}")
33 return path
35 @staticmethod
36 def validate_score_threshold(threshold: float) -> float:
37 """Validate score threshold is within valid range.
39 :param threshold: score threshold to validate.
40 """
41 if not 0.0 <= threshold <= 1.0:
42 raise ValueError(
43 f"Score threshold must be between 0.0 and 1.0, got: {threshold}"
44 )
45 return threshold
47 @staticmethod
48 def validate_nlp_configuration(config: Dict[str, Any]) -> Dict[str, Any]:
49 """Validate NLP configuration structure.
51 :param config: NLP Configuration to validate.
52 """
53 if not isinstance(config, dict):
54 raise ValueError("NLP configuration must be a dictionary")
56 required_fields = ["nlp_engine_name", "models"]
57 missing_fields = [field for field in required_fields if field not in config]
58 if missing_fields:
59 raise ValueError(
60 f"NLP configuration missing required fields: {missing_fields}"
61 )
63 # Validate models structure
64 if not isinstance(config["models"], list) or not config["models"]:
65 raise ValueError("Models must be a non-empty list")
67 for model in config["models"]:
68 if not isinstance(model, dict):
69 raise ValueError("Each model must be a dictionary")
70 if "lang_code" not in model or "model_name" not in model:
71 raise ValueError("Each model must have 'lang_code' and 'model_name'")
73 return config
75 @staticmethod
76 def validate_recognizer_registry_configuration(
77 config: Dict[str, Any],
78 ) -> Dict[str, Any]:
79 """Validate recognizer registry configuration using Pydantic models."""
80 try:
81 # Use Pydantic model for validation
82 validated_config = RecognizerRegistryConfig(**config)
83 # Use model_dump() without exclude_unset to include default values
84 return validated_config.model_dump(exclude_unset=False)
85 except ValidationError as e:
86 raise ValueError("Invalid recognizer registry configuration") from e
88 @staticmethod
89 def validate_analyzer_configuration(config: Dict[str, Any]) -> Dict[str, Any]:
90 """Validate analyzer engine configuration."""
91 if not isinstance(config, dict):
92 raise ValueError("Analyzer configuration must be a dictionary")
94 # Define valid top-level keys for analyzer configuration
95 valid_keys = {
96 "supported_languages",
97 "default_score_threshold",
98 "nlp_configuration",
99 "recognizer_registry",
100 }
102 # Check for unknown keys
103 unknown_keys = set(config.keys()) - valid_keys
104 if unknown_keys:
105 raise ValueError(
106 f"Unknown configuration key(s) in "
107 f"analyzer configuration: {sorted(unknown_keys)}. "
108 f"Valid keys are: {sorted(valid_keys)}"
109 )
111 # Validate supported languages if present
112 if "supported_languages" in config:
113 validate_language_codes(config["supported_languages"])
115 # Validate score threshold if present
116 if "default_score_threshold" in config:
117 ConfigurationValidator.validate_score_threshold(
118 config["default_score_threshold"]
119 )
121 # Validate nested configurations
122 if "nlp_configuration" in config:
123 ConfigurationValidator.validate_nlp_configuration(
124 config["nlp_configuration"]
125 )
127 if "recognizer_registry" in config:
128 ConfigurationValidator.validate_recognizer_registry_configuration(
129 config["recognizer_registry"]
130 )
132 return config