简体   繁体   中英

Check if JSON string is valid Pydantic schema

I want to check if a JSON string is a valid Pydantic schema.

from pydantic import BaseModel

class MySchema(BaseModel):
    val: int

I can do this very simply with a try/except:

import json

valid = '{"val": 1}'
invalid = '{"val": "horse"}'

def check_valid(item):
    try:
        MySchema(**json.loads(item))
        return True
    except:
        return False

print(check_valid(valid))
print(check_valid(invalid))

Output:

True
False

Use of try/except to get a true/false seems like bad practice. Is there a better way?

I think it's a good approach, I would only suggest treating the JSON parsing separately from the model instantiation, and being more specific when catching the exceptions, see below:

import pydantic
import json

class MySchema(pydantic.BaseModel):
    val: int

invalid_json = '{"invalid": 123'
invalid_value = '{"val": "horse"}'
invalid_key = '{"wrong_key": 1}'

valid = '{"val": 1}'
valid_2 = '{"val": "1"}'

def check_valid(item):
    try:
        json_item = json.loads(item)

    # Catch potential JSON formatting problems:
    except json.JSONDecodeError as exc:
        print(f"ERROR: Invalid JSON: {exc.msg}, line {exc.lineno}, column {exc.colno}")
        return False

    try:
        MySchema(**json_item)

    # Catch pydantic's validation errors:
    except pydantic.ValidationError as exc:
        print(f"ERROR: Invalid schema: {exc}")
        return False

    return True

print(check_valid(invalid_json))
# ERROR: Invalid JSON: Expecting ',' delimiter, line 1, column 16
# False

print(check_valid(invalid_value))
# ERROR: Invalid schema: 1 validation error for MySchema
# val
#   value is not a valid integer (type=type_error.integer)
# False

print(check_valid(invalid_key))
# ERROR: Invalid schema: 1 validation error for MySchema
# val
#   field required (type=value_error.missing)
# False

print(check_valid(valid))
# True

print(check_valid(valid_2))
# True

Of course, you could split up the logic into two functions, one taking care of the JSON validation, and the other of the pydantic model.

import pydantic

class MySchema(pydantic.BaseModel):
    val: int

MySchema.parse_raw('{"val": 1}')
MySchema.parse_raw('{"val": "horse"}')

I think it will be the simplest solution:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM