1. import json
  2. def validate_json(json_data, schema):
  3. """
  4. Validates a JSON object against a given schema.
  5. Args:
  6. json_data (dict): The JSON object to validate.
  7. schema (dict): The schema to validate against.
  8. Returns:
  9. list: A list of flagged anomalies (error messages). Empty list if valid.
  10. """
  11. anomalies = []
  12. def check_type(value, expected_type):
  13. """Checks if a value matches the expected type."""
  14. if type(value) != expected_type:
  15. return f"Type mismatch: Expected {expected_type}, got {type(value)}"
  16. return None
  17. def check_required_fields(data, schema):
  18. """Checks for missing required fields."""
  19. for key, value in schema.items():
  20. if key not in data:
  21. return f"Missing required field: {key}"
  22. return None
  23. def check_value_constraints(value, constraints):
  24. """Checks if a value meets specific constraints."""
  25. if constraints:
  26. for constraint_type, constraint_value in constraints.items():
  27. if constraint_type == "min":
  28. if not isinstance(value, (int, float)) or value < constraint_value:
  29. return f"Value {key} must be >= {constraint_value}"
  30. elif constraint_type == "max":
  31. if not isinstance(value, (int, float)) or value > constraint_value:
  32. return f"Value {key} must be <= {constraint_value}"
  33. elif constraint_type == "in":
  34. if value not in constraint_value:
  35. return f"Value {key} must be one of: {constraint_value}"
  36. return None
  37. # Check required fields
  38. required_error = check_required_fields(json_data, schema)
  39. if required_error:
  40. anomalies.append(required_error)
  41. # Check data types
  42. for key, value in schema.items():
  43. if key in json_data:
  44. if isinstance(value, dict):
  45. if not isinstance(json_data[key], dict):
  46. anomalies.append(f"Type mismatch for {key}: Expected dict, got {type(json_data[key])}")
  47. continue
  48. else:
  49. nested_errors = validate_json(json_data[key], value)
  50. anomalies.extend(nested_errors)
  51. elif isinstance(value, list):
  52. if not isinstance(json_data[key], list):
  53. anomalies.append(f"Type mismatch for {key}: Expected list, got {type(json_data[key])}")
  54. continue
  55. else:
  56. for i, item in enumerate(json_data[key]):
  57. if isinstance(value[i], dict):
  58. if not isinstance(item, dict):
  59. anomalies.append(f"Type mismatch for item in list {key} at index {i}: Expected dict, got {type(item)}")
  60. elif isinstance(value[i], list):
  61. anomalies.append(f"Type mismatch for item in list {key} at index {i}: Expected list, got {type(item)}")
  62. else:
  63. continue #ignore simple types
  64. else:
  65. error = check_type(json_data[key], value)
  66. if error:
  67. anomalies.append(error)
  68. return anomalies
  69. if __name__ == '__main__':
  70. # Example Usage
  71. schema = {
  72. "name": str,
  73. "age": int,
  74. "city": str,
  75. "scores": list,
  76. "details": {
  77. "height": float,
  78. "weight": float
  79. }
  80. }
  81. valid_json = {
  82. "name": "Alice",
  83. "age": 30,
  84. "city": "New York",
  85. "scores": [85, 90, 92],
  86. "details": {
  87. "height": 1.75,
  88. "weight": 60.0
  89. }
  90. }
  91. invalid_json = {
  92. "name": 123,
  93. "age": "thirty",
  94. "scores": "not a list",
  95. "details": {
  96. "height": "tall",
  97. "weight": -10.0
  98. }
  99. }
  100. print("

Add your comment