Извлеките требуемый ключ в JSON, который отсутствует в ValidationError

Я пытаюсь проверить JSON в python, используя библиотеку jsonschema. Чего я хочу добиться, так это словаря с ключами, состоящими из ключей json, вызывающих проблемы и сообщения от валидатора в качестве значений.

С проверкой типа проблем нет, поскольку она возвращает путь к ключу json, который не проходит проверку. Моя проблема заключается в том, что ключ отсутствует, переменная пути в ValidationError пуста, и я не могу найти другое место, где указано, какой ключ json вызывает проблемы. Единственное место, в котором указывается, какой ключ json является проблемой, — это сообщение, но его разделение для извлечения этой информации больше похоже на обходной путь, чем на решение.

Код:

import jsonschema

schema = {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
        "name": {
            "type": "string"
        },
        "email": {
            "type": "string"
        }
    },
    "required": ["name", "email"]
}

jsonToValidate = {
  "name": 1234
}

validator = jsonschema.Draft202012Validator(schema)
errorsGenerator = validator.iter_errors(jsonToValidate)
errors = dict()
for err in errorsGenerator:
    # errors.update({err.path[0], err.message})
    print("path: ", err.path, " \n message: ", err.message)

Текущий выход:

path:  deque(['name'])  
 message:  1234 is not of type 'string'
path:  deque([])  
 message:  'email' is a required property

Ожидаемый результат: Словарь с ключом в виде ключа json, который вызывает проблемы, и сообщением в качестве значения. Для этого примера это будет выглядеть так:

{
    "name": "1234 is not of type 'string'",
    "email":  'email' is a required property
}

Итак, мой вопрос: возможно ли извлечь информацию о том, какой отсутствующий ключ json (требуемый схемой) вызвал ValidationError?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Судя по вашему примеру, это первое слово сообщения об ошибке, поэтому вы можете извлечь первое слово:

err.message.split(" ")[0]

И используйте это для создания своего словаря.

Ну да, но тогда мне нужно будет добавить код, чтобы проверить, относится ли ошибка к отсутствующему полю или несоответствующему типу, и обрабатывать их по-разному. Это немного усложняет код. Это конечно решение, но мне было интересно, есть ли что-то более элегантное/универсальное

MrHutnik 22.07.2023 20:34
Ответ принят как подходящий

В репозитории jsonschema есть открытый отчет об ошибке именно по вашей проблеме, с кратким ответом, что в настоящее время нет стандартного способа получить отсутствующий необходимый ключ. Однако в комментарии к отчету упоминается обходной путь с помощью пользовательских валидаторов. Может быть, это был бы способ пойти и для вас.

Обновление: в качестве альтернативы вы можете использовать сочетание синтаксического анализа сообщений и использования доступных атрибутов: проанализируйте сообщение об ошибке для ключей required, как это предлагается в ответе пользователя user2704177; в противном случае используйте ValidationErrorpath, где это возможно. Итак, что-то вроде:

errors = dict()
for err in errorsGenerator:
    if err.validator == "required":
        # Parse first word of error message as key, strip surrounding quotes
        errors[err.message.split(" ")[0].strip("'")] = err.message
    else:
        # Use last path element as key (empty string for empty path)
        errors[err.path[-1] if err.path else ""] = err.message
print(errors)
# >>> {'name': "1234 is not of type 'string'", 'email': "'email' is a required property"}

Спасибо за указание на отчет об ошибке. Возможно, я попробую обходной путь, о котором вы упомянули, но пока это не так важно.

MrHutnik 24.07.2023 23:28

Другие вопросы по теме