198 lines
5.2 KiB
Python
Executable File
198 lines
5.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Argument choices and custom validation patterns.
|
|
|
|
Usage:
|
|
python choices-validation.py --log-level debug
|
|
python choices-validation.py --port 8080 --host 192.168.1.1
|
|
python choices-validation.py --region us-east-1 --instance-type t2.micro
|
|
"""
|
|
|
|
import argparse
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def validate_port(value):
|
|
"""Custom validator for port numbers."""
|
|
try:
|
|
ivalue = int(value)
|
|
except ValueError:
|
|
raise argparse.ArgumentTypeError(f"{value} is not a valid integer")
|
|
|
|
if ivalue < 1 or ivalue > 65535:
|
|
raise argparse.ArgumentTypeError(
|
|
f"{value} is not a valid port (must be 1-65535)"
|
|
)
|
|
return ivalue
|
|
|
|
|
|
def validate_ip(value):
|
|
"""Custom validator for IP addresses."""
|
|
pattern = r'^(\d{1,3}\.){3}\d{1,3}$'
|
|
if not re.match(pattern, value):
|
|
raise argparse.ArgumentTypeError(f"{value} is not a valid IP address")
|
|
|
|
# Check each octet is 0-255
|
|
octets = [int(x) for x in value.split('.')]
|
|
if any(o < 0 or o > 255 for o in octets):
|
|
raise argparse.ArgumentTypeError(
|
|
f"{value} contains invalid octets (must be 0-255)"
|
|
)
|
|
return value
|
|
|
|
|
|
def validate_email(value):
|
|
"""Custom validator for email addresses."""
|
|
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
|
if not re.match(pattern, value):
|
|
raise argparse.ArgumentTypeError(f"{value} is not a valid email address")
|
|
return value
|
|
|
|
|
|
def validate_path_exists(value):
|
|
"""Custom validator to check if path exists."""
|
|
path = Path(value)
|
|
if not path.exists():
|
|
raise argparse.ArgumentTypeError(f"Path does not exist: {value}")
|
|
return path
|
|
|
|
|
|
def validate_range(min_val, max_val):
|
|
"""Factory function for range validators."""
|
|
def validator(value):
|
|
try:
|
|
ivalue = int(value)
|
|
except ValueError:
|
|
raise argparse.ArgumentTypeError(f"{value} is not a valid integer")
|
|
|
|
if ivalue < min_val or ivalue > max_val:
|
|
raise argparse.ArgumentTypeError(
|
|
f"{value} must be between {min_val} and {max_val}"
|
|
)
|
|
return ivalue
|
|
return validator
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description='Demonstrate choices and validation patterns',
|
|
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
)
|
|
|
|
# ===== String Choices =====
|
|
parser.add_argument(
|
|
'--log-level',
|
|
choices=['debug', 'info', 'warning', 'error', 'critical'],
|
|
default='info',
|
|
help='Logging level (default: %(default)s)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--region',
|
|
choices=[
|
|
'us-east-1', 'us-west-1', 'us-west-2',
|
|
'eu-west-1', 'eu-central-1',
|
|
'ap-southeast-1', 'ap-northeast-1'
|
|
],
|
|
default='us-east-1',
|
|
help='AWS region (default: %(default)s)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--format',
|
|
choices=['json', 'yaml', 'toml', 'xml'],
|
|
default='json',
|
|
help='Output format (default: %(default)s)'
|
|
)
|
|
|
|
# ===== Custom Validators =====
|
|
parser.add_argument(
|
|
'--port',
|
|
type=validate_port,
|
|
default=8080,
|
|
help='Server port (1-65535, default: %(default)s)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--host',
|
|
type=validate_ip,
|
|
default='127.0.0.1',
|
|
help='Server host IP (default: %(default)s)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--email',
|
|
type=validate_email,
|
|
help='Email address for notifications'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--config',
|
|
type=validate_path_exists,
|
|
help='Path to configuration file (must exist)'
|
|
)
|
|
|
|
# ===== Range Validators =====
|
|
parser.add_argument(
|
|
'--workers',
|
|
type=validate_range(1, 32),
|
|
default=4,
|
|
help='Number of worker processes (1-32, default: %(default)s)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--timeout',
|
|
type=validate_range(1, 3600),
|
|
default=30,
|
|
help='Request timeout in seconds (1-3600, default: %(default)s)'
|
|
)
|
|
|
|
# ===== Integer Choices =====
|
|
parser.add_argument(
|
|
'--instance-type',
|
|
choices=['t2.micro', 't2.small', 't2.medium', 't3.large'],
|
|
default='t2.micro',
|
|
help='EC2 instance type (default: %(default)s)'
|
|
)
|
|
|
|
# ===== Type Coercion =====
|
|
parser.add_argument(
|
|
'--memory',
|
|
type=float,
|
|
default=1.0,
|
|
help='Memory limit in GB (default: %(default)s)'
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--retry-count',
|
|
type=int,
|
|
default=3,
|
|
help='Number of retries (default: %(default)s)'
|
|
)
|
|
|
|
# Parse arguments
|
|
args = parser.parse_args()
|
|
|
|
# Display parsed values
|
|
print("Configuration:")
|
|
print(f" Log Level: {args.log_level}")
|
|
print(f" Region: {args.region}")
|
|
print(f" Format: {args.format}")
|
|
print(f" Port: {args.port}")
|
|
print(f" Host: {args.host}")
|
|
print(f" Email: {args.email}")
|
|
print(f" Config: {args.config}")
|
|
print(f" Workers: {args.workers}")
|
|
print(f" Timeout: {args.timeout}s")
|
|
print(f" Instance Type: {args.instance_type}")
|
|
print(f" Memory: {args.memory}GB")
|
|
print(f" Retry Count: {args.retry_count}")
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|