Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 不使用json模式的用户定义模式验证_Python_Json_Validation_Schema - Fatal编程技术网

Python 不使用json模式的用户定义模式验证

Python 不使用json模式的用户定义模式验证,python,json,validation,schema,Python,Json,Validation,Schema,我希望有一个用于模式验证的用户定义结构。例如,我希望能够为数据库文件创建不同的字段,在数据加载到文件中之前,我希望检查模式。使用json shema和validate方法可以很容易地做到这一点;但是,除了python的标准内置包之外,我不想使用任何包。比如我有 "price" : {"type" : "number" and number >45}, "name" : {"type" : "string"} "age" : {"type" : "number" and number >

我希望有一个用于模式验证的用户定义结构。例如,我希望能够为数据库文件创建不同的字段,在数据加载到文件中之前,我希望检查模式。使用json shema和validate方法可以很容易地做到这一点;但是,除了python的标准内置包之外,我不想使用任何包。比如我有

"price" : {"type" : "number" and number >45},
"name" : {"type" : "string"}
"age" : {"type" : "number" and number >0}
.................
那么,在不使用json模式的情况下,如何使用这样的模式来验证我的输入呢


谢谢

在这种情况下,您能做的最好的事情是在使用ast保护验证代码之后评估它


除了标准的内置包约束之外,它不满足您的包,但您可能需要考虑。它简洁、易于使用,到目前为止,我们在项目中对它非常满意。

没有使用它有什么特别的原因吗?这将是更多的工作重做自己。是的,因为在演练中,我不允许使用非内置软件包;因此,如果我想使用json模式,我必须下载它;而这在演习中是不允许的。应该有办法;现在我正在考虑使用iInstance。例如,对于第一个字段,我可以有如下内容:isinstancenumber、int和number>45。
# schema_validator.py
import ast


class SchemaSecurityValidationError(Exception):
    pass


class ValidationError(Exception):
    pass


def secure_schema(schema,
                  builitins=__builtins__.__dict__.values(),
                  forbidden_builtins=(file, open, __import__),
                  forbidden_nodes=(ast.Import, ast.ImportFrom)):
    forbidden_builtins_names = tuple(b.__name__ for b in forbidden_builtins)
    for field, field_descriptor in schema.iteritems():
        type_validator = field_descriptor.get('type', None)
        if type_validator is not None:
            if not type_validator in builitins:
                raise SchemaSecurityValidationError(
                    "%s:'type' can only be basic type or builtin" % field)
            if type_validator in forbidden_builtins:
                raise SchemaSecurityValidationError(
                    "%s:'type' cant be of %s type" % (field, type_validator))
        value_validator = field_descriptor.get('validator', None)
        if value_validator is not None:
            tree = ast.parse(value_validator)
            for node in ast.walk(tree):
                if type(node) in forbidden_nodes:
                    raise SchemaSecurityValidationError(
                        "%s:%s is forbidden in validator" % (field, ast.dump(node)))
                if  isinstance(node, ast.Call) \
                        and isinstance(node.func, ast.Name)\
                        and node.func.id in forbidden_builtins_names:
                    raise SchemaSecurityValidationError(
                        "%s:%s is forbidden in validator" % (field, ast.dump(node)))


def validate(record, schema):
    secure_schema(schema)
    for field, field_descriptor in schema.iteritems():
        value = record[field]
        type_validator = field_descriptor.get('type', None)
        if type_validator is not None:
            if not isinstance(value, type_validator):
                raise ValidationError('wrong type blabla')
        value_validator = field_descriptor.get('validator', None)
        if value_validator is not None:
            if not eval(value_validator, {'value': value}):
                raise ValidationError('wrong value blabla')
    return record


#validating with different schemas

schema0 = {'price': {'type': int, 'validator': 'value and value>45'}}
schema1 = {'price': {
    'type': int, 'validator': '__import__("socket") or value and value>45'}}
schema2 = {'price': {
    'type': int, 'validator': 'int("test.py",x=file("test.py")).read() or value and value>45'}}
schema3 = {'price': {
    'type': int, 'validator': 'open("test.py").read() or value and value>45'}}

print validate({'price': 45}, schema0)
print validate({'price': 46}, schema1)
print validate({'price': 46}, schema2)
print validate({'price': 46}, schema3)