0
# System and Time Validation
1
2
Validators for system-related formats including cron expressions and time-based scheduling patterns. These validators ensure proper syntax and valid ranges for system configuration and scheduling tasks.
3
4
## Capabilities
5
6
### Cron Expression Validation
7
8
Validates cron expression strings used for scheduling tasks in Unix-like systems.
9
10
```python { .api }
11
def cron(value: str, /) -> Union[Literal[True], ValidationError]:
12
"""
13
Validate cron expression strings.
14
15
Parameters:
16
- value: Cron expression string to validate
17
18
Returns:
19
True if valid cron expression, ValidationError otherwise
20
21
Validates standard 5-field cron format:
22
- Minute (0-59)
23
- Hour (0-23)
24
- Day of month (1-31)
25
- Month (1-12)
26
- Day of week (0-7, where 0 and 7 are Sunday)
27
28
Supported special characters:
29
- * (any value)
30
- , (value list separator)
31
- - (range)
32
- / (step values)
33
34
Examples:
35
- "0 0 * * *" (daily at midnight)
36
- "0 9-17 * * 1-5" (hourly during business hours on weekdays)
37
- "*/15 * * * *" (every 15 minutes)
38
- "0 0 1 */3 *" (first day of every 3rd month)
39
"""
40
```
41
42
## Usage Examples
43
44
```python
45
import validators
46
47
# Basic cron expressions
48
validators.cron('0 0 * * *') # True (daily at midnight)
49
validators.cron('0 12 * * *') # True (daily at noon)
50
validators.cron('30 14 * * *') # True (daily at 2:30 PM)
51
52
# Hourly and minute patterns
53
validators.cron('0 * * * *') # True (every hour)
54
validators.cron('*/15 * * * *') # True (every 15 minutes)
55
validators.cron('0,30 * * * *') # True (twice per hour at :00 and :30)
56
57
# Weekly patterns
58
validators.cron('0 9 * * 1') # True (Mondays at 9 AM)
59
validators.cron('0 9 * * 1-5') # True (weekdays at 9 AM)
60
validators.cron('0 0 * * 0') # True (Sundays at midnight)
61
validators.cron('0 0 * * 7') # True (Sundays at midnight, alternative)
62
63
# Monthly patterns
64
validators.cron('0 0 1 * *') # True (first day of every month)
65
validators.cron('0 0 15 * *') # True (15th of every month)
66
validators.cron('0 0 * * 1') # True (every Monday)
67
68
# Complex patterns with ranges and steps
69
validators.cron('0 9-17 * * 1-5') # True (business hours on weekdays)
70
validators.cron('*/10 9-17 * * 1-5') # True (every 10 min during business hours)
71
validators.cron('0 0 1 */3 *') # True (quarterly on 1st day)
72
validators.cron('0 0 1 1,7 *') # True (January 1st and July 1st)
73
74
# Invalid cron expressions
75
validators.cron('60 0 * * *') # ValidationError (minute 60 invalid)
76
validators.cron('0 24 * * *') # ValidationError (hour 24 invalid)
77
validators.cron('0 0 32 * *') # ValidationError (day 32 invalid)
78
validators.cron('0 0 0 * *') # ValidationError (day 0 invalid)
79
validators.cron('0 0 * 13 *') # ValidationError (month 13 invalid)
80
validators.cron('0 0 * * 8') # ValidationError (day-of-week 8 invalid)
81
82
# Malformed expressions
83
validators.cron('0 0 * *') # ValidationError (missing field)
84
validators.cron('0 0 * * * *') # ValidationError (too many fields)
85
validators.cron('0 0 * * x') # ValidationError (invalid character)
86
```
87
88
## Advanced Usage
89
90
### Cron Expression Analysis
91
92
```python
93
import validators
94
95
def analyze_cron_expression(expression: str) -> dict:
96
"""Analyze and describe a cron expression."""
97
98
if not validators.cron(expression):
99
return {'valid': False, 'error': 'Invalid cron expression'}
100
101
fields = expression.split()
102
minute, hour, day, month, dow = fields
103
104
analysis = {
105
'valid': True,
106
'expression': expression,
107
'fields': {
108
'minute': minute,
109
'hour': hour,
110
'day_of_month': day,
111
'month': month,
112
'day_of_week': dow
113
}
114
}
115
116
# Basic frequency analysis
117
if minute == '*' and hour == '*':
118
analysis['frequency'] = 'Every minute'
119
elif hour == '*':
120
if '/' in minute:
121
step = minute.split('/')[1]
122
analysis['frequency'] = f'Every {step} minutes'
123
else:
124
analysis['frequency'] = 'Every hour'
125
elif day == '*' and month == '*' and dow == '*':
126
analysis['frequency'] = 'Daily'
127
elif dow != '*':
128
analysis['frequency'] = 'Weekly'
129
elif day != '*':
130
analysis['frequency'] = 'Monthly'
131
else:
132
analysis['frequency'] = 'Custom'
133
134
return analysis
135
136
# Usage examples
137
expressions = [
138
'0 0 * * *', # Daily
139
'*/15 * * * *', # Every 15 minutes
140
'0 9 * * 1-5', # Weekdays at 9 AM
141
'0 0 1 * *', # First of month
142
]
143
144
for expr in expressions:
145
result = analyze_cron_expression(expr)
146
print(f"{expr}: {result['frequency']}")
147
```
148
149
### Cron Schedule Validation
150
151
```python
152
import validators
153
from datetime import datetime, timedelta
154
155
def validate_cron_schedule(cron_expr: str, max_executions: int = 10) -> dict:
156
"""Validate cron expression and show next execution times."""
157
158
if not validators.cron(cron_expr):
159
return {'valid': False, 'error': 'Invalid cron expression'}
160
161
# This is a simplified example - real implementation would use a cron library
162
# like python-crontab or croniter for accurate next execution calculation
163
164
result = {
165
'valid': True,
166
'expression': cron_expr,
167
'analysis': analyze_cron_expression(cron_expr),
168
'note': 'Use croniter library for actual execution time calculation'
169
}
170
171
return result
172
173
# Usage
174
schedule = validate_cron_schedule('0 9 * * 1-5')
175
print(f"Schedule valid: {schedule['valid']}")
176
print(f"Frequency: {schedule['analysis']['frequency']}")
177
```
178
179
### Common Cron Patterns
180
181
```python
182
import validators
183
184
# Define common cron patterns with descriptions
185
COMMON_PATTERNS = {
186
# Basic time patterns
187
'0 0 * * *': 'Daily at midnight',
188
'0 12 * * *': 'Daily at noon',
189
'0 9 * * *': 'Daily at 9 AM',
190
'0 17 * * *': 'Daily at 5 PM',
191
192
# Frequent patterns
193
'*/5 * * * *': 'Every 5 minutes',
194
'*/15 * * * *': 'Every 15 minutes',
195
'*/30 * * * *': 'Every 30 minutes',
196
'0 * * * *': 'Every hour',
197
198
# Weekly patterns
199
'0 9 * * 1': 'Mondays at 9 AM',
200
'0 9 * * 1-5': 'Weekdays at 9 AM',
201
'0 0 * * 0': 'Sundays at midnight',
202
'0 0 * * 6': 'Saturdays at midnight',
203
204
# Monthly patterns
205
'0 0 1 * *': 'First day of every month',
206
'0 0 15 * *': '15th of every month',
207
'0 0 * * 1': 'Every Monday (weekly)',
208
209
# Business hour patterns
210
'0 9-17 * * 1-5': 'Every hour during business hours (weekdays 9-5)',
211
'*/30 9-17 * * 1-5': 'Every 30 min during business hours',
212
213
# Maintenance patterns
214
'0 2 * * 0': 'Weekly maintenance (Sundays at 2 AM)',
215
'0 1 1 * *': 'Monthly maintenance (1st at 1 AM)',
216
'0 0 1 1 *': 'Yearly maintenance (Jan 1st)',
217
}
218
219
def test_common_patterns():
220
"""Test all common cron patterns."""
221
222
print("Testing common cron patterns:")
223
print("-" * 50)
224
225
for pattern, description in COMMON_PATTERNS.items():
226
is_valid = bool(validators.cron(pattern))
227
status = "✓" if is_valid else "✗"
228
print(f"{status} {pattern:20} - {description}")
229
230
# Run the test
231
test_common_patterns()
232
```
233
234
## Cron Expression Components
235
236
### Field Ranges and Special Characters
237
238
```python
239
import validators
240
241
# Valid field ranges
242
CRON_FIELD_RANGES = {
243
'minute': '0-59',
244
'hour': '0-23',
245
'day_of_month': '1-31',
246
'month': '1-12',
247
'day_of_week': '0-7 (0 and 7 are Sunday)'
248
}
249
250
# Special characters
251
CRON_SPECIAL_CHARS = {
252
'*': 'Any value (wildcard)',
253
',': 'List separator (e.g., 1,3,5)',
254
'-': 'Range (e.g., 1-5)',
255
'/': 'Step values (e.g., */10 = every 10th)'
256
}
257
258
def validate_cron_field(field_value: str, field_type: str) -> bool:
259
"""Validate individual cron field (simplified example)."""
260
261
# This is a basic example - the actual validator does comprehensive checking
262
if field_value == '*':
263
return True
264
265
# For demonstration, just validate that the cron expression with this field works
266
test_cron = '0 0 * * *' # Default pattern
267
if field_type == 'minute':
268
test_cron = f'{field_value} 0 * * *'
269
elif field_type == 'hour':
270
test_cron = f'0 {field_value} * * *'
271
# ... etc for other fields
272
273
return bool(validators.cron(test_cron))
274
275
# Test field validation
276
print("Testing cron field validation:")
277
print(f"Minute field '*/15': {validate_cron_field('*/15', 'minute')}")
278
print(f"Hour field '9-17': {validate_cron_field('9-17', 'hour')}")
279
print(f"Invalid minute '60': {validate_cron_field('60', 'minute')}")
280
```
281
282
## Integration Examples
283
284
### Task Scheduler Validation
285
286
```python
287
import validators
288
289
class TaskScheduler:
290
"""Example task scheduler with cron validation."""
291
292
def __init__(self):
293
self.scheduled_tasks = []
294
295
def add_task(self, name: str, cron_expr: str, task_func: callable) -> bool:
296
"""Add a scheduled task with cron validation."""
297
298
if not validators.cron(cron_expr):
299
raise ValueError(f"Invalid cron expression: {cron_expr}")
300
301
task = {
302
'name': name,
303
'cron': cron_expr,
304
'function': task_func,
305
'active': True
306
}
307
308
self.scheduled_tasks.append(task)
309
return True
310
311
def list_tasks(self):
312
"""List all scheduled tasks."""
313
for task in self.scheduled_tasks:
314
analysis = analyze_cron_expression(task['cron'])
315
print(f"Task: {task['name']}")
316
print(f" Schedule: {task['cron']} ({analysis['frequency']})")
317
print(f" Active: {task['active']}")
318
319
# Usage example
320
scheduler = TaskScheduler()
321
322
try:
323
scheduler.add_task('Daily Backup', '0 2 * * *', lambda: print("Running backup"))
324
scheduler.add_task('Hourly Report', '0 * * * *', lambda: print("Generating report"))
325
scheduler.add_task('Weekly Cleanup', '0 0 * * 0', lambda: print("Cleaning up"))
326
327
scheduler.list_tasks()
328
329
except ValueError as e:
330
print(f"Scheduling error: {e}")
331
```