0
# Schema Rules
1
2
The Rule class provides schema rule definition and management, serving as the building blocks for creating complex validation schemas with type constraints, length validation, pattern matching, and custom validation functions.
3
4
## Capabilities
5
6
### Rule Class Initialization
7
8
Creates a Rule instance representing a schema validation rule.
9
10
```python { .api }
11
class Rule:
12
def __init__(self, schema=None, parent=None, strict_rule_validation=False):
13
"""
14
Initialize a Rule instance.
15
16
Args:
17
schema (dict, optional): Schema definition dictionary
18
parent (Rule, optional): Parent rule for nested rules
19
strict_rule_validation (bool): Enable strict validation of rule keywords
20
"""
21
```
22
23
### Rule Initialization and Management
24
25
```python { .api }
26
def init(self, schema, path):
27
"""
28
Initialize rule from schema definition.
29
30
Args:
31
schema (dict): Schema definition
32
path (str): Path context for error reporting
33
"""
34
35
def keywords(self):
36
"""
37
Get list of supported keywords for this rule type.
38
39
Returns:
40
list: List of supported keyword strings
41
"""
42
43
def check_type_keywords(self, schema, rule, path):
44
"""
45
Check that keywords are valid for the rule type.
46
47
Args:
48
schema (dict): Schema definition
49
rule (Rule): Rule instance
50
path (str): Path context
51
"""
52
53
def check_conflicts(self, schema, rule, path):
54
"""
55
Check for conflicting rule definitions.
56
57
Args:
58
schema (dict): Schema definition
59
rule (Rule): Rule instance
60
path (str): Path context
61
"""
62
```
63
64
## Rule Properties
65
66
All rule properties support both getting and setting values:
67
68
### Core Properties
69
70
```python { .api }
71
@property
72
def type(self):
73
"""The data type this rule validates (str, int, float, map, seq, etc.)"""
74
75
@property
76
def required(self):
77
"""Whether this field is required (bool)"""
78
79
@property
80
def nullable(self):
81
"""Whether null/None values are allowed (bool)"""
82
83
@property
84
def default(self):
85
"""Default value if field is missing"""
86
87
@property
88
def desc(self):
89
"""Description of this rule (str)"""
90
91
@property
92
def example(self):
93
"""Example value for this rule"""
94
```
95
96
### Validation Constraints
97
98
```python { .api }
99
@property
100
def range(self):
101
"""Range constraints for numeric values (dict with min/max keys)"""
102
103
@property
104
def length(self):
105
"""Length constraints for strings/collections (dict with min/max keys)"""
106
107
@property
108
def pattern(self):
109
"""Regular expression pattern for string validation (str)"""
110
111
@property
112
def enum(self):
113
"""List of allowed values (list)"""
114
115
@property
116
def unique(self):
117
"""Whether sequence values must be unique (bool)"""
118
```
119
120
### Collection Rules
121
122
```python { .api }
123
@property
124
def sequence(self):
125
"""Rules for sequence (list) validation (list of Rule objects)"""
126
127
@property
128
def mapping(self):
129
"""Rules for mapping (dict) validation (dict of Rule objects)"""
130
131
@property
132
def allowempty_map(self):
133
"""Whether empty mappings are allowed (bool)"""
134
```
135
136
### Advanced Features
137
138
```python { .api }
139
@property
140
def func(self):
141
"""Custom validation function name (str)"""
142
143
@property
144
def assertion(self):
145
"""Assertion expression for custom validation (str)"""
146
147
@property
148
def include_name(self):
149
"""Name of partial schema to include (str)"""
150
151
@property
152
def matching(self):
153
"""Matching pattern for flexible validation (str)"""
154
155
@property
156
def matching_rule(self):
157
"""Rule to apply for matching validation (Rule)"""
158
159
@property
160
def extensions(self):
161
"""List of extension files (list)"""
162
163
@property
164
def format(self):
165
"""Format specification for validation (str)"""
166
167
@property
168
def version(self):
169
"""Schema version specification"""
170
```
171
172
### Internal Properties
173
174
```python { .api }
175
@property
176
def parent(self):
177
"""Parent rule for nested rules (Rule)"""
178
179
@property
180
def schema(self):
181
"""Original schema definition (dict)"""
182
183
@property
184
def schema_str(self):
185
"""String representation of schema (str)"""
186
187
@property
188
def name(self):
189
"""Rule name identifier (str)"""
190
191
@property
192
def ident(self):
193
"""Rule identifier (int)"""
194
195
@property
196
def pattern_regexp(self):
197
"""Compiled regular expression pattern"""
198
199
@property
200
def type_class(self):
201
"""Python class for the rule type"""
202
203
@property
204
def map_regex_rule(self):
205
"""Regex rule for mapping validation"""
206
207
@property
208
def regex_mappings(self):
209
"""Regex mapping rules (dict)"""
210
```
211
212
## Usage Examples
213
214
### Basic Rule Creation
215
216
```python
217
from pykwalify.rule import Rule
218
219
# Create a simple string rule
220
schema_def = {
221
"type": "str",
222
"required": True,
223
"desc": "User name"
224
}
225
226
rule = Rule()
227
rule.init(schema_def, "/name")
228
229
print(f"Rule type: {rule.type}")
230
print(f"Required: {rule.required}")
231
print(f"Description: {rule.desc}")
232
```
233
234
### Complex Validation Rules
235
236
```python
237
from pykwalify.rule import Rule
238
239
# Numeric range validation
240
number_schema = {
241
"type": "int",
242
"range": {"min": 1, "max": 100},
243
"desc": "Age in years"
244
}
245
246
age_rule = Rule()
247
age_rule.init(number_schema, "/age")
248
249
# String pattern validation
250
email_schema = {
251
"type": "str",
252
"pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
253
"desc": "Email address"
254
}
255
256
email_rule = Rule()
257
email_rule.init(email_schema, "/email")
258
259
# Enumeration validation
260
status_schema = {
261
"type": "str",
262
"enum": ["active", "inactive", "pending"],
263
"default": "pending"
264
}
265
266
status_rule = Rule()
267
status_rule.init(status_schema, "/status")
268
```
269
270
### Sequence (List) Rules
271
272
```python
273
from pykwalify.rule import Rule
274
275
# List of strings with length constraints
276
tags_schema = {
277
"type": "seq",
278
"sequence": [
279
{
280
"type": "str",
281
"length": {"min": 1, "max": 50}
282
}
283
],
284
"length": {"min": 1, "max": 10}
285
}
286
287
tags_rule = Rule()
288
tags_rule.init(tags_schema, "/tags")
289
290
# List with unique values
291
ids_schema = {
292
"type": "seq",
293
"sequence": [{"type": "int"}],
294
"unique": True
295
}
296
297
ids_rule = Rule()
298
ids_rule.init(ids_schema, "/ids")
299
```
300
301
### Mapping (Dictionary) Rules
302
303
```python
304
from pykwalify.rule import Rule
305
306
# Complex nested mapping
307
user_schema = {
308
"type": "map",
309
"mapping": {
310
"name": {
311
"type": "str",
312
"required": True,
313
"length": {"min": 1, "max": 100}
314
},
315
"age": {
316
"type": "int",
317
"range": {"min": 0, "max": 120}
318
},
319
"email": {
320
"type": "str",
321
"format": "email"
322
},
323
"addresses": {
324
"type": "seq",
325
"sequence": [{
326
"type": "map",
327
"mapping": {
328
"street": {"type": "str", "required": True},
329
"city": {"type": "str", "required": True},
330
"zipcode": {"type": "str", "pattern": r"^\d{5}(-\d{4})?$"}
331
}
332
}]
333
}
334
}
335
}
336
337
user_rule = Rule()
338
user_rule.init(user_schema, "/user")
339
```
340
341
### Custom Validation Functions
342
343
```python
344
from pykwalify.rule import Rule
345
346
# Using custom validation function
347
custom_schema = {
348
"type": "str",
349
"func": "validate_custom_format",
350
"desc": "Custom validated field"
351
}
352
353
custom_rule = Rule()
354
custom_rule.init(custom_schema, "/custom_field")
355
356
print(f"Custom function: {custom_rule.func}")
357
```
358
359
### Rule Property Access and Modification
360
361
```python
362
from pykwalify.rule import Rule
363
364
# Create rule and modify properties
365
rule = Rule()
366
rule.type = "str"
367
rule.required = True
368
rule.length = {"min": 3, "max": 50}
369
rule.pattern = r"^[a-zA-Z]+$"
370
rule.desc = "Alphabetic string"
371
372
# Access computed properties
373
print(f"Type class: {rule.type_class}")
374
print(f"Keywords: {rule.keywords()}")
375
376
# Check if pattern was compiled
377
if rule.pattern_regexp:
378
print("Pattern successfully compiled")
379
```
380
381
### Partial Schema Inclusion
382
383
```python
384
from pykwalify.rule import Rule
385
import pykwalify
386
387
# Set up partial schema
388
pykwalify.partial_schemas["address"] = {
389
"type": "map",
390
"mapping": {
391
"street": {"type": "str", "required": True},
392
"city": {"type": "str", "required": True},
393
"zipcode": {"type": "str"}
394
}
395
}
396
397
# Use partial schema in rule
398
schema_with_include = {
399
"type": "map",
400
"mapping": {
401
"name": {"type": "str"},
402
"home_address": {"include": "address"},
403
"work_address": {"include": "address"}
404
}
405
}
406
407
rule = Rule()
408
rule.init(schema_with_include, "/person")
409
```
410
411
## Rule Validation Keywords
412
413
### Type Keywords
414
415
Supported type values:
416
- `str` - String values
417
- `int` - Integer values
418
- `float` - Floating point values
419
- `bool` - Boolean values
420
- `map` - Dictionary/mapping values
421
- `seq` - List/sequence values
422
- `any` - Any value type
423
- `text` - String or numeric values
424
- `number` - Integer or float values
425
- `scalar` - Any non-collection value
426
- `timestamp` - Timestamp values
427
- `date` - Date values
428
- `email` - Email format strings
429
- `url` - URL format strings
430
431
### Constraint Keywords
432
433
Available constraint keywords by type:
434
- **All types**: `required`, `nullable`, `default`, `desc`, `example`
435
- **Strings**: `length`, `pattern`, `enum`, `format`
436
- **Numbers**: `range`, `enum`
437
- **Collections**: `length`, `unique` (sequences only)
438
- **Mappings**: `mapping`, `allowempty_map`
439
- **Sequences**: `sequence`, `unique`
440
- **Advanced**: `func`, `assertion`, `include`, `matching`, `extensions`