2013-07-01 1 views
10

및 두 가지 모두 유효성 검사에서 단순하지만 우수하지만 두 경우 모두 예외 기반 오류보고를 시도합니다. 즉, 첫 번째 오류가 발생하면 오류가 발생합니다. Voluptuous 또는 Schema에서 데이터의 유효성 검사 오류를 모두 얻을 수있는 방법이 있습니까?첫 번째 실패 대신 모든 유효성 검사 오류를보고하는 간단한 파이썬 유효성 검사 라이브러리?

일부 요구 사항과 일치하는 것으로 보이지만 객체 키 및 맞춤 함수 기반 유효성 검사 (예 : lambdas)에 대한 유효성 검사가 없습니다.

요구 사항 :

def myMethod(input_dict): 

    #input_dict should abide to this schema -> 
    # { 'id' : INT , 'name':'string 5-10 chars','hobbies': LIST OF STRINGS } 
    # for incorrect input like 
    # {'id': 'hello','name':'Dhruv','hobbies':[1,2,3] } 
    # I should be able to return all errors like 
    # ['id' is not integer,'hobbies' is not list of strings ] 
+0

이러한 라이브러리에서 필요한 것을 제공 할 수 있습니까? 유효성 검사가 실패하고 계속 진행하고 실행을 중지하지 않으려는 경우 로깅을위한 작업처럼 들립니다. –

+0

@BurhanKhalid 물론, 메소드의 입력을 검증하고 모든 유효성 검증 오류를 리턴하려고합니다. – DhruvPathak

+0

https://pypi.python.org/pypi/voluptuous#error-reporting은 유효성 검사기가 '유효하지 않은'예외를 발생 시키면이를 캐치하여 경로에 연결한다는 것입니다. 당신이 원하는대로하지 않습니까? (나는 단지 궁금해서, 나는 그것을 사용하지 않았다) – rectummelancolique

답변

1

내가 전에 jsonschema을 사용하고 당신이하고 싶은 일을 정확하게 할 수 있습니다. 원할 경우 예외 기반 오류보고를 수행하지만 문서에서 발견 된 모든 유효성 검사 오류를 반복 할 수도 있습니다. 스키마 (Json Schema V3 Spec 참조)를 사용하여 발견 된 모든 오류를 인쇄하는 간단한 예제 프로그램을 작성했습니다.

편집 : 사용자 지정 유효성 검사기를 사용하도록 스크립트를 변경 했으므로 사용자 지정 유효성 검사를 롤업 할 수 있으며 코드는 설명이 필요합니다. jsonschema 소스를 extend에 올리거나 유효성 검사기를 확장/코딩하는 방법을 찾아 볼 수 있습니다.

#!/usr/bin/env python2 

from jsonschema import Draft3Validator 
from jsonschema.exceptions import ValidationError 
from jsonschema.validators import extend 
import json 
import sys 

schema = { 
    "type": "object", 
    "required": True, 
    "additinalProperties": False, 
    "properties": { 
     "id": { 
      "type": "integer", 
      "required": True 
     }, 
     "name": { 
      "type": "string", 
      "required": True, 
      "minLength": 5, 
      "maxLength": 10 
     }, 
     "hobbies": { 
      "type": "array", 
      "customvalidator": "hobbies", 
      "required": True, 
      "items": { 
       "type": "string" 
      } 
     } 
    } 
} 


def hobbiesValidator(validator, value, instance, schema): 
    if 'Foo' not in instance: 
     yield ValidationError("You need to like Foo") 

    for field in instance: 
     if not validator.is_type(instance, "string"): 
      yield ValidationError("A hobby needs to be a string") 
     elif len(field) < 5: 
      err = "I like only hobbies which are len() >= 5, {} doesn't" 
      yield ValidationError(err.format(value)) 


def anotherHobbiesValidator(validator, value, instance, schema): 
    pass 


myCustomValidators = { 
    'hobbies': hobbiesValidator, 
    'anotherHobbies': anotherHobbiesValidator 
} 


def customValidatorDispatch(validator, value, instance, schema): 
    if value not in myCustomValidators: 
     err = '{} is unknown, we only know about: {}' 
     yield ValidationError(err.format(value, ', '.join(myCustomValidators.keys()))) 
    else: 
     errors = myCustomValidators[value](validator, value, instance, schema) 
     for error in errors: 
      yield error 


