import json
import re
def validate_api_payload(payload, schema):
"""
Validates an API payload against a predefined schema.
Args:
payload (dict): The API payload to validate.
schema (dict): A dictionary defining the expected schema.
Returns:
bool: True if the payload is valid, False otherwise.
"""
try:
# Check if the payload is valid JSON
json.loads(json.dumps(payload))
except json.JSONDecodeError:
print("Error: Invalid JSON payload.")
return False
for field, details in schema.items():
if field not in payload:
print(f"Error: Missing field: {field}")
return False
expected_type = details.get("type")
if expected_type:
if expected_type == "string":
if not isinstance(payload[field], str):
print(f"Error: Field '{field}' should be a string.")
return False
elif expected_type == "integer":
if not isinstance(payload[field], int):
print(f"Error: Field '{field}' should be an integer.")
return False
elif expected_type == "float":
if not isinstance(payload[field], (int, float)):
print(f"Error: Field '{field}' should be a float.")
return False
elif expected_type == "boolean":
if not isinstance(payload[field], bool):
print(f"Error: Field '{field}' should be a boolean.")
return False
elif expected_type == "list":
if not isinstance(payload[field], list):
print(f"Error: Field '{field}' should be a list.")
return False
elif expected_type == "dict":
if not isinstance(payload[field], dict):
print(f"Error: Field '{field}' should be a dictionary.")
return False
if "required" in details and field in details["required"] and not payload[field]:
print(f"Error: Field '{field}' is required and cannot be empty.")
return False
if "pattern" in details:
pattern = re.compile(details["pattern"])
if not pattern.match(str(payload[field])):
print(f"Error: Field '{field}' does not match pattern: {details['pattern']}")
return False
return True
if __name__ == '__main__':
# Example Usage
schema = {
"user_id": {"type": "integer"},
"username": {"type": "string"},
"email": {"type": "string", "pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"},
"is_active": {"type": "boolean"},
"roles": {"type": "list"},
"details": {"type": "dict"}
}
payload1 = {
"user_id": 123,
"username": "john.doe",
"email": "john.doe@example.com",
"is_active": True,
"roles": ["admin", "editor"],
"details": {"created_at": "2023-10-27"}
}
payload2 = {
"username": "jane doe",
"email": "invalid-email",
"is_active": "yes"
}
print(f"Payload 1 is valid: {validate_api_payload(payload1, schema)}")
print(f"Payload 2 is valid: {validate_api_payload(payload2, schema)}")
Add your comment