def generate_response_validator(api_path, operation_definition, response_definition, path_definition, context): validators = ValidationDict() # Parameters is special cause it needs data from both the # `operation_definition` and the `path_definition` validators.add_validator( "path", generate_path_validator( api_path=api_path, path_definition=path_definition, parameters=operation_definition.get("parameters", []), context=context, ), ) for key in validator_mapping: if key in response_definition: validators.add_validator(key, validator_mapping[key](context=context, **response_definition)) elif key in operation_definition: validators.add_validator(key, validator_mapping[key](context=context, **operation_definition)) elif key in path_definition: validators.add_validator(key, validator_mapping[key](context=context, **path_definition)) if "produces" in context and "produces" not in validators: validators.add_validator("produces", generate_response_content_type_validator(**context)) return functools.partial(validate_object, field_validators=validators)
def generate_response_header_validator(headers, context, **kwargs): validators = ValidationDict() for key, header_definition in headers.items(): # generate a function that will attempt to cast the header to the # appropriate type. header_processor = generate_value_processor( context=context, **header_definition ) # generate a function that will validate the header. header_validator = functools.partial( validate_object, field_validators=construct_header_validators(header_definition, context=context), ) # Chain the type casting function, the individual header validation # function with a methodcaller that will fetch the header with # `response.headers.get(header_name, EMPTY)` and then feed that into # the type casting function and then into the validation function. validators.add_validator(key, chain_reduce_partial( methodcaller('get', key, EMPTY), header_processor, header_validator, )) return chain_reduce_partial( attrgetter('headers'), functools.partial(validate_object, field_validators=validators), )
def generate_response_header_validator(headers, context, **kwargs): validators = ValidationDict() for key, header_definition in headers.items(): # generate a function that will attempt to cast the header to the # appropriate type. header_processor = generate_value_processor( context=context, **header_definition ) # generate a function that will validate the header. header_validator = functools.partial( validate_object, field_validators=construct_header_validators(header_definition, context=context), ) # Chain the type casting function, the individual header validation # function with a methodcaller that will fetch the header with # `response.headers.get(header_name, EMPTY)` and then feed that into # the type casting function and then into the validation function. validators.add_validator(key, chain_reduce_partial( methodcaller('get', key, EMPTY), header_processor, header_validator, )) return chain_reduce_partial( attrgetter('headers'), functools.partial(validate_object, field_validators=validators), )
def construct_schema_validators(schema, context): """ Given a schema object, construct a dictionary of validators needed to validate a response matching the given schema. Special Cases: - $ref: These validators need to be Lazily evaluating so that circular validation dependencies do not result in an infinitely deep validation chain. - properties: These validators are meant to apply to properties of the object being validated rather than the object itself. In this case, we need recurse back into this function to generate a dictionary of validators for the property. """ validators = ValidationDict() if '$ref' in schema: validators.add_validator( '$ref', SchemaReferenceValidator(schema['$ref'], context), ) if 'properties' in schema: for property_, property_schema in schema['properties'].items(): property_validator = generate_object_validator( schema=property_schema, context=context, ) validators.add_property_validator(property_, property_validator) assert 'context' not in schema for key in schema: if key in validator_mapping: validators.add_validator(key, validator_mapping[key](context=context, **schema)) return validators
def construct_schema_validators(schema, context): """ Given a schema object, construct a dictionary of validators needed to validate a response matching the given schema. Special Cases: - $ref: These validators need to be Lazily evaluating so that circular validation dependencies do not result in an infinitely deep validation chain. - properties: These validators are meant to apply to properties of the object being validated rather than the object itself. In this case, we need recurse back into this function to generate a dictionary of validators for the property. """ validators = ValidationDict() if '$ref' in schema: validators.add_validator( '$ref', LazyReferenceValidator(schema['$ref'], context), ) if 'properties' in schema: for property_, property_schema in schema['properties'].items(): property_validator = generate_object_validator( schema=property_schema, context=context, ) validators.add_property_validator(property_, property_validator) assert 'context' not in schema for key in schema: if key in validator_mapping: validators.add_validator( key, validator_mapping[key](context=context, **schema)) return validators
def construct_header_validators(header_definition, context): validators = ValidationDict() for key in header_definition: if key in validator_mapping: validators.add_validator( key, validator_mapping[key](context=context, **header_definition), ) return validators
def generate_response_validator(api_path, operation_definition, response_definition, path_definition, context): validators = ValidationDict() # Parameters is special cause it needs data from both the # `operation_definition` and the `path_definition` validators.add_validator( 'path', generate_path_validator( api_path=api_path, path_definition=path_definition, parameters=operation_definition.get('parameters', []), context=context, )) if '$ref' in response_definition: response_definition = dereference_reference( response_definition['$ref'], context) for key in validator_mapping: if key in response_definition: validators.add_validator( key, validator_mapping[key](context=context, **response_definition), ) elif key in operation_definition: validators.add_validator( key, validator_mapping[key](context=context, **operation_definition), ) elif key in path_definition: validators.add_validator( key, validator_mapping[key](context=context, **path_definition), ) if 'produces' in context and 'produces' not in validators: validators.add_validator( 'produces', generate_response_content_type_validator(**context), ) return functools.partial( validate_object, field_validators=validators, )
def construct_parameter_validators(parameter, context): """ Constructs a dictionary of validator functions for the provided parameter definition. """ validators = ValidationDict() for key in parameter: if key in validator_mapping: validators.add_validator( key, validator_mapping[key](context=context, **parameter), ) if 'schema' in parameter: schema_validators = construct_schema_validators(parameter['schema'], context=context) for key, value in schema_validators.items(): validators.setdefault(key, value) return validators
def construct_multi_parameter_validators(parameters, context): """ Given an iterable of parameters, returns a dictionary of validator functions for each parameter. Note that this expects the parameters to be unique in their name value, and throws an error if this is not the case. """ validators = ValidationDict() for parameter in parameters: key = parameter['name'] if key in validators: raise ValueError("Duplicate parameter name {0}".format(key)) parameter_validators = construct_parameter_validators(parameter, context=context) validators.add_validator( key, generate_object_validator(field_validators=parameter_validators), ) return validators
def construct_multi_parameter_validators(parameters, context): """ Given an iterable of parameters, returns a dictionary of validator functions for each parameter. Note that this expects the parameters to be unique in their name value, and throws an error if this is not the case. """ validators = ValidationDict() for parameter in parameters: key = parameter['name'] if key in validators: raise ValueError("Duplicate parameter name {0}".format(key)) parameter_validators = construct_parameter_validators(parameter, context=context) validators.add_validator( key, generate_object_validator(field_validators=parameter_validators), ) return validators
def generate_response_validator(api_path, operation_definition, response_definition, path_definition, context): validators = ValidationDict() # Parameters is special cause it needs data from both the # `operation_definition` and the `path_definition` validators.add_validator('path', generate_path_validator( api_path=api_path, path_definition=path_definition, parameters=operation_definition.get('parameters', []), context=context, )) if '$ref' in response_definition: response_definition = dereference_reference(response_definition['$ref'], context) for key in validator_mapping: if key in response_definition: validators.add_validator( key, validator_mapping[key](context=context, **response_definition), ) elif key in operation_definition: validators.add_validator( key, validator_mapping[key](context=context, **operation_definition), ) elif key in path_definition: validators.add_validator( key, validator_mapping[key](context=context, **path_definition), ) if 'produces' in context and 'produces' not in validators: validators.add_validator( 'produces', generate_response_content_type_validator(**context), ) return functools.partial( validate_object, field_validators=validators, )
def construct_parameter_validators(parameter, context): """ Constructs a dictionary of validator functions for the provided parameter definition. """ validators = ValidationDict() if '$ref' in parameter: validators.add_validator( '$ref', ParameterReferenceValidator(parameter['$ref'], context), ) for key in parameter: if key in validator_mapping: validators.add_validator( key, validator_mapping[key](context=context, **parameter), ) if 'schema' in parameter: schema_validators = construct_schema_validators(parameter['schema'], context=context) for key, value in schema_validators.items(): validators.setdefault(key, value) return validators
schema_non_field_validators = ValidationDict() schema_non_field_validators.update(common_schema_non_field_validators) schema_validator = generate_object_validator( schema=common_schema_schema, field_validators=schema_field_validators, non_field_validators=schema_non_field_validators, ) # # Properties. # properties_non_field_validators = ValidationDict() properties_non_field_validators.add_validator( 'properties', functools.partial(apply_validator_to_object, validator=schema_validator), ) properties_validator = generate_object_validator( schema=common_properties_schema, non_field_validators=properties_non_field_validators, ) # Now put the properties validator onto the schema validator. schema_field_validators.add_property_validator('properties', properties_validator) # # Items # items_non_field_validators = ValidationList()
schema_field_validators.add_property_validator('format', format_validator) schema_field_validators.add_property_validator('title', title_validator) schema_field_validators.add_property_validator('minProperties', min_properties_validator) schema_field_validators.add_property_validator('maxProperties', max_properties_validator) schema_field_validators.add_property_validator('required', required_validator) schema_field_validators.add_property_validator('type', type_validator) schema_field_validators.add_property_validator('readOnly', read_only_validator) schema_field_validators.add_property_validator('externalDocs', external_docs_validator) schema_non_field_validators = ValidationDict() schema_non_field_validators.update(common_non_field_validators) schema_non_field_validators.update(common_type_validators) schema_non_field_validators.add_validator( 'default', validate_default_is_of_one_of_declared_types, ) schema_non_field_validators.add_validator( 'maxProperties', validate_max_properties_is_greater_than_or_equal_to_min_properties, ) schema_non_field_validators.add_validator( 'type', validate_type_for_min_properties, ) schema_non_field_validators.add_validator( 'type', validate_type_for_max_properties, ) # # Properties. #
schema_field_validators.add_property_validator('format', format_validator) schema_field_validators.add_property_validator('title', title_validator) schema_field_validators.add_property_validator('minProperties', min_properties_validator) schema_field_validators.add_property_validator('maxProperties', max_properties_validator) schema_field_validators.add_property_validator('required', required_validator) schema_field_validators.add_property_validator('type', type_validator) schema_field_validators.add_property_validator('readOnly', read_only_validator) schema_field_validators.add_property_validator('externalDocs', external_docs_validator) schema_non_field_validators = ValidationDict() schema_non_field_validators.update(common_non_field_validators) schema_non_field_validators.update(common_type_validators) schema_non_field_validators.add_validator( 'default', validate_default_is_of_one_of_declared_types, ) schema_non_field_validators.add_validator( 'maxProperties', validate_max_properties_is_greater_than_or_equal_to_min_properties, ) schema_non_field_validators.add_validator( 'type', validate_type_for_min_properties, ) schema_non_field_validators.add_validator( 'type', validate_type_for_max_properties, ) # # Properties. #
def generate_parameters_validator(api_path, path_definition, parameters, context, **kwargs): """ Generates a validator function to validate. - request.path against the path parameters. - request.query against the query parameters. - request.headers against the header parameters. - TODO: request.body against the body parameters. - TODO: request.formData against any form data. """ # TODO: figure out how to merge this with the same code in response # validation. validators = ValidationDict() path_level_parameters = dereference_parameter_list( path_definition.get('parameters', []), context, ) operation_level_parameters = dereference_parameter_list( parameters, context, ) all_parameters = merge_parameter_lists( path_level_parameters, operation_level_parameters, ) # PATH in_path_parameters = filter_parameters(all_parameters, in_=PATH) validators.add_validator( 'path', chain_reduce_partial( operator.attrgetter('path'), generate_path_parameters_validator(api_path, in_path_parameters, context), ), ) # QUERY in_query_parameters = filter_parameters(all_parameters, in_=QUERY) validators.add_validator( 'query', chain_reduce_partial( operator.attrgetter('query_data'), functools.partial( validate_query_parameters, query_parameters=in_query_parameters, context=context, ), ), ) # HEADERS in_header_parameters = filter_parameters(all_parameters, in_=HEADER) validators.add_validator( 'headers', chain_reduce_partial( operator.attrgetter('headers'), generate_header_validator(in_header_parameters, context), ), ) # FORM_DATA # in_form_data_parameters = filter_parameters(all_parameters, in_=FORM_DATA) # validators.add_validator( # 'form_data', # chain_reduce_partial( # operator.attrgetter('data'), # generate_form_data_validator(in_form_data_parameters, context), # ) # ) # REQUEST_BODY in_request_body_parameters = filter_parameters(all_parameters, in_=BODY) validators.add_validator( 'request_body', chain_reduce_partial( operator.attrgetter('data'), generate_request_body_validator(in_request_body_parameters, context), )) return generate_object_validator(field_validators=validators)
if parts.path: from flex.core import load_source if parts.path.startswith('/'): schema = load_source(parts.path) elif 'base_path' in kwargs: schema = load_source( os.path.join(kwargs['base_path'], parts.path)) try: jsonpointer.resolve_pointer(schema, parts.fragment) except jsonpointer.JsonPointerException: errors.add_error( reference, MESSAGES['reference']['undefined'].format(reference), ) field_validators = ValidationDict() field_validators.add_property_validator('parameters', parameters_validator) field_validators.add_property_validator('responses', responses_validator) field_validators.add_property_validator('definitions', schema_definitions_validator) non_field_validators = ValidationDict() non_field_validators.add_validator('definitions', validate_deferred_references) definitions_validator = generate_object_validator( schema=definitions_schema, field_validators=field_validators, non_field_validators=non_field_validators, )
'collectionFormat', collection_format_validator, ) @pull_keys_from_obj('type', 'items') @suffix_reserved_words def validate_items_required_if_type_arraw(type_, items, **kwargs): types = pluralize(type_) if ARRAY in types and items is EMPTY: raise ValidationError(MESSAGES['required']['required']) single_header_non_field_validators = ValidationDict() single_header_non_field_validators.update(common_non_field_validators) single_header_non_field_validators.update(common_type_validators) single_header_non_field_validators.add_validator( 'default', validate_default_is_of_one_of_declared_types, ) single_header_non_field_validators.add_validator( 'items', validate_items_required_if_type_arraw, ) single_header_validator = generate_object_validator( schema=single_header_schema, field_validators=single_header_field_validators, non_field_validators=single_header_non_field_validators, )
def generate_parameters_validator(api_path, path_definition, parameters, context, **kwargs): """ Generates a validator function to validate. - request.path against the path parameters. - request.query against the query parameters. - request.headers against the header parameters. - TODO: request.body against the body parameters. - TODO: request.formData against any form data. """ # TODO: figure out how to merge this with the same code in response # validation. validators = ValidationDict() path_level_parameters = dereference_parameter_list( path_definition.get('parameters', []), context, ) operation_level_parameters = dereference_parameter_list( parameters, context, ) all_parameters = merge_parameter_lists( path_level_parameters, operation_level_parameters, ) # PATH in_path_parameters = filter_parameters(all_parameters, in_=PATH) validators.add_validator( 'path', chain_reduce_partial( attrgetter('path'), generate_path_parameters_validator(api_path, in_path_parameters, context), ), ) # QUERY in_query_parameters = filter_parameters(all_parameters, in_=QUERY) validators.add_validator( 'query', chain_reduce_partial( attrgetter('query_data'), functools.partial( validate_query_parameters, query_parameters=in_query_parameters, context=context, ), ), ) # HEADERS in_header_parameters = filter_parameters(all_parameters, in_=HEADER) validators.add_validator( 'headers', chain_reduce_partial( attrgetter('headers'), generate_header_validator(in_header_parameters, context), ), ) # FORM_DATA # in_form_data_parameters = filter_parameters(all_parameters, in_=FORM_DATA) # validators.add_validator( # 'form_data', # chain_reduce_partial( # attrgetter('data'), # generate_form_data_validator(in_form_data_parameters, context), # ) # ) # REQUEST_BODY in_request_body_parameters = filter_parameters(all_parameters, in_=BODY) validators.add_validator( 'request_body', chain_reduce_partial( attrgetter('data'), generate_request_body_validator(in_request_body_parameters, context), ) ) return generate_object_validator(field_validators=validators)
single_header_field_validators.add_property_validator('type', type_validator) single_header_field_validators.add_property_validator('format', format_validator) single_header_field_validators.add_property_validator( 'collectionFormat', collection_format_validator, ) @pull_keys_from_obj('type', 'items') @suffix_reserved_words def validate_items_required_if_type_arraw(type_, items, **kwargs): types = pluralize(type_) if ARRAY in types and items is EMPTY: raise ValidationError(MESSAGES['required']['required']) single_header_non_field_validators = ValidationDict() single_header_non_field_validators.update(common_non_field_validators) single_header_non_field_validators.update(common_type_validators) single_header_non_field_validators.add_validator( 'default', validate_default_is_of_one_of_declared_types, ) single_header_non_field_validators.add_validator( 'items', validate_items_required_if_type_arraw, ) single_header_validator = generate_object_validator( schema=single_header_schema, field_validators=single_header_field_validators, non_field_validators=single_header_non_field_validators, )
single_parameter_field_validators.add_property_validator( 'required', required_validator) single_parameter_field_validators.add_property_validator( 'type', type_validator) single_parameter_field_validators.add_property_validator( 'format', format_validator) single_parameter_field_validators.add_property_validator( 'collectionFormat', collection_format_validator, ) single_parameter_non_field_validators = ValidationDict() single_parameter_non_field_validators.update(common_non_field_validators) single_parameter_non_field_validators.update(common_type_validators) single_parameter_non_field_validators.add_validator( 'default', validate_default_is_of_one_of_declared_types, ) single_parameter_non_field_validators.add_validator( 'required', validate_path_parameters_must_be_required, ) single_parameter_non_field_validators.add_validator( 'schema', validate_body_parameters_must_include_a_schema, ) single_parameter_non_field_validators.add_validator( 'type', validate_type_declared_for_non_body_parameters, ) single_parameter_non_field_validators.add_validator( 'collectionFormat',
parts = urlparse.urlparse(reference) if any((parts.scheme, parts.netloc, parts.path, parts.params, parts.query)): errors.add_error( reference, MESSAGES['reference']['unsupported'].format(reference), ) continue try: jsonpointer.resolve_pointer(schema, parts.fragment) except jsonpointer.JsonPointerException: errors.add_error( reference, MESSAGES['reference']['undefined'].format(reference), ) field_validators = ValidationDict() field_validators.add_property_validator('parameters', parameters_validator) field_validators.add_property_validator('responses', responses_validator) field_validators.add_property_validator('definitions', schema_definitions_validator) non_field_validators = ValidationDict() non_field_validators.add_validator('definitions', validate_deferred_references) definitions_validator = generate_object_validator( schema=definitions_schema, field_validators=field_validators, non_field_validators=non_field_validators, )
field_validators.add_property_validator('maximum', maximum_validator) field_validators.add_property_validator('exclusiveMinimum', exclusive_minimum_validator) field_validators.add_property_validator('exclusiveMaximum', exclusive_maximum_validator) field_validators.add_property_validator('minLength', min_length_validator) field_validators.add_property_validator('maxLength', max_length_validator) field_validators.add_property_validator('pattern', pattern_validator) field_validators.add_property_validator('minItems', min_items_validator) field_validators.add_property_validator('maxItems', max_items_validator) field_validators.add_property_validator('uniqueItems', unique_items_validator) field_validators.add_property_validator('enum', enum_validator) non_field_validators = ValidationDict() non_field_validators.add_validator( 'maximum', validate_maximum_is_gte_minimum, ) non_field_validators.add_validator( 'maximum', validate_maximum_required_if_exclusive_maximum_set, ) non_field_validators.add_validator( 'minimum', validate_minimum_required_if_exclusive_minimum_set, ) non_field_validators.add_validator( 'maxLength', validate_max_length_greater_than_or_equal_to_min_length, ) non_field_validators.add_validator( 'maxItems', validate_max_items_greater_than_or_equal_to_min_items, )
single_parameter_field_validators.add_property_validator('in', in_validator) single_parameter_field_validators.add_property_validator('name', name_validator) single_parameter_field_validators.add_property_validator('description', description_validator) single_parameter_field_validators.add_property_validator('required', required_validator) single_parameter_field_validators.add_property_validator('type', type_validator) single_parameter_field_validators.add_property_validator('format', format_validator) single_parameter_field_validators.add_property_validator( 'collectionFormat', collection_format_validator, ) single_parameter_non_field_validators = ValidationDict() single_parameter_non_field_validators.update(common_non_field_validators) single_parameter_non_field_validators.update(common_type_validators) single_parameter_non_field_validators.add_validator( 'default', validate_default_is_of_one_of_declared_types, ) single_parameter_non_field_validators.add_validator( 'required', validate_path_parameters_must_be_required, ) single_parameter_non_field_validators.add_validator( 'schema', validate_body_parameters_must_include_a_schema, ) single_parameter_non_field_validators.add_validator( 'type', validate_type_declared_for_non_body_parameters, ) single_parameter_non_field_validators.add_validator( 'collectionFormat', validate_collection_format_based_on_in_value, ) single_parameter_non_field_validators.add_validator( 'items', validate_items_required_if_array_type,
schema_non_field_validators.update(common_schema_non_field_validators) schema_validator = generate_object_validator( schema=common_schema_schema, field_validators=schema_field_validators, non_field_validators=schema_non_field_validators, ) # # Properties. # properties_non_field_validators = ValidationDict() properties_non_field_validators.add_validator( 'properties', functools.partial(apply_validator_to_object, validator=schema_validator), ) properties_validator = generate_object_validator( schema=common_properties_schema, non_field_validators=properties_non_field_validators, ) # Now put the properties validator onto the schema validator. schema_field_validators.add_property_validator('properties', properties_validator) # # Items # items_non_field_validators = ValidationList()