0
# Validation System
1
2
Comprehensive validation framework with required field checking, type validation, range constraints, custom conditions, and combinatorial validators for ensuring configuration integrity. The validation system helps maintain data quality and provides clear error reporting.
3
4
## Capabilities
5
6
### Validator Creation
7
8
Create validation rules for configuration values.
9
10
```python { .api }
11
class Validator:
12
"""Validation rule for configuration values."""
13
def __init__(
14
self,
15
*names, # Variable names or patterns to validate
16
must_exist=False, # Require the value to exist
17
required=None, # Alias for must_exist
18
condition=None, # Custom validation function
19
when=None, # Conditional validator
20
env=None, # Environment(s) to validate in
21
messages=None, # Custom error messages
22
cast=None, # Type casting function
23
default=None, # Default value or callable
24
description=None, # Description string
25
apply_default_on_none=False, # Apply default when value is None
26
# Validation operations
27
eq=None, # Equal to
28
ne=None, # Not equal to
29
gt=None, # Greater than
30
lt=None, # Less than
31
gte=None, # Greater than or equal
32
lte=None, # Less than or equal
33
is_type_of=None, # Type validation
34
is_in=None, # Value in list/set
35
is_not_in=None, # Value not in list/set
36
identity=None, # Identity check (is)
37
cont=None, # Contains substring/element
38
len_eq=None, # Length equal
39
len_ne=None, # Length not equal
40
len_min=None, # Minimum length
41
len_max=None, # Maximum length
42
**kwargs
43
): ...
44
```
45
46
Usage examples:
47
48
```python
49
from dynaconf import Validator
50
51
# Basic required field
52
Validator("DATABASE_URL", must_exist=True)
53
54
# Type validation with default
55
Validator("DEBUG", default=False, is_type_of=bool)
56
57
# Range validation
58
Validator("PORT", default=8000, gte=1000, lte=9999)
59
60
# Multiple conditions
61
Validator("LOG_LEVEL", is_in=["DEBUG", "INFO", "WARNING", "ERROR"])
62
63
# Custom validation function
64
Validator("EMAIL", condition=lambda x: "@" in x, must_exist=True)
65
```
66
67
### Validation Execution
68
69
Run validation rules against settings.
70
71
```python { .api }
72
def validate(
73
self,
74
settings, # Settings instance to validate
75
only=None, # Validate only specific validators
76
exclude=None, # Exclude specific validators
77
only_current_env=False # Validate only current environment
78
):
79
"""
80
Run validation against settings.
81
82
Raises:
83
ValidationError: If validation fails
84
"""
85
...
86
```
87
88
### Validator Combination
89
90
Combine validators with logical operations.
91
92
```python { .api }
93
def __or__(self, other):
94
"""OR operation - either validator can pass."""
95
...
96
97
def __and__(self, other):
98
"""AND operation - both validators must pass."""
99
...
100
```
101
102
Usage examples:
103
104
```python
105
# OR combination - either condition passes
106
email_or_phone = (
107
Validator("EMAIL", condition=lambda x: "@" in x) |
108
Validator("PHONE", condition=lambda x: x.isdigit())
109
)
110
111
# AND combination - both conditions must pass
112
secure_password = (
113
Validator("PASSWORD", len_min=8) &
114
Validator("PASSWORD", condition=lambda x: any(c.isupper() for c in x))
115
)
116
```
117
118
### Validation Errors
119
120
Handle validation failures with detailed error information.
121
122
```python { .api }
123
class ValidationError(Exception):
124
"""Exception raised when validation fails."""
125
def __init__(self, message: str, details=None): ...
126
127
@property
128
def message(self) -> str:
129
"""Error message."""
130
...
131
132
@property
133
def details(self) -> list:
134
"""List of detailed error information."""
135
...
136
```
137
138
### Validator Management
139
140
Manage collections of validators.
141
142
```python { .api }
143
class ValidatorList:
144
"""Container for managing multiple validators."""
145
def __init__(self, settings=None, validators=None): ...
146
147
def register(self, *args, **kwargs):
148
"""Register new validators."""
149
...
150
151
def validate(
152
self,
153
only=None, # Validate only specific validators
154
exclude=None, # Exclude specific validators
155
only_current_env=False # Validate only current environment
156
):
157
"""
158
Run all validators.
159
160
Raises:
161
ValidationError: If any validation fails
162
"""
163
...
164
165
def validate_all(
166
self,
167
only=None,
168
exclude=None,
169
only_current_env=False
170
) -> list:
171
"""
172
Run all validators and collect all errors.
173
174
Returns:
175
list: List of validation errors (empty if all pass)
176
"""
177
...
178
179
def descriptions(self, flat=False) -> dict:
180
"""Get validator descriptions."""
181
...
182
```
183
184
### Combined Validators
185
186
Specialized validator classes for logical combinations.
187
188
```python { .api }
189
class OrValidator:
190
"""At least one of the validators must pass."""
191
def __init__(self, *validators): ...
192
193
def validate(self, settings, only=None, exclude=None, only_current_env=False): ...
194
195
class AndValidator:
196
"""All validators must pass."""
197
def __init__(self, *validators): ...
198
199
def validate(self, settings, only=None, exclude=None, only_current_env=False): ...
200
```
201
202
## Advanced Validation Patterns
203
204
### Conditional Validation
205
206
Validate values only when certain conditions are met.
207
208
```python
209
# Validate SSL settings only when HTTPS is enabled
210
Validator(
211
"SSL_CERTIFICATE",
212
must_exist=True,
213
when=Validator("USE_HTTPS", eq=True)
214
)
215
216
# Environment-specific validation
217
Validator("DEBUG", eq=False, env="production")
218
```
219
220
### Custom Validation Functions
221
222
Create complex validation logic with custom functions.
223
224
```python
225
def validate_database_url(url):
226
"""Custom database URL validation."""
227
return url.startswith(("postgresql://", "mysql://", "sqlite:///"))
228
229
def validate_email_list(emails):
230
"""Validate list of email addresses."""
231
if not isinstance(emails, list):
232
return False
233
return all("@" in email for email in emails)
234
235
# Use custom validators
236
Validator("DATABASE_URL", condition=validate_database_url)
237
Validator("ADMIN_EMAILS", condition=validate_email_list)
238
```
239
240
### Validation with Type Casting
241
242
Combine validation with automatic type conversion.
243
244
```python
245
# Cast to integer and validate range
246
Validator("WORKER_COUNT", cast=int, gte=1, lte=10, default=4)
247
248
# Cast to boolean with validation
249
Validator("ENABLE_CACHE", cast=bool, default=True)
250
251
# Cast to list and validate contents
252
Validator("ALLOWED_HOSTS", cast=list, len_min=1)
253
```
254
255
### Error Messages and Descriptions
256
257
Provide clear error messages and documentation.
258
259
```python
260
Validator(
261
"API_KEY",
262
must_exist=True,
263
messages={
264
"must_exist_true": "API key is required for external service access"
265
},
266
description="Authentication key for third-party API integration"
267
)
268
```
269
270
## Complete Validation Examples
271
272
### Web Application Validation
273
274
```python
275
from dynaconf import Dynaconf, Validator
276
277
settings = Dynaconf(
278
validators=[
279
# Database configuration
280
Validator("DATABASE_URL", must_exist=True),
281
Validator("DB_POOL_SIZE", cast=int, gte=1, lte=100, default=10),
282
283
# Security settings
284
Validator("SECRET_KEY", must_exist=True, len_min=32),
285
Validator("DEBUG", cast=bool, default=False),
286
Validator("ALLOWED_HOSTS", cast=list, len_min=1),
287
288
# External services
289
Validator("REDIS_URL", condition=lambda x: x.startswith("redis://")),
290
Validator("EMAIL_BACKEND", is_in=["smtp", "sendgrid", "ses"]),
291
292
# Environment-specific
293
Validator("DEBUG", eq=False, env="production"),
294
Validator("SSL_REQUIRED", eq=True, env="production"),
295
]
296
)
297
298
# Validate all settings
299
try:
300
settings.validators.validate()
301
print("All settings are valid!")
302
except ValidationError as e:
303
print(f"Validation failed: {e.message}")
304
for detail in e.details:
305
print(f" - {detail}")
306
```
307
308
### API Service Validation
309
310
```python
311
validators = [
312
# Server configuration
313
Validator("HOST", default="localhost"),
314
Validator("PORT", cast=int, gte=1000, lte=65535, default=8000),
315
Validator("WORKERS", cast=int, gte=1, lte=20, default=4),
316
317
# API configuration
318
Validator("API_VERSION", is_in=["v1", "v2", "v3"], default="v2"),
319
Validator("RATE_LIMIT", cast=int, gte=10, lte=10000, default=1000),
320
321
# Authentication
322
Validator("JWT_SECRET", must_exist=True, len_min=64),
323
Validator("TOKEN_EXPIRY", cast=int, gte=300, lte=86400, default=3600),
324
325
# Monitoring
326
Validator("METRICS_ENABLED", cast=bool, default=True),
327
Validator("LOG_LEVEL", is_in=["DEBUG", "INFO", "WARNING", "ERROR"], default="INFO"),
328
]
329
330
settings = Dynaconf(validators=validators)
331
```