【问题标题】:Python json schema that extracts parameters提取参数的 Python json 模式
【发布时间】:2016-09-12 09:31:37
【问题描述】:

我需要将请求解析为以 JSON 格式出现的单个 url,但有几种不同的格式。例如,有些时间戳记为timestamp attr,另一些记为unixtime 等。所以我想为所有类型的请求创建json模式,这些模式不仅可以验证传入的JSON,还可以从指定的位置提取它们的参数。有没有图书馆可以做到这一点?

例子:

如果我可以定义一个看起来像这样的模式

schema = {
    "type" : "object",
    "properties" : {
        "price" : {
            "type" : "number",
            "mapped_name": "product_price"
        },
        "name" : {
            "type" : "string",
            "mapped_name": "product_name"

        },
        "added_at":{
            "type" : "int",
            "mapped_name": "timestamp"

        },
    },
}

然后将其应用到字典

request = {
    "name" : "Eggs",
    "price" : 34.99,
    'added_at': 1234567
}

通过一些神奇的功能

params = validate_and_extract(request, schema)

我希望 params 在那里有映射值:

{"mapped_name": "Eggs", "product_price": 34.99, "timestamp": 1234567}

所以这是我正在寻找的模块。它应该支持request 中的嵌套字典,而不仅仅是平面字典。

【问题讨论】:

  • 你能举一个输入和期望输出的例子吗?
  • json 库的标准JSONDecoder 就是这样做的。如果要解析特定的输入,例如日期see this thread
  • 不知道 Python 中有任何此类库。您是否尝试过编写自己的函数来执行此操作?如果您没有自己尝试过,社区用户将不愿意提供帮助。

标签: python json


【解决方案1】:

以下代码可能会有所帮助。它也支持嵌套字典。

import json


def valid_type(type_name, obj):
    if type_name == "number":
        return isinstance(obj, int) or isinstance(obj, float)

    if type_name == "int":
        return isinstance(obj, int)

    if type_name == "float":
        return isinstance(obj, float)

    if type_name == "string":
        return isinstance(obj, str)


def validate_and_extract(request, schema):
    ''' Validate request (dict) against the schema (dict).

        Validation is limited to naming and type information.
        No check is done to ensure all elements in schema
        are present in the request. This could be enhanced by
        specifying mandatory/optional/conditional information
        within the schema and subsequently checking for that.
    '''
    out = {}

    for k, v in request.items():
        if k not in schema['properties'].keys():
            print("Key '{}' not in schema ... skipping.".format(k))
            continue

        if schema['properties'][k]['type'] == 'object':
            v = validate_and_extract(v, schema['properties'][k])

        elif not valid_type(schema['properties'][k]['type'], v):
            print("Wrong type for '{}' ... skipping.".format(k))
            continue

        out[schema['properties'][k]['mapped_name']] = v

    return out


# Sample Data 1
schema1 = {
    "type" : "object",
    "properties" : {
        "price" : {
            "type" : "number",
            "mapped_name": "product_price"
        },
        "name" : {
            "type" : "string",
            "mapped_name": "product_name"

        },
        "added_at":{
            "type" : "int",
            "mapped_name": "timestamp"

        },
    },
}
request1 = {
    "name" : "Eggs",
    "price" : 34.99,
    'added_at': 1234567
}

# Sample Data 2: containing nested dict
schema2 = {
    "type" : "object",
    "properties" : {
        "price" : {
            "type" : "number",
            "mapped_name": "product_price"
        },
        "name" : {
            "type" : "string",
            "mapped_name": "product_name"
        },
        "added_at":{
            "type" : "int",
            "mapped_name": "timestamp"
        },
        "discount":{
            "type" : "object",
            "mapped_name": "offer",
            "properties" : {
                "percent": {
                    "type" : "int",
                    "mapped_name": "percentage"
                },
                "last_date": {
                    "type" : "string",
                    "mapped_name": "end_date"
                },
            }
        },
    },
}
request2 = {
    "name" : "Eggs",
    "price" : 34.99,
    'added_at': 1234567,
    'discount' : {
        'percent' : 40,
        'last_date' : '2016-09-25'
    }
}


params = validate_and_extract(request1, schema1)
print(params)

params = validate_and_extract(request2, schema2)
print(params)

运行的输出:

{'timestamp': 1234567, 'product_name': 'Eggs', 'product_price': 34.99}
{'offer': {'percentage': 40, 'end_date': '2016-09-25'}, 'timestamp': 1234567, 'product_name': 'Eggs', 'product_price': 34.99}

【讨论】:

    【解决方案2】:

    http://json-schema.org

    这看起来不像是 Python 问题。

    【讨论】:

      猜你喜欢
      • 2016-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-02
      • 2019-06-26
      相关资源
      最近更新 更多