def test_raise(empty_swagger_spec): spec = { 'type': 'integer', } with pytest.raises(SwaggerMappingError): handle_null_value(empty_swagger_spec, spec)
def test_nullable(empty_swagger_spec): spec = { 'type': 'integer', 'x-nullable': True, } assert None is handle_null_value(empty_swagger_spec, spec)
def marshal_array(swagger_spec, array_spec, array_value): """Marshal a jsonschema type of 'array' into a json-like list. :type swagger_spec: :class:`bravado_core.spec.Spec` :type array_spec: dict :type array_value: list :rtype: list :raises: SwaggerMappingError """ if array_value is None: return handle_null_value(swagger_spec, array_spec) if not is_list_like(array_value): raise SwaggerMappingError('Expected list like type for {0}: {1}' .format(type(array_value), array_value)) items_spec = swagger_spec.deref(array_spec).get('items') return [ marshal_schema_object( swagger_spec, items_spec, element) for element in array_value ]
def marshal_model(swagger_spec, model_spec, model_value): """Marshal a Model instance into a json-like dict. :type swagger_spec: :class:`bravado_core.spec.Spec` :type model_spec: dict :type model_value: Model instance :rtype: dict :raises: SwaggerMappingError """ deref = swagger_spec.deref model_name = deref(model_spec).get(MODEL_MARKER) model_type = swagger_spec.definitions.get(model_name, None) if model_type is None: raise SwaggerMappingError('Unknown model {0}'.format(model_name)) if model_value is None: return handle_null_value(swagger_spec, model_spec) if not isinstance(model_value, Model): raise SwaggerMappingError( 'Expected {0.__module__}.{0.__name__} object but got {1.__module__}.{1.__name__}'.format( Model, type(model_value), ), ) # just convert the model to a dict and feed into `marshal_object` because # models are essentially 'type':'object' when marshaled object_value = model_value._as_dict() return marshal_object(swagger_spec, model_spec, object_value)
def test_default(empty_swagger_spec): spec = { 'type': 'integer', 'default': 42 } assert 42 == handle_null_value(empty_swagger_spec, spec)
def marshal_model(swagger_spec, model_spec, model_value): """Marshal a Model instance into a json-like dict. :type swagger_spec: :class:`bravado_core.spec.Spec` :type model_spec: dict :type model_value: Model instance :rtype: dict :raises: SwaggerMappingError """ deref = swagger_spec.deref model_name = deref(model_spec).get(MODEL_MARKER) model_type = swagger_spec.definitions.get(model_name, None) if model_type is None: raise SwaggerMappingError('Unknown model {0}'.format(model_name)) if model_value is None: return handle_null_value(swagger_spec, model_spec) if not isinstance(model_value, model_type): raise SwaggerMappingError( 'Expected model of type {0} for {1}:{2}' .format(model_name, type(model_value), model_value)) # just convert the model to a dict and feed into `marshal_object` because # models are essentially 'type':'object' when marshaled attr_names = dir(model_value) object_value = dict( (attr_name, getattr(model_value, attr_name)) for attr_name in attr_names) return marshal_object(swagger_spec, model_spec, object_value)
def marshal_model(swagger_spec, model_spec, model_value): """Marshal a Model instance into a json-like dict. :type swagger_spec: :class:`bravado_core.spec.Spec` :type model_spec: dict :type model_value: Model instance :rtype: dict :raises: SwaggerMappingError """ deref = swagger_spec.deref model_name = deref(model_spec).get(MODEL_MARKER) model_type = swagger_spec.definitions.get(model_name, None) if model_type is None: raise SwaggerMappingError('Unknown model {0}'.format(model_name)) if model_value is None: return handle_null_value(swagger_spec, model_spec) if not model_type._isinstance(model_value): raise SwaggerMappingError( 'Expected model of type {0} for {1}:{2}' .format(model_name, type(model_value), model_value)) # just convert the model to a dict and feed into `marshal_object` because # models are essentially 'type':'object' when marshaled object_value = model_value._as_dict() return marshal_object(swagger_spec, model_spec, object_value)
def unmarshal_model(swagger_spec, model_spec, model_value): """Unmarshal a dict into a Model instance. :type swagger_spec: :class:`bravado_core.spec.Spec` :type model_spec: dict :type model_value: dict :rtype: Model instance :raises: SwaggerMappingError """ deref = swagger_spec.deref model_name = deref(model_spec).get(MODEL_MARKER) model_type = swagger_spec.definitions.get(model_name, None) if model_type is None: raise SwaggerMappingError( 'Unknown model {0} when trying to unmarshal {1}' .format(model_name, model_value)) if model_value is None: return handle_null_value(swagger_spec, model_spec) if not is_dict_like(model_value): raise SwaggerMappingError( "Expected type to be dict for value {0} to unmarshal to a {1}." "Was {1} instead." .format(model_value, model_type, type(model_value))) model_as_dict = unmarshal_object(swagger_spec, model_spec, model_value) model_instance = model_type(**model_as_dict) return model_instance
def test_default(empty_swagger_spec): spec = { 'type': 'integer', 'default': 42, } assert 42 == handle_null_value(empty_swagger_spec, spec)
def unmarshal_collection_format(swagger_spec, param_spec, value): """For a non-body parameter of type array, unmarshal the value into an array of elements. Input: param_spec = { 'name': 'status' 'in': 'query', 'collectionFormat': 'psv', # pipe separated value 'type': 'array', 'items': { 'type': 'string', } } value="pending|completed|started" Output: ['pending', 'completed', 'started'] :type swagger_spec: :class:`bravado_core.spec.Spec` :param param_spec: param_spec of the parameter with 'type': 'array' :type param_spec: dict :param value: parameter value :type value: string :rtype: list """ deref = swagger_spec.deref param_spec = deref(param_spec) collection_format = param_spec.get('collectionFormat', 'csv') if value is None: if not schema.is_required(swagger_spec, param_spec): # Just pass through an optional array that has no value return None return schema.handle_null_value(swagger_spec, param_spec) if schema.is_list_like(value): value_array = value elif collection_format == 'multi': # http client lib should have already unmarshalled the value value_array = [value] else: sep = COLLECTION_FORMATS[collection_format] if value == '': value_array = [] else: value_array = value.split(sep) items_spec = param_spec['items'] items_type = deref(items_spec).get('type') param_name = param_spec['name'] return [ cast_request_param(items_type, param_name, item) for item in value_array ]
def unmarshal_collection_format(swagger_spec, param_spec, value): """For a non-body parameter of type array, unmarshal the value into an array of elements. Input: param_spec = { 'name': 'status' 'in': 'query', 'collectionFormat': 'psv', # pipe separated value 'type': 'array', 'items': { 'type': 'string', } } value="pending|completed|started" Output: ['pending', 'completed', 'started'] :type swagger_spec: :class:`bravado_core.spec.Spec` :param param_spec: param_spec of the parameter with 'type': 'array' :type param_spec: dict :param value: parameter value :type value: string :rtype: list """ deref = swagger_spec.deref param_spec = deref(param_spec) collection_format = param_spec.get('collectionFormat', 'csv') if value is None: if not schema.is_required(swagger_spec, param_spec): # Just pass through an optional array that has no value return None return schema.handle_null_value(swagger_spec, param_spec) if schema.is_list_like(value): value_array = value elif collection_format == 'multi': # http client lib should have already unmarshaled the value value_array = [value] else: sep = COLLECTION_FORMATS[collection_format] if value == '': value_array = [] else: value_array = value.split(sep) items_spec = param_spec['items'] items_type = deref(items_spec).get('type') param_name = param_spec['name'] return [ cast_request_param(items_type, param_name, item) for item in value_array ]
def unmarshal_object(swagger_spec, object_spec, object_value): """Unmarshal a jsonschema type of 'object' into a python dict. :type swagger_spec: :class:`bravado_core.spec.Spec` :type object_spec: dict :type object_value: dict :rtype: dict :raises: SwaggerMappingError """ deref = swagger_spec.deref if object_value is None: return handle_null_value(swagger_spec, object_spec) if not is_dict_like(object_value): raise SwaggerMappingError('Expected dict like type for {0}:{1}'.format( type(object_value), object_value)) object_spec = deref(object_spec) required_fields = object_spec.get('required', []) result = {} for k, v in iteritems(object_value): prop_spec = get_spec_for_prop(swagger_spec, object_spec, object_value, k) if v is None and k not in required_fields and prop_spec: if schema.has_default(swagger_spec, prop_spec): result[k] = schema.get_default(swagger_spec, prop_spec) else: result[k] = None elif prop_spec: # Zohar: Ugly hack to fix handling of unicode type, which were recognized as objects if type(v) == type(u''): result[k] = unmarshal_primitive(swagger_spec, prop_spec, v) # elif type(v) == type(list()): # result[k] = unmarshal_array(swagger_spec, prop_spec, v) else: result[k] = unmarshal_schema_object(swagger_spec, prop_spec, v) else: # Don't marshal when a spec is not available - just pass through result[k] = v properties = collapsed_properties(deref(object_spec), swagger_spec) for prop_name, prop_spec in iteritems(properties): if prop_name not in result and swagger_spec.config[ 'include_missing_properties']: result[prop_name] = None if schema.has_default(swagger_spec, prop_spec): result[prop_name] = schema.get_default(swagger_spec, prop_spec) return result
def unmarshal_primitive(swagger_spec, primitive_spec, value): """Unmarshal a jsonschema primitive type into a python primitive. :type swagger_spec: :class:`bravado_core.spec.Spec` :type primitive_spec: dict :type value: int, long, float, boolean, string, unicode, etc :rtype: int, long, float, boolean, string, unicode, or an object based on 'format' :raises: SwaggerMappingError """ if value is None: return handle_null_value(swagger_spec, primitive_spec) value = formatter.to_python(swagger_spec, primitive_spec, value) return value
def unmarshal_object(swagger_spec, object_spec, object_value): """Unmarshal a jsonschema type of 'object' into a python dict. :type swagger_spec: :class:`bravado_core.spec.Spec` :type object_spec: dict :type object_value: dict :rtype: dict :raises: SwaggerMappingError """ deref = swagger_spec.deref if object_value is None: return handle_null_value(swagger_spec, object_spec) if not is_dict_like(object_value): raise SwaggerMappingError('Expected dict like type for {0}:{1}'.format( type(object_value), object_value)) object_spec = deref(object_spec) required_fields = object_spec.get('required', []) properties = collapsed_properties(object_spec, swagger_spec) result = {} for k, v in iteritems(object_value): prop_spec = get_spec_for_prop( swagger_spec, object_spec, object_value, k, properties) if v is None and k not in required_fields and prop_spec: if schema.has_default(swagger_spec, prop_spec): result[k] = schema.get_default(swagger_spec, prop_spec) else: result[k] = None elif prop_spec: result[k] = unmarshal_schema_object(swagger_spec, prop_spec, v) else: # Don't marshal when a spec is not available - just pass through result[k] = v for prop_name, prop_spec in iteritems(properties): if prop_name not in result and swagger_spec.config['include_missing_properties']: result[prop_name] = None if schema.has_default(swagger_spec, prop_spec): result[prop_name] = schema.get_default(swagger_spec, prop_spec) return result
def unmarshal_model(swagger_spec, model_spec, model_value): """Unmarshal a dict into a Model instance. :type swagger_spec: :class:`bravado_core.spec.Spec` :type model_spec: dict :type model_value: dict :rtype: Model instance :raises: SwaggerMappingError """ deref = swagger_spec.deref model_name = deref(model_spec).get(MODEL_MARKER) model_type = swagger_spec.definitions.get(model_name, None) if model_type is None: raise SwaggerMappingError( 'Unknown model {0} when trying to unmarshal {1}' .format(model_name, model_value)) if model_value is None: return handle_null_value(swagger_spec, model_spec) if not is_dict_like(model_value): raise SwaggerMappingError( "Expected type to be dict for value {0} to unmarshal to a {1}." "Was {2} instead." .format(model_value, model_type, type(model_value))) # Check if model is polymorphic discriminator = model_spec.get('discriminator') if discriminator is not None: child_model_name = model_value.get(discriminator, None) if child_model_name not in swagger_spec.definitions: raise SwaggerMappingError( 'Unknown model {0} when trying to unmarshal {1}. ' 'Value of {2}\'s discriminator {3} did not match any definitions.' .format(child_model_name, model_value, model_name, discriminator) ) model_type = swagger_spec.definitions.get(child_model_name) model_spec = model_type._model_spec model_as_dict = unmarshal_object(swagger_spec, model_spec, model_value) model_instance = model_type._from_dict(model_as_dict) return model_instance
def unmarshal_model(swagger_spec, model_spec, model_value): """Unmarshal a dict into a Model instance. :type swagger_spec: :class:`bravado_core.spec.Spec` :type model_spec: dict :type model_value: dict :rtype: Model instance :raises: SwaggerMappingError """ deref = swagger_spec.deref model_name = deref(model_spec).get(MODEL_MARKER) model_type = swagger_spec.definitions.get(model_name, None) if model_type is None: raise SwaggerMappingError( 'Unknown model {0} when trying to unmarshal {1}'.format( model_name, model_value)) if model_value is None: return handle_null_value(swagger_spec, model_spec) if not is_dict_like(model_value): raise SwaggerMappingError( "Expected type to be dict for value {0} to unmarshal to a {1}." "Was {2} instead.".format(model_value, model_type, type(model_value))) # Check if model is polymorphic discriminator = model_spec.get('discriminator') if discriminator is not None: child_model_name = model_value.get(discriminator, None) if child_model_name not in swagger_spec.definitions: raise SwaggerMappingError( 'Unknown model {0} when trying to unmarshal {1}. ' 'Value of {2}\'s discriminator {3} did not match any definitions.' .format(child_model_name, model_value, model_name, discriminator)) model_type = swagger_spec.definitions.get(child_model_name) model_spec = model_type._model_spec model_as_dict = unmarshal_object(swagger_spec, model_spec, model_value) model_instance = model_type._from_dict(model_as_dict) return model_instance
def marshal_object(swagger_spec, object_spec, object_value): """Marshal a python dict to json dict. :type swagger_spec: :class:`bravado_core.spec.Spec` :type object_spec: dict :type object_value: dict :rtype: dict :raises: SwaggerMappingError """ deref = swagger_spec.deref if object_value is None: return handle_null_value(swagger_spec, object_spec) if not is_dict_like(object_value): raise SwaggerMappingError('Expected dict like type for {0}:{1}'.format( type(object_value), object_value)) object_spec = deref(object_spec) required_fields = object_spec.get('required', []) properties = collapsed_properties(object_spec, swagger_spec) result = {} for k, v in iteritems(object_value): prop_spec = get_spec_for_prop( swagger_spec, object_spec, object_value, k, properties) if not prop_spec: # Don't marshal when a spec is not available - just pass through result[k] = v continue if v is None and k not in required_fields: if not is_prop_nullable(swagger_spec, prop_spec): continue result[k] = marshal_schema_object(swagger_spec, prop_spec, v) return result
def unmarshal_object(swagger_spec, object_spec, object_value): """Unmarshal a jsonschema type of 'object' into a python dict. :type swagger_spec: :class:`bravado_core.spec.Spec` :type object_spec: dict :type object_value: dict :rtype: dict :raises: SwaggerMappingError """ deref = swagger_spec.deref if object_value is None: return handle_null_value(swagger_spec, object_spec) if not is_dict_like(object_value): raise SwaggerMappingError('Expected dict like type for {0}:{1}'.format( type(object_value), object_value)) object_spec = deref(object_spec) required_fields = object_spec.get('required', []) result = {} for k, v in iteritems(object_value): prop_spec = get_spec_for_prop( swagger_spec, object_spec, object_value, k) if v is None and k not in required_fields: result[k] = None elif prop_spec: result[k] = unmarshal_schema_object(swagger_spec, prop_spec, v) else: # Don't marshal when a spec is not available - just pass through result[k] = v # re-introduce and None'ify any properties that weren't passed properties = deref(object_spec).get('properties', {}) for prop_name, prop_spec in iteritems(properties): if prop_name not in result: result[prop_name] = None return result
def marshal_primitive(swagger_spec, primitive_spec, value): """Marshal a python primitive type into a jsonschema primitive. :type swagger_spec: :class:`bravado_core.spec.Spec` :type primitive_spec: dict :type value: int, long, float, boolean, string, unicode, or an object based on 'format' :rtype: int, long, float, boolean, string, unicode, etc :raises: SwaggerMappingError """ default_used = False if value is None and schema.has_default(swagger_spec, primitive_spec): default_used = True value = schema.get_default(swagger_spec, primitive_spec) if value is None: return handle_null_value(swagger_spec, primitive_spec) if not default_used: value = formatter.to_wire(swagger_spec, primitive_spec, value) return value