def __init__(self, url, user_name=None, password=None): self.url = url self.authenticated = False # This next part pretty much just goes through the motions of what # from_url() does in the parent class. # First let's make an http client self.http_client = RequestsClient() # Now let's get the spec spec_url = urljoin(self.url, '/docs/swagger.json') loader = Loader(self.http_client) spec_dict = loader.load_spec(spec_url) # Now we can create the spec client config = {'include_missing_properties': False} # Apply bravado config defaults bravado_config = bravado_config_from_config_dict(config) # set bravado config object config['bravado'] = bravado_config_from_config_dict(config) swagger_spec = Spec.from_dict(spec_dict, origin_url=spec_url, http_client=self.http_client, config=config) # Now that we have the spec client we can init the parent class super().__init__(swagger_spec, bravado_config.also_return_response) # Go ahead and auth if we were passed creds. if user_name and password: self.authenticate(user_name, password)
def from_spec(cls, spec_dict, origin_url=None, http_client=None, config=None): """ Build a :class:`SwaggerClient` from a Swagger spec in dict form. :param spec_dict: a dict with a Swagger spec in json-like form :param origin_url: the url used to retrieve the spec_dict :type origin_url: str :param config: Configuration dict - see spec.CONFIG_DEFAULTS :rtype: :class:`SwaggerClient` """ http_client = http_client or RequestsClient() config = config or {} # Apply bravado config defaults bravado_config = bravado_config_from_config_dict(config) # remove bravado configs from config dict for key in set(bravado_config._fields).intersection(set(config)): del config[key] # set bravado config object config['bravado'] = bravado_config swagger_spec = Spec.from_dict( spec_dict, origin_url, http_client, config, ) return cls(swagger_spec, also_return_response=bravado_config.also_return_response)
def __init__(self, apikey=None, headers=None, host=HOST): # - Kong forwards consumer headers when api-key used for auth # - forward consumer headers when connecting through localhost self.__dict__ = self._shared_state self.apikey = apikey self.headers = {"x-api-key": apikey} if apikey else headers self.host = host if "swagger_spec" not in self.__dict__ or ( self.headers is not None and self.swagger_spec.http_client.headers != self.headers ): http_client = FidoClientGlobalHeaders(headers=self.headers) loader = Loader(http_client) protocol = "https" if self.apikey else "http" origin_url = f"{protocol}://{self.host}/apispec.json" spec_dict = loader.load_spec(origin_url) spec_dict["host"] = self.host spec_dict["schemes"] = [protocol] config = { "validate_responses": False, "use_models": False, "include_missing_properties": False, "formats": [email_format], } bravado_config = bravado_config_from_config_dict(config) for key in set(bravado_config._fields).intersection(set(config)): del config[key] config["bravado"] = bravado_config swagger_spec = Spec.from_dict(spec_dict, origin_url, http_client, config) super().__init__( swagger_spec, also_return_response=bravado_config.also_return_response )
def test_no_fallback_result_if_config_disabled(mock_future_adapter, mock_operation, http_future): mock_future_adapter.result.side_effect = BravadoTimeoutError() mock_operation.swagger_spec.config = { 'bravado': bravado_config_from_config_dict({'disable_fallback_results': True}), } with pytest.raises(BravadoTimeoutError): http_future.response(fallback_result=lambda e: None)
def test_no_is_fallback_result_if_no_exceptions(http_future, mock_operation): mock_operation.swagger_spec.config = { 'bravado': bravado_config_from_config_dict({'disable_fallback_results': False}), } with mock.patch('bravado.http_future.unmarshal_response'): response = http_future.response() assert response.metadata.is_fallback_result is False
def test_custom_response_metadata(mock_operation, http_future): mock_operation.swagger_spec.config = { 'bravado': bravado_config_from_config_dict( {'response_metadata_class': 'tests.http_future.HttpFuture.response_test.ResponseMetadata'}), } with mock.patch('bravado.http_future.unmarshal_response'): response = http_future.response() assert response.metadata.__class__ is ResponseMetadata
def test_fallback_result(fallback_result, mock_future_adapter, mock_operation, http_future): mock_future_adapter.result.side_effect = BravadoTimeoutError() mock_operation.swagger_spec.config = { 'bravado': bravado_config_from_config_dict({'disable_fallback_results': False}), } response = http_future.response(fallback_result=fallback_result) assert response.result is fallback_result assert response.metadata.is_fallback_result is True
def test_config_overrides_default_config(mock_log): config_dict = { 'also_return_response': True, 'disable_fallback_results': True, 'response_metadata_class': 'tests.config_test.ResponseMetadata', } expected_config_dict = config_dict.copy() expected_config_dict['response_metadata_class'] = ResponseMetadata assert bravado_config_from_config_dict(config_dict)._asdict() == expected_config_dict assert mock_log.warning.call_count == 0
def test_config_overrides_default_config(mock_log): config_dict = { 'also_return_response': True, 'disable_fallback_results': True, 'response_metadata_class': 'tests.config_test.ResponseMetadata', } expected_config_dict = config_dict.copy() expected_config_dict['response_metadata_class'] = ResponseMetadata assert bravado_config_from_config_dict( config_dict)._asdict() == expected_config_dict assert mock_log.warning.call_count == 0
def test_no_force_fallback_result_if_disabled(http_future, mock_operation, mock_incoming_response, fallback_result): http_future.request_config = RequestConfig( {'force_fallback_result': True}, also_return_response_default=False, ) mock_operation.swagger_spec.config = { 'bravado': bravado_config_from_config_dict({'disable_fallback_results': True}), } with mock.patch('bravado.http_future.unmarshal_response', autospec=True): response = http_future.response(fallback_result=lambda e: fallback_result) assert response.result == mock_incoming_response.swagger_result
def test_force_fallback_result(mock_operation, fallback_result, http_future): http_future.request_config = RequestConfig( {'force_fallback_result': True}, also_return_response_default=False, ) mock_operation.swagger_spec.config = { 'bravado': bravado_config_from_config_dict({}) } with mock.patch('bravado.http_future.unmarshal_response', autospec=True): response = http_future.response(fallback_result=lambda e: fallback_result) assert response.result == fallback_result assert response.metadata.is_fallback_result is True assert response.metadata.handled_exception_info[0] is ForcedFallbackResultError
def _bravado_config(self): # type: () -> BravadoConfig if self.operation: return self.operation.swagger_spec.config['bravado'] else: return bravado_config_from_config_dict(CONFIG_DEFAULTS)
def load(self): http_client = FidoClientGlobalHeaders(headers=self.headers) loader = Loader(http_client) origin_url = f"{self.url}/apispec.json" spec_dict = loader.load_spec(origin_url) spec_dict["host"] = self.host spec_dict["schemes"] = [self.protocol] config = { "validate_responses": False, "use_models": False, "include_missing_properties": False, "formats": [email_format, url_format], } bravado_config = bravado_config_from_config_dict(config) for key in set(bravado_config._fields).intersection(set(config)): del config[key] config["bravado"] = bravado_config swagger_spec = Spec.from_dict(spec_dict, origin_url, http_client, config) super().__init__( swagger_spec, also_return_response=bravado_config.also_return_response) # expand regex-based query parameters for `data` columns try: resp = self.projects.get_entries(_fields=["columns"]).result() except AttributeError: # skip in tests return columns = {"text": [], "number": []} for project in resp["data"]: for column in project["columns"]: if column["path"].startswith("data."): col = column["path"].replace(".", "__") if column["unit"] == "NaN": columns["text"].append(col) else: col = f"{col}__value" columns["number"].append(col) operators = {"text": ["contains"], "number": ["gte", "lte"]} for path, d in spec_dict["paths"].items(): for verb in ["get", "put", "post", "delete"]: if verb in d: old_params = deepcopy(d[verb].pop("parameters")) new_params, param_names = [], set() while old_params: param = old_params.pop() if param["name"].startswith("^data__"): op = param["name"].rsplit("__", 1)[1] for typ, ops in operators.items(): if op in ops: for column in columns[typ]: new_param = deepcopy(param) param_name = f"{column}__{op}" if param_name not in param_names: new_param["name"] = param_name desc = f"filter {column} via ${op}" new_param["description"] = desc new_params.append(new_param) param_names.add(param_name) else: new_params.append(param) d[verb]["parameters"] = new_params swagger_spec = Spec.from_dict(spec_dict, origin_url, http_client, config) super().__init__( swagger_spec, also_return_response=bravado_config.also_return_response)
def test_empty_config_yields_default_config(processed_default_config): assert bravado_config_from_config_dict({}) == processed_default_config
def test_ignore_unknown_configs(processed_default_config): config_dict = {'validate_swagger_spec': False} assert bravado_config_from_config_dict( config_dict) == processed_default_config
def test_empty_config_yields_default_config(processed_default_config): assert bravado_config_from_config_dict({}) == processed_default_config
def _bravado_config(self): # type: () -> BravadoConfig if self.operation: return self.operation.swagger_spec.config['bravado'] else: return bravado_config_from_config_dict(CONFIG_DEFAULTS)
def test_ignore_unknown_configs(processed_default_config): config_dict = {'validate_swagger_spec': False} assert bravado_config_from_config_dict(config_dict) == processed_default_config