0
# Schema Management
1
2
Schema creation, include management, and validation result handling for building complex validation structures. This module provides the core classes for managing YAML schemas and processing validation results.
3
4
## Capabilities
5
6
### Schema Class
7
8
Main schema representation that processes YAML schema definitions and validates data against defined rules.
9
10
```python { .api }
11
class Schema:
12
"""
13
Schema object that represents a YAML validation schema.
14
"""
15
16
def __init__(self, schema_dict, name="", validators=None, includes=None):
17
"""
18
Create a Schema object from a schema dictionary.
19
20
Parameters:
21
- schema_dict (dict): Dictionary representing the schema structure
22
- name (str): Optional name for the schema
23
- validators (dict, optional): Validator dictionary, defaults to DefaultValidators
24
- includes (dict, optional): Existing includes dictionary for shared includes
25
26
Attributes:
27
- validators: Dictionary of available validators
28
- dict: Original schema dictionary
29
- name: Schema name
30
- includes: Dictionary of included sub-schemas
31
"""
32
33
def add_include(self, type_dict):
34
"""
35
Add include definitions to the schema.
36
37
Parameters:
38
- type_dict (dict): Dictionary of include names to schema definitions
39
"""
40
41
def validate(self, data, data_name, strict):
42
"""
43
Validate data against this schema.
44
45
Parameters:
46
- data: Data to validate
47
- data_name (str): Name/path for error reporting
48
- strict (bool): Enable strict validation mode
49
50
Returns:
51
ValidationResult: Result of validation with errors if any
52
"""
53
54
# Schema attributes
55
validators: dict # Available validators dictionary
56
dict: dict # Original schema dictionary
57
name: str # Schema name
58
includes: dict # Dictionary of included sub-schemas
59
60
61
class FatalValidationError(Exception):
62
"""
63
Exception raised for fatal validation errors during schema processing.
64
"""
65
66
def __init__(self, error):
67
"""
68
Initialize with error message.
69
70
Parameters:
71
- error (str): Error message
72
73
Attributes:
74
- error: Error message string
75
"""
76
77
error: str # Error message
78
```
79
80
Usage examples:
81
82
```python
83
# Create schema from dictionary
84
schema_dict = {
85
'name': 'str()',
86
'age': 'int(min=0)',
87
'emails': 'list(str())'
88
}
89
schema = yamale.schema.Schema(schema_dict)
90
91
# Add external includes after creation
92
includes = {
93
'address': {
94
'street': 'str()',
95
'city': 'str()',
96
'zip': 'str()'
97
}
98
}
99
schema.add_include(includes)
100
101
# Validate data
102
data = {'name': 'John', 'age': 30, 'emails': ['john@example.com']}
103
result = schema.validate(data, 'test.yaml', strict=True)
104
```
105
106
### Validation Results
107
108
Classes that represent the outcome of validation operations with detailed error information.
109
110
```python { .api }
111
class ValidationResult(Result):
112
"""
113
Contains the result of validating data against a schema.
114
Inherits from Result class.
115
"""
116
117
def __init__(self, data, schema, errors):
118
"""
119
Initialize validation result.
120
121
Parameters:
122
- data (str): Path or identifier of validated data
123
- schema (str): Path or identifier of schema used
124
- errors (list): List of validation error messages
125
126
Attributes:
127
- data: Data identifier that was validated
128
- schema: Schema identifier used for validation
129
- errors: List of error messages
130
"""
131
132
def isValid(self):
133
"""
134
Check if validation passed.
135
136
Returns:
137
bool: True if no errors, False otherwise
138
"""
139
140
def __str__(self):
141
"""
142
Get human-readable representation of validation result.
143
144
Returns:
145
str: Formatted validation result message
146
"""
147
148
149
class Result:
150
"""
151
Base result class for validation operations.
152
"""
153
154
def __init__(self, errors):
155
"""
156
Initialize result with error list.
157
158
Parameters:
159
- errors (list): List of error messages
160
161
Attributes:
162
- errors: List of error messages
163
"""
164
165
def isValid(self):
166
"""
167
Check if result represents success.
168
169
Returns:
170
bool: True if no errors, False otherwise
171
"""
172
173
def __str__(self):
174
"""
175
Get string representation of errors.
176
177
Returns:
178
str: Newline-separated error messages
179
"""
180
```
181
182
Usage examples:
183
184
```python
185
# Check validation results
186
results = yamale.validate(schema, data, _raise_error=False)
187
for result in results:
188
if result.isValid():
189
print(f"✓ {result.data} is valid")
190
else:
191
print(f"✗ {result.data} failed validation:")
192
for error in result.errors:
193
print(f" - {error}")
194
195
# Access result attributes
196
result = results[0]
197
print(f"Data: {result.data}")
198
print(f"Schema: {result.schema}")
199
print(f"Error count: {len(result.errors)}")
200
print(f"Valid: {result.isValid()}")
201
```
202
203
### Schema Includes System
204
205
Yamale supports a powerful includes system for schema composition and reuse.
206
207
#### Basic Includes
208
209
Define reusable schema components in separate YAML documents:
210
211
```yaml
212
# Main schema document
213
user: include('person')
214
admin: include('person')
215
216
---
217
# Include definitions
218
person:
219
name: str()
220
age: int(min=0)
221
email: str()
222
```
223
224
#### Recursive Includes
225
226
Create self-referencing schemas for tree structures:
227
228
```yaml
229
directory: include('folder')
230
231
---
232
folder:
233
name: str()
234
files: list(str(), required=False)
235
subdirs: list(include('folder'), required=False)
236
```
237
238
#### Programmatic Include Management
239
240
```python
241
# Create base schema
242
schema = yamale.make_schema('./base-schema.yaml')
243
244
# Add external includes dynamically
245
external_includes = {
246
'address': {
247
'street': 'str()',
248
'city': 'str()',
249
'country': 'str(equals="US")'
250
},
251
'contact': {
252
'phone': 'str()',
253
'email': 'str()',
254
'address': 'include("address")'
255
}
256
}
257
258
schema.add_include(external_includes)
259
260
# Now schema can use include('address') and include('contact')
261
```
262
263
#### Include with Strict Mode Control
264
265
Control strict validation per include:
266
267
```yaml
268
user_data: include('user', strict=False) # Allow extra fields in user data
269
system_config: include('config') # Use default strict mode
270
271
---
272
user:
273
name: str()
274
preferences: map() # Flexible user preferences
275
276
config:
277
debug: bool()
278
timeout: int()
279
```
280
281
### Advanced Schema Patterns
282
283
#### Multi-document Schemas
284
285
```python
286
# Schema with multiple include documents
287
schema_content = """
288
api_request: include('request')
289
api_response: include('response')
290
291
---
292
request:
293
method: str()
294
url: str()
295
headers: map(str(), required=False)
296
297
---
298
response:
299
status: int()
300
body: any()
301
headers: map(str(), required=False)
302
"""
303
304
schema = yamale.make_schema(content=schema_content)
305
```
306
307
#### Custom Validator Integration
308
309
```python
310
# Create custom validator
311
class EmailValidator(yamale.validators.Validator):
312
tag = 'email'
313
314
def _is_valid(self, value):
315
return '@' in str(value) and '.' in str(value)
316
317
# Create custom validator set
318
custom_validators = yamale.validators.DefaultValidators.copy()
319
custom_validators['email'] = EmailValidator
320
321
# Use in schema
322
schema = yamale.make_schema(
323
content="contact_email: email()",
324
validators=custom_validators
325
)
326
```
327
328
## Error Handling
329
330
Schema operations may raise several types of exceptions:
331
332
- **SyntaxError**: Invalid schema syntax or validator expressions
333
- **ValueError**: Invalid include references or empty schemas
334
- **TypeError**: Invalid schema dictionary structure
335
- **KeyError**: Missing required validator or include definitions
336
337
Always handle these exceptions when working with dynamic schema creation:
338
339
```python
340
try:
341
schema = yamale.make_schema('./schema.yaml')
342
results = yamale.validate(schema, data)
343
except (SyntaxError, ValueError) as e:
344
print(f"Schema error: {e}")
345
except yamale.YamaleError as e:
346
print(f"Validation error: {e}")
347
```