def print_spec(spec, level=0): indent = '\t' * level if is_dict_like(spec): for k, v in spec.items(): print(indent + k + ':') if is_dict_like(v): print('{') print_spec(v, level + 1) print(indent + '}') elif is_list_like(v): print(' [') print_spec(v, level + 1) print(indent + ']') else: print(str(v) + ', ') elif is_list_like(spec): for element in spec: if is_list_like(element): print(' [') print_spec(element, level + 1) print(indent + ']') elif is_dict_like(element): print(indent + '{') print_spec(element, level + 1) print(indent + '},') else: print_spec(element, level + 1) else: print(indent + str(spec) + ', ')
def print_spec(spec, level=0): indent = '\t' * level if is_dict_like(spec): for k, v in spec.iteritems(): print indent + k + ':', if is_dict_like(v): print '{' print_spec(v, level + 1) print indent + '}' elif is_list_like(v): print ' [' print_spec(v, level + 1) print indent + ']' else: print str(v) + ', ' elif is_list_like(spec): for element in spec: if is_list_like(element): print ' [' print_spec(element, level + 1) print indent + ']' elif is_dict_like(element): print indent + '{' print_spec(element, level + 1) print indent + '},' else: print_spec(element, level + 1) else: print indent + str(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 descend(fragment, path, visited_refs): if is_ref(fragment): ref_dict = fragment ref = fragment['$ref'] attach_scope(ref_dict, resolver) # Don't recurse down already visited refs. A ref is not unique # by its name alone. Its scope (attached above) is part of the # equivalence comparison. if ref_dict in visited_refs: log.debug('Already visited %s' % ref) return visited_refs.append(ref_dict) with resolver.resolving(ref) as target: descend(target, path, visited_refs) return # fragment is guaranteed not to be a ref from this point onwards if is_dict_like(fragment): if 'type' not in fragment: if 'properties' in fragment: fragment['type'] = 'object' elif 'items' in fragment: fragment['type'] = 'array' for key, value in iteritems(fragment): fire_callbacks(fragment, key, path + [key]) descend(fragment[key], path + [key], visited_refs) elif is_list_like(fragment): for index in range(len(fragment)): fire_callbacks(fragment, index, path + [str(index)]) descend(fragment[index], path + [str(index)], visited_refs)
def _as_dict(self, additional_properties=True, recursive=True): """Get property values as dictionary. :param bool additional_properties: Whether to include additional properties set on the instance but not defined in the spec. :param bool recursive: Whether to convert all property values which are themselves models to dicts as well. :rtype: dict """ dct = dict() for attr_name, attr_val in iteritems(self.__dict): if attr_name not in self._properties and not additional_properties: continue if recursive: is_list = is_list_like(attr_val) attribute = attr_val if is_list else [attr_val] new_attr_val = [] for attr in attribute: if isinstance(attr, Model): attr = attr._as_dict( additional_properties=additional_properties, recursive=recursive, ) new_attr_val.append(attr) attr_val = new_attr_val if is_list else new_attr_val[0] dct[attr_name] = attr_val return dct
def descend(fragment): if is_dict_like(fragment): fragment.pop('x-model', None) # Removes 'x-model' key if present for key in iterkeys(fragment): descend(fragment[key]) elif is_list_like(fragment): for element in fragment: descend(element)
def descend(fragment): if is_dict_like(fragment): for k, v in iteritems(fragment): if k == '$ref' and v in model_names: fragment[k] = "#/definitions/{0}".format(v) descend(v) elif is_list_like(fragment): for element in fragment: descend(element)
def descend(fragment): if is_dict_like(fragment): for k, v in fragment.items(): if isinstance(v, jsonref.JsonRef): fragment[k] = v.__subject__ descend(fragment[k]) elif is_list_like(fragment): for element in fragment: descend(element)
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 descend(fragment): if is_dict_like(fragment): for key in fragment: fire_callbacks(fragment, key) descend(fragment[key]) elif is_list_like(fragment): for index in range(len(fragment)): fire_callbacks(fragment, index) descend(fragment[index])
def descend(fragment): if is_dict_like(fragment): for key in list(fragment.keys()): if key == 'x-scope': del fragment['x-scope'] else: descend(fragment[key]) elif is_list_like(fragment): for element in fragment: descend(element)
def descend(fragment): if is_dict_like(fragment): for k, v in iteritems(fragment): if isinstance(v, jsonref.JsonRef): fragment[k] = v.__subject__ descend(fragment[k]) elif is_list_like(fragment): for index, element in enumerate(fragment): if isinstance(element, jsonref.JsonRef): fragment[index] = element.__subject__ descend(element)
def _equivalent(spec, obj1, obj2): if is_dict_like(obj1) != is_dict_like(obj2) or is_list_like(obj1) != is_list_like(obj2): return False if is_dict_like(obj1): if len(obj1) != len(obj2): return False for key in iterkeys(obj1): if key not in obj2: return False return _equivalent(spec, spec._force_deref(obj1[key]), spec._force_deref(obj2[key])) elif is_list_like(obj1): if len(obj1) != len(obj2): return False for key in range(len(obj1)): return _equivalent(spec, spec._force_deref(obj1[key]), spec._force_deref(obj2[key])) else: return obj1 == obj2
def prepare_params( self, params: Optional[Dict[str, Any]] ) -> Union[Optional[Dict[str, Any]], MultiDict]: if not params: return params items = [] for key, value in params.items(): entries = ([(key, str(value))] if not is_list_like(value) else [(key, str(v)) for v in value]) items.extend(entries) return MultiDict(items)
def _marshal_array(marshal_array_item_function, value): # type: (MarshalingMethod, typing.Any) -> typing.Any """ Marshal a python list to its JSON list representation. :param marshal_array_item_function: Marshaling function for each array item :param value: Python list/tuple to marshal as JSON Array :raises: SwaggerMappingError """ if not is_list_like(value): raise SwaggerMappingError('Expected list like type for {0}:{1}'.format( type(value), value)) return [marshal_array_item_function(item) for item in value]
def _unmarshal_array(unmarshal_array_item_function, value): # type: (UnmarshalingMethod, typing.Any) -> typing.Any """ Unmarshal a JSON list to its python representation. :param unmarshal_array_item_function: Unmarshaling function for each array item :param value: JSON value to unmarshal :raises: SwaggerMappingError """ if not is_list_like(value): raise SwaggerMappingError('Expected list like type for {0}:{1}'.format( type(value), value)) return [unmarshal_array_item_function(item) for item in value]
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 or jsonref.JsonRef :type array_value: list :rtype: list :raises: SwaggerMappingError """ if not is_list_like(array_value): raise SwaggerMappingError("Expected list like type for {0}:{1}".format(type(array_value), array_value)) result = [] for element in array_value: result.append(marshal_schema_object(swagger_spec, array_spec["items"], element)) return result
def unmarshal_array(swagger_spec, array_spec, array_value): """Unmarshal a jsonschema type of 'array' into a python list. :type swagger_spec: :class:`bravado_core.spec.Spec` :type array_spec: dict or jsonref.JsonRef :type array_value: list :rtype: list :raises: TypeError """ if not is_list_like(array_value): raise TypeError('Expected list like type for {0}:{1}'.format( type(array_value), array_value)) result = [] for element in array_value: result.append(unmarshal_schema_object( swagger_spec, array_spec['items'], element)) return result
def descend(obj): # Inline modification of obj # This method is needed because JsonRef could produce performance penalties in accessing # the proxied attributes if isinstance(obj, JsonRef): # Extract the proxied value # http://jsonref.readthedocs.io/en/latest/#jsonref.JsonRef.__subject__ return obj.__subject__ if is_dict_like(obj): for key in list(iterkeys(obj)): obj[key] = descend(obj[key]) elif is_list_like(obj): # obj is list like object provided from flattened_spec specs. # This guarantees that it cannot be a tuple instance and # inline object modification are allowed for index in range(len(obj)): obj[index] = descend(obj[index]) return obj
def unmarshal_array(swagger_spec, array_spec, array_value): """Unmarshal a jsonschema type of 'array' into a python list. :type swagger_spec: :class:`bravado_core.spec.Spec` :type array_spec: dict :type array_value: list :rtype: list :raises: SwaggerMappingError """ if not is_list_like(array_value): raise SwaggerMappingError('Expected list like type for {0}:{1}'.format( type(array_value), array_value)) item_spec = swagger_spec.deref(array_spec).get('items') return [ unmarshal_schema_object(swagger_spec, item_spec, item) for item in array_value ]
def descend(fragment, path=None, visited_refs=None): """ :param fragment: node in spec_dict :param path: list of strings that form the current path to fragment :param visited_refs: list of visted ref_dict """ path = path or [] visited_refs = visited_refs or [] if is_dict_like(fragment): for key, value in iteritems(fragment): fire_callbacks(fragment, key, path + [key]) descend(fragment[key], path + [key], visited_refs) elif is_list_like(fragment): for index in range(len(fragment)): fire_callbacks(fragment, index, path + [str(index)]) descend(fragment[index], path + [str(index)], visited_refs)
def descend(self, value): if is_ref(value): # Update spec_resolver scope to be able to dereference relative specs from a not root file with in_scope(self.spec_resolver, value): uri, deref_value = self.resolve(value['$ref']) object_type = determine_object_type( object_dict=deref_value, default_type_to_object=self.default_type_to_object, ) known_mapping_key = object_type.get_root_holder() if known_mapping_key is None: return self.descend(value=deref_value) else: uri = urlparse(uri) if uri not in self.known_mappings.get( known_mapping_key, {}): # The placeholder is present to interrupt the recursion # during the recursive traverse of the data model (``descend``) self.known_mappings[known_mapping_key][uri] = None self.known_mappings[known_mapping_key][ uri] = self.descend(value=deref_value) return { '$ref': '#/{}/{}'.format(known_mapping_key, self.marshal_uri(uri)) } elif is_dict_like(value): return { key: self.descend(value=subval) for key, subval in iteritems(value) } elif is_list_like(value): return [ self.descend(value=subval) for index, subval in enumerate(value) ] else: return value
def _rename_references_descend(value): if is_ref(value): return { '$ref': reference_renaming_mapping.get(value['$ref'], value['$ref']) } elif is_dict_like(value): return { key: _rename_references_descend(value=subval) for key, subval in iteritems(value) } elif is_list_like(value): return [ _rename_references_descend(value=subval) for index, subval in enumerate(value) ] else: return value
def unmarshal_array(swagger_spec, array_spec, array_value): """Unmarshal a jsonschema type of 'array' into a python list. :type swagger_spec: :class:`bravado_core.spec.Spec` :type array_spec: dict or jsonref.JsonRef :type array_value: list :rtype: list :raises: SwaggerMappingError """ if not is_list_like(array_value): raise SwaggerMappingError('Expected list like type for {0}:{1}'.format( type(array_value), array_value)) result = [] for element in array_value: result.append( unmarshal_schema_object(swagger_spec, array_spec['items'], element)) return result
def descend(value): if is_ref(value): uri, deref_value = resolve(value['$ref']) # Update spec_resolver scope to be able to dereference relative specs from a not root file with in_scope(spec_resolver, {'x-scope': [uri]}): object_type = _determine_object_type(object_dict=deref_value) if object_type is _TYPE_PATH_ITEM: return descend(value=deref_value) else: mapping_key = _TYPE_PROPERTY_HOLDER_MAPPING.get( object_type, 'definitions') uri = urlparse(uri) if uri not in known_mappings.get(mapping_key, {}): # The placeholder is present to interrupt the recursion # during the recursive traverse of the data model (``descend``) known_mappings[mapping_key][uri] = None known_mappings[mapping_key][uri] = descend( value=deref_value) return { '$ref': '#/{}/{}'.format(mapping_key, marshal_uri(uri)) } elif is_dict_like(value): return { key: descend(value=subval) for key, subval in iteritems(value) } elif is_list_like(value): return [ descend(value=subval) for index, subval in enumerate(value) ] else: return value
def descend(fragment, json_reference=None): """ :param fragment: node in spec_dict :param json_reference: JSON Uri where the current fragment could be found :type json_reference: str """ if is_dict_like(fragment): for key, value in sorted(iteritems(fragment)): json_ref = '{}/{}'.format(json_reference or '', key) fire_callbacks(fragment, json_ref) descend( fragment=fragment[key], json_reference=json_ref, ) elif is_list_like(fragment): for index in range(len(fragment)): json_ref = '{}/{}'.format(json_reference or '', index) fire_callbacks(fragment, json_ref) descend( fragment=fragment[index], json_reference=json_ref, )
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 descend(fragment, path=None, visited_refs=None): """ :param fragment: node in spec_dict :param path: list of strings that form the current path to fragment :param visited_refs: list of visted ref_dict """ path = path or [] visited_refs = visited_refs or [] if is_ref(fragment): ref_dict = fragment ref = fragment['$ref'] attach_scope(ref_dict, resolver) # Don't recurse down already visited refs. A ref is not unique # by its name alone. Its scope (attached above) is part of the # equivalence comparison. if ref_dict in visited_refs: log.debug('Already visited %s' % ref) return visited_refs.append(ref_dict) with resolver.resolving(ref) as target: descend(target, path, visited_refs) return # fragment is guaranteed not to be a ref from this point onwards if is_dict_like(fragment): for key, value in iteritems(fragment): fire_callbacks(fragment, key, path + [key]) descend(fragment[key], path + [key], visited_refs) elif is_list_like(fragment): for index in range(len(fragment)): fire_callbacks(fragment, index, path + [str(index)]) descend(fragment[index], path + [str(index)], visited_refs)
def descend(value): if is_ref(value): uri, deref_value = resolve(value['$ref']) # Update spec_resolver scope to be able to dereference relative specs from a not root file with in_scope(spec_resolver, {'x-scope': [uri]}): object_type = _determine_object_type(object_dict=deref_value) if object_type is _TYPE_PATH_ITEM: return descend(value=deref_value) else: mapping_key = _TYPE_PROPERTY_HOLDER_MAPPING.get(object_type, 'definitions') uri = urlparse(uri) if uri not in known_mappings.get(mapping_key, {}): # The placeholder is present to interrupt the recursion # during the recursive traverse of the data model (``descend``) known_mappings[mapping_key][uri] = None known_mappings[mapping_key][uri] = descend(value=deref_value) return {'$ref': '#/{}/{}'.format(mapping_key, marshal_uri(uri))} elif is_dict_like(value): return { key: descend(value=subval) for key, subval in iteritems(value) } elif is_list_like(value): return [ descend(value=subval) for index, subval in enumerate(value) ] else: return value
def request( self, request_params: MutableMapping[str, Any], operation: Optional[Operation] = None, request_config: Optional[RequestConfig] = None, ) -> HttpFuture: """Sets up the request params for aiohttp and executes the request in the background. :param request_params: request parameters for the http request. :param operation: operation that this http request is for. Defaults to None - in which case, we're obviously just retrieving a Swagger Spec. :param request_config:RequestConfig request_config: Per-request config that is passed to :class:`bravado.http_future.HttpFuture`. :rtype: :class: `bravado_core.http_future.HttpFuture` """ orig_data = request_params.get("data", {}) if isinstance(orig_data, Mapping): data = FormData() for name, value in orig_data.items(): str_value = ( str(value) if not is_list_like(value) else [str(v) for v in value] ) data.add_field(name, str_value) else: data = orig_data if isinstance(data, FormData): for name, file_tuple in request_params.get("files", {}): stream_obj = file_tuple[1] data.add_field(name, stream_obj, filename=file_tuple[0]) params = self.prepare_params(request_params.get("params")) connect_timeout = request_params.get("connect_timeout") # type: Optional[float] request_timeout = request_params.get("timeout") # type: Optional[float] # mypy thinks the type of total and connect is float, even though it is Optional[float]. Let's ignore the error. timeout = ( aiohttp.ClientTimeout(total=request_timeout, connect=connect_timeout) if (connect_timeout or request_timeout) else None ) follow_redirects = request_params.get("follow_redirects", False) # aiohttp always adds a Content-Type header, and this breaks some servers that don't # expect it for non-POST/PUT requests: https://github.com/aio-libs/aiohttp/issues/457 skip_auto_headers = ( ["Content-Type"] if request_params.get("method") not in ["POST", "PUT"] else None ) coroutine = self.client_session.request( method=request_params.get("method") or "GET", url=cast(str, request_params.get("url", "")), params=params, data=data, headers={ # Convert not string headers to string k: from_bytes(v) if isinstance(v, bytes) else str(v) for k, v in request_params.get("headers", {}).items() }, allow_redirects=follow_redirects, skip_auto_headers=skip_auto_headers, timeout=timeout, **self._get_ssl_params() ) future = self.run_coroutine_func(coroutine, loop=self.loop) return self.bravado_future_class( self.future_adapter(future), self.response_adapter(loop=self.loop), operation, request_config=request_config, )