Can you validate json per object?

I want to validate my json data based on defined jsonschema. I have the following script:

import json
import jsonschema
from jsonschema import validate

schema = {
  "type": "array",
  "items": {
    "properties": {
      "description": {
        "type": "string"
      },
      "status": {
        "type": "boolean"
      },
      "value1": {
        "type": "number"
      },
      "value2": {
        "type": "number"
      }
    }
  }
}

data = json.loads('[{"description": "Hello world!", "status": true, "value1": 1, "value2": 2}, {"description": "Test", "status": "true", "value1": 3, "value2": 4}]')

def validateJson(data):
    try:
        validate(instance=data, schema=schema)
    except jsonschema.exceptions.ValidationError as err:
        print(err)
        return False
    return True

# validate it
isValid = validateJson(data)
if isValid:
    print(data)
    print("Given JSON data is Valid")
else:
    print(data)
    print("Given JSON data is InValid")

When I run the code, I get that the data is invalid because “true” in the second object is not boolean. But as you can see, the first object

{"description": "Hello world!", "status": true, "value1": 1, "value2": 2}

is valid. So what I really want is that the validateJSON function gives me valid and invalid objects and not validate the data as a whole. How can I do that?

Answer

Define a schema that each JSON object in your array should be validated against, and validate each independently.

schema = {
  "type": "object",
  "properties": {
    "description": {
      "type": "string"
    },
    "status": {
      "type": "boolean"
    },
    "value1": {
      "type": "number"
    },
    "value2": {
      "type": "number"
    }
  }
}

Then:

>>> for i, obj in enumerate(data):
...     try:
...         validate(instance=obj, schema=schema)
...     except Exception as e:
...         print(f"obj {i} invalid: {e}")
...     else:
...         print(f"obj {i} valid")

obj 0 valid
obj 1 invalid: 'true' is not of type 'boolean'

Failed validating 'type' in schema['properties']['status']:
    {'type': 'boolean'}

On instance['status']:
    'true'

If you want to keep references to the valid versus invalid objects, you could append their numeric indices to two lists such as valid_idxs: list[int] and invalid_idxs: list[int].