def myMethod(input_dict): 
    customValidator = extend(Draft3Validator, {'customvalidator': customValidatorDispatch}, 'MySchema') 
    validator = customValidator(schema) 

    errors = [e for e in validator.iter_errors(input_dict)] 
    if len(errors): 
     return errors 

    # do further processing here 
    return [] 

if __name__ == '__main__': 
    data = None 
    try: 
     f = open(sys.argv[1], 'r') 
     data = json.loads(f.read()) 
    except Exception, e: 
     print "Failed to parse input: {}".format(e) 
     sys.exit(-1) 

    errors = myMethod(data) 

    if not len(errors): 
     print "Input is valid!" 
    else: 
     print "Input is not valid, errors:" 
     for error in errors: 
      print "Err: ", error 

잘못된 입력 :

$ cat invalid-input.json 
{ 
    "id": "hello", 
    "name": "Dhruv", 
    "hobbies": [ 
     1, 2, 3 
    ] 
} 

$ ./validate.py invalid-input.json 
Input is not valid, errors: 
Err: 1 is not of type 'string' 

Failed validating 'type' in schema['properties']['hobbies']['items']: 
    {'type': 'string'} 

On instance['hobbies'][0]: 
    1 
Err: 2 is not of type 'string' 

Failed validating 'type' in schema['properties']['hobbies']['items']: 
    {'type': 'string'} 

On instance['hobbies'][1]: 
    2 
Err: 3 is not of type 'string' 

Failed validating 'type' in schema['properties']['hobbies']['items']: 
    {'type': 'string'} 

On instance['hobbies'][2]: 
    3 
Err: You need to like Foo 

Failed validating 'customvalidator' in schema['properties']['hobbies']: 
    {'customvalidator': 'hobbies', 
    'items': {'type': 'string'}, 
    'required': True, 
    'type': 'array'} 

On instance['hobbies']: 
    [1, 2, 3] 
Err: A hobby needs to be a string 

Failed validating 'customvalidator' in schema['properties']['hobbies']: 
    {'customvalidator': 'hobbies', 
    'items': {'type': 'string'}, 
    'required': True, 
    'type': 'array'} 

On instance['hobbies']: 
    [1, 2, 3] 
Err: A hobby needs to be a string 

Failed validating 'customvalidator' in schema['properties']['hobbies']: 
    {'customvalidator': 'hobbies', 
    'items': {'type': 'string'}, 
    'required': True, 
    'type': 'array'} 

On instance['hobbies']: 
    [1, 2, 3] 
Err: A hobby needs to be a string 

Failed validating 'customvalidator' in schema['properties']['hobbies']: 
    {'customvalidator': 'hobbies', 
    'items': {'type': 'string'}, 
    'required': True, 
    'type': 'array'} 

On instance['hobbies']: 
    [1, 2, 3] 
Err: u'hello' is not of type 'integer' 

Failed validating 'type' in schema['properties']['id']: 
    {'required': True, 'type': 'integer'} 

On instance['id']: 
    u'hello' 

나는 당신의 요구 사항은 지금이 스크립트에 의해 채워진다 생각합니다.

+0

하지만 jsonschema는 "객체 키 및 사용자 정의 함수 기반 유효성 검사 (예 : lambdas)에 대한 유효성 검사가 없습니다"라는 질문에서 언급 한 요구 사항을 충족하지 못합니다. – DhruvPathak

+0

내 코드에 사용자 정의 유효성 검사를 추가 했으므로 이제는 (사용자 자신의 스키마와 유효성 검사기를 롤아웃 할 때) 원하는 것을 수행해야합니다. – Luminger

11

사실 Voluptuous은이 기능을 제공하지만 문서에서는 명확하지 않지만 단순히 MultipleInvalid.errors을 호출합니다. 이 함수는 유효성 검사기에서 catch 된 Invalid 예외 목록을 반환합니다.

try: 

    schema({...}) 

except MultipleInvalid as e: 
    # get the list of all `Invalid` exceptions caught 
    print e.errors 
+0

고마워, 이것을 시도하고 그것이 작동하는지 확인합니다. voluptous가 jsonschema보다 융통성이 있기 때문에 이런 식으로 작동하면 좋을 것입니다. – DhruvPathak

+0

시도해 보셨습니까? :) – chutsu

+0

예, 작동합니다. 감사! – Kevin

관련 문제