Python Data Validation for Humans™ - comprehensive validation library for various data types without schema definitions
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.
Validates cron expression strings used for scheduling tasks in Unix-like systems.
def cron(value: str, /) -> Union[Literal[True], ValidationError]:
"""
Validate cron expression strings.
Parameters:
- value: Cron expression string to validate
Returns:
True if valid cron expression, ValidationError otherwise
Validates standard 5-field cron format:
- Minute (0-59)
- Hour (0-23)
- Day of month (1-31)
- Month (1-12)
- Day of week (0-7, where 0 and 7 are Sunday)
Supported special characters:
- * (any value)
- , (value list separator)
- - (range)
- / (step values)
Examples:
- "0 0 * * *" (daily at midnight)
- "0 9-17 * * 1-5" (hourly during business hours on weekdays)
- "*/15 * * * *" (every 15 minutes)
- "0 0 1 */3 *" (first day of every 3rd month)
"""import validators
# Basic cron expressions
validators.cron('0 0 * * *') # True (daily at midnight)
validators.cron('0 12 * * *') # True (daily at noon)
validators.cron('30 14 * * *') # True (daily at 2:30 PM)
# Hourly and minute patterns
validators.cron('0 * * * *') # True (every hour)
validators.cron('*/15 * * * *') # True (every 15 minutes)
validators.cron('0,30 * * * *') # True (twice per hour at :00 and :30)
# Weekly patterns
validators.cron('0 9 * * 1') # True (Mondays at 9 AM)
validators.cron('0 9 * * 1-5') # True (weekdays at 9 AM)
validators.cron('0 0 * * 0') # True (Sundays at midnight)
validators.cron('0 0 * * 7') # True (Sundays at midnight, alternative)
# Monthly patterns
validators.cron('0 0 1 * *') # True (first day of every month)
validators.cron('0 0 15 * *') # True (15th of every month)
validators.cron('0 0 * * 1') # True (every Monday)
# Complex patterns with ranges and steps
validators.cron('0 9-17 * * 1-5') # True (business hours on weekdays)
validators.cron('*/10 9-17 * * 1-5') # True (every 10 min during business hours)
validators.cron('0 0 1 */3 *') # True (quarterly on 1st day)
validators.cron('0 0 1 1,7 *') # True (January 1st and July 1st)
# Invalid cron expressions
validators.cron('60 0 * * *') # ValidationError (minute 60 invalid)
validators.cron('0 24 * * *') # ValidationError (hour 24 invalid)
validators.cron('0 0 32 * *') # ValidationError (day 32 invalid)
validators.cron('0 0 0 * *') # ValidationError (day 0 invalid)
validators.cron('0 0 * 13 *') # ValidationError (month 13 invalid)
validators.cron('0 0 * * 8') # ValidationError (day-of-week 8 invalid)
# Malformed expressions
validators.cron('0 0 * *') # ValidationError (missing field)
validators.cron('0 0 * * * *') # ValidationError (too many fields)
validators.cron('0 0 * * x') # ValidationError (invalid character)import validators
def analyze_cron_expression(expression: str) -> dict:
"""Analyze and describe a cron expression."""
if not validators.cron(expression):
return {'valid': False, 'error': 'Invalid cron expression'}
fields = expression.split()
minute, hour, day, month, dow = fields
analysis = {
'valid': True,
'expression': expression,
'fields': {
'minute': minute,
'hour': hour,
'day_of_month': day,
'month': month,
'day_of_week': dow
}
}
# Basic frequency analysis
if minute == '*' and hour == '*':
analysis['frequency'] = 'Every minute'
elif hour == '*':
if '/' in minute:
step = minute.split('/')[1]
analysis['frequency'] = f'Every {step} minutes'
else:
analysis['frequency'] = 'Every hour'
elif day == '*' and month == '*' and dow == '*':
analysis['frequency'] = 'Daily'
elif dow != '*':
analysis['frequency'] = 'Weekly'
elif day != '*':
analysis['frequency'] = 'Monthly'
else:
analysis['frequency'] = 'Custom'
return analysis
# Usage examples
expressions = [
'0 0 * * *', # Daily
'*/15 * * * *', # Every 15 minutes
'0 9 * * 1-5', # Weekdays at 9 AM
'0 0 1 * *', # First of month
]
for expr in expressions:
result = analyze_cron_expression(expr)
print(f"{expr}: {result['frequency']}")import validators
from datetime import datetime, timedelta
def validate_cron_schedule(cron_expr: str, max_executions: int = 10) -> dict:
"""Validate cron expression and show next execution times."""
if not validators.cron(cron_expr):
return {'valid': False, 'error': 'Invalid cron expression'}
# This is a simplified example - real implementation would use a cron library
# like python-crontab or croniter for accurate next execution calculation
result = {
'valid': True,
'expression': cron_expr,
'analysis': analyze_cron_expression(cron_expr),
'note': 'Use croniter library for actual execution time calculation'
}
return result
# Usage
schedule = validate_cron_schedule('0 9 * * 1-5')
print(f"Schedule valid: {schedule['valid']}")
print(f"Frequency: {schedule['analysis']['frequency']}")import validators
# Define common cron patterns with descriptions
COMMON_PATTERNS = {
# Basic time patterns
'0 0 * * *': 'Daily at midnight',
'0 12 * * *': 'Daily at noon',
'0 9 * * *': 'Daily at 9 AM',
'0 17 * * *': 'Daily at 5 PM',
# Frequent patterns
'*/5 * * * *': 'Every 5 minutes',
'*/15 * * * *': 'Every 15 minutes',
'*/30 * * * *': 'Every 30 minutes',
'0 * * * *': 'Every hour',
# Weekly patterns
'0 9 * * 1': 'Mondays at 9 AM',
'0 9 * * 1-5': 'Weekdays at 9 AM',
'0 0 * * 0': 'Sundays at midnight',
'0 0 * * 6': 'Saturdays at midnight',
# Monthly patterns
'0 0 1 * *': 'First day of every month',
'0 0 15 * *': '15th of every month',
'0 0 * * 1': 'Every Monday (weekly)',
# Business hour patterns
'0 9-17 * * 1-5': 'Every hour during business hours (weekdays 9-5)',
'*/30 9-17 * * 1-5': 'Every 30 min during business hours',
# Maintenance patterns
'0 2 * * 0': 'Weekly maintenance (Sundays at 2 AM)',
'0 1 1 * *': 'Monthly maintenance (1st at 1 AM)',
'0 0 1 1 *': 'Yearly maintenance (Jan 1st)',
}
def test_common_patterns():
"""Test all common cron patterns."""
print("Testing common cron patterns:")
print("-" * 50)
for pattern, description in COMMON_PATTERNS.items():
is_valid = bool(validators.cron(pattern))
status = "✓" if is_valid else "✗"
print(f"{status} {pattern:20} - {description}")
# Run the test
test_common_patterns()import validators
# Valid field ranges
CRON_FIELD_RANGES = {
'minute': '0-59',
'hour': '0-23',
'day_of_month': '1-31',
'month': '1-12',
'day_of_week': '0-7 (0 and 7 are Sunday)'
}
# Special characters
CRON_SPECIAL_CHARS = {
'*': 'Any value (wildcard)',
',': 'List separator (e.g., 1,3,5)',
'-': 'Range (e.g., 1-5)',
'/': 'Step values (e.g., */10 = every 10th)'
}
def validate_cron_field(field_value: str, field_type: str) -> bool:
"""Validate individual cron field (simplified example)."""
# This is a basic example - the actual validator does comprehensive checking
if field_value == '*':
return True
# For demonstration, just validate that the cron expression with this field works
test_cron = '0 0 * * *' # Default pattern
if field_type == 'minute':
test_cron = f'{field_value} 0 * * *'
elif field_type == 'hour':
test_cron = f'0 {field_value} * * *'
# ... etc for other fields
return bool(validators.cron(test_cron))
# Test field validation
print("Testing cron field validation:")
print(f"Minute field '*/15': {validate_cron_field('*/15', 'minute')}")
print(f"Hour field '9-17': {validate_cron_field('9-17', 'hour')}")
print(f"Invalid minute '60': {validate_cron_field('60', 'minute')}")import validators
class TaskScheduler:
"""Example task scheduler with cron validation."""
def __init__(self):
self.scheduled_tasks = []
def add_task(self, name: str, cron_expr: str, task_func: callable) -> bool:
"""Add a scheduled task with cron validation."""
if not validators.cron(cron_expr):
raise ValueError(f"Invalid cron expression: {cron_expr}")
task = {
'name': name,
'cron': cron_expr,
'function': task_func,
'active': True
}
self.scheduled_tasks.append(task)
return True
def list_tasks(self):
"""List all scheduled tasks."""
for task in self.scheduled_tasks:
analysis = analyze_cron_expression(task['cron'])
print(f"Task: {task['name']}")
print(f" Schedule: {task['cron']} ({analysis['frequency']})")
print(f" Active: {task['active']}")
# Usage example
scheduler = TaskScheduler()
try:
scheduler.add_task('Daily Backup', '0 2 * * *', lambda: print("Running backup"))
scheduler.add_task('Hourly Report', '0 * * * *', lambda: print("Generating report"))
scheduler.add_task('Weekly Cleanup', '0 0 * * 0', lambda: print("Cleaning up"))
scheduler.list_tasks()
except ValueError as e:
print(f"Scheduling error: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-validators