提取参数的Python json模式

时间:2016-09-12 09:31:38

标签: python json

我需要将请求解析为以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中的嵌套dicts,而不仅仅是扁平的dicts。

2 个答案:

答案 0 :(得分:0)

请参阅http://json-schema.org

这看起来不像是Python问题。

答案 1 :(得分:0)

以下代码可能有所帮助。它也支持嵌套的dict。

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}