【问题标题】:Python: jsonschema package to validate schema and custom error messagesPython:用于验证模式和自定义错误消息的 jsonschema 包
【发布时间】:2014-09-18 01:05:38
【问题描述】:

鉴于此架构:

{
    "type": "object",
    "properties": {
        "account": {
            "type": "object",
            "required": ["id"],
            "properties": {
                "id": {"type": "number"}
            }
        },
        "name": {"type": "string"},
        "trigger": {
            "type": "object",
            "required": ["type"],
            "properties": {
                "type": {"type": "string"}
            }
        },
        "content": {
            "type": "object",
            "properties": {
                "emails": {
                    "type": "array",
                    "minItems": 1,
                    "items": {
                        "type": "object",
                        "required": ["fromEmail","subject"],
                        "properties": {
                            "fromEmail": {"type": "string", "format": "email"},
                            "subject": {"type": "string"}
                        }
                    }
                }
            }
        }
    }
}

我正在尝试使用 jsonschema.Draft4Validator 来验证 POST 的 JSON 对象以检查其有效性,但在尝试从返回的错误中提出更好的人类可读消息时遇到了一些问题。

这是我验证的方式:

from jsonschema import Draft4Validator

v = Draft4Validator(self.schema)
errors = sorted(v.iter_errors(autoresponder_workflow), key=lambda e: e.path)

if errors:
    print(', '.join(
        '%s %s %s' % (error.path.popleft(), error.path.pop(), error.message) for error in errors
    ))

错误信息如下:

content emails [] is too short, trigger type None is not of type u'string'

我正在尝试创建一个看起来有点像的错误消息请在您的工作流程中添加至少一封电子邮件,“请确保您的所有电子邮件都包含主题行”,等等

【问题讨论】:

    标签: python validation jsonschema


    【解决方案1】:

    发生错误时,我需要向用户显示更详细的自定义消息。我通过向架构中的属性添加一个字段然后在 ValidationError 上查找它来做到这一点。

    import json
    import jsonschema
    
    
    def validate(_data, _schema):
        try:
            jsonschema.validate(_data, _schema)
        except jsonschema.ValidationError as e:
            return e.schema["error_msg"] 
    
    
    schema = {
        "title": "index",
        "type": "object",
        "required": [
            "author",
            "description"
        ],
        "properties": {
            "author": {
                "type": "string",
                "description": "Name of the Author",
                "minLength": 3,
                "default": "",
                "error_msg": "Please provide a Author name"
            },
            "description": {
                "type": "string",
                "description": "Short description",
                "minLength": 10,
                "default": "",
                "error_msg": "Please add a short description"
            }
        }
    }
    
    data = {
        "author": "Jerakin",
        "description": ""
    }
    

    【讨论】:

    • 这真是太好了。我对同样的问题感到沮丧,并开始认为像“error_msg”这样的字段将是对 jsonschema 规范的一个很好的补充。这是一个不错的解决方法。我唯一想添加的是错误消息中的插值,也许。但是,考虑到这通常用于处理传入数据(用户数据),这可能具有固有的风险。另一种选择是让 error_msg 成为回调。
    • 很棒的解决方案。
    【解决方案2】:

    您可以捕获ValidationError exception 并从 ValidationError 元数据中为您想要的特定情况构建自定义消息。在这个对象中你有:

    失败验证器的信息:它的值和架构路径 失败实例的信息:验证失败时的路径和值 子模式中可能出现的错误 原因(非验证错误导致的错误)

    【讨论】:

      【解决方案3】:

      我在运行验证之前使用此清理功能。它将 None 转换为空字符串,因为 jsonschema 不喜欢处理 None 类型。验证时会抛出:jsonschema.exceptions.ValidationError: None is not of type u'string'

      def scrub(x):
          ret = copy.deepcopy(x)
          if isinstance(x, dict):
              for k, v in ret.items():
                  ret[k] = scrub(v)
          if isinstance(x, (list, tuple)):
              for k, v in enumerate(ret):
                  ret[k] = scrub(v)
          if x is None:
              ret = ''
          return ret
      

      【讨论】:

      • JSON 模式标准强制执行这种类型检查,jsonschema 只是符合标准。 None(又名"null")实际上不是"string" 类型。如果您希望null 成为有效值,只需为架构中的对象设置"type": ["string", "null"]。或者对于更复杂的类型使用"oneOf",并添加"null"作为选项之一。
      【解决方案4】:

      你可以试试jsonschema.exceptions.ValidationError:

      try:
          v = Draft4Validator(self.schema)
      except jsonschema.exceptions.ValidationError as err:
          print(err.message)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-24
        • 1970-01-01
        • 1970-01-01
        • 2020-08-31
        • 1970-01-01
        • 2017-09-14
        • 1970-01-01
        相关资源
        最近更新 更多