def create(cls, request): method = request.method.lower() cookie = request.cookies or {} # gets deduced by path finder against spec path = {} mimetype = request.headers.get('Accept') or \ request.headers.get('Content-Type') parameters = RequestParameters( query=ImmutableMultiDict(request.params), header=request.headers, cookie=cookie, path=path, ) return OpenAPIRequest( full_url_pattern=request.url, method=method, parameters=parameters, body=request.data, mimetype=mimetype, )
def test_no_resolver(self, request_factory): request = request_factory.get('/admin/') openapi_request = DjangoOpenAPIRequest(request) path = {} query = {} headers = { 'Cookie': '', } cookies = {} assert openapi_request.parameters == RequestParameters( path=path, query=query, header=headers, cookie=cookies, ) assert openapi_request.host_url == request._current_scheme_host assert openapi_request.path == request.path assert openapi_request.method == request.method.lower() assert openapi_request.path_pattern == request.path assert openapi_request.body == request.body assert openapi_request.mimetype == request.content_type
def test_no_resolver(self, request_factory): request = request_factory.get("/admin/") openapi_request = DjangoOpenAPIRequest(request) path = {} query = {} headers = Headers({ "Cookie": "", }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, query=query, header=headers, cookie=cookies, ) assert openapi_request.method == request.method.lower() assert ( openapi_request.full_url_pattern == request._current_scheme_host + request.path) assert openapi_request.body == request.body assert openapi_request.mimetype == request.content_type
def test_get_pet(self, validator): authorization = 'Basic ' + self.api_key_encoded headers = { 'Authorization': authorization, } request = MockRequest( self.host_url, 'get', '/v1/pets/1', path_pattern='/v1/pets/{petId}', view_args={'petId': '1'}, headers=headers, ) result = validator.validate(request) assert result.errors == [] assert result.body is None assert result.parameters == RequestParameters( path={ 'petId': 1, }, ) assert result.security == { 'petstore_auth': self.api_key, }
def test_get_pets(self, validator): args = {'limit': '10', 'ids': ['1', '2'], 'api_key': self.api_key} request = MockRequest( self.host_url, 'get', '/v1/pets', path_pattern='/v1/pets', args=args, ) result = validator.validate(request) assert result.errors == [] assert result.body is None assert result.parameters == RequestParameters(query={ 'limit': 10, 'page': 1, 'search': '', 'ids': [1, 2], }, ) assert result.security == { 'api_key': self.api_key, }
def test_get_pets_webob(self, validator): from webob.multidict import GetDict request = MockRequest( self.host_url, 'get', '/v1/pets', path_pattern='/v1/pets', ) request.parameters.query = GetDict( [('limit', '5'), ('ids', '1'), ('ids', '2')], {} ) result = validator.validate(request) assert result.errors == [] assert result.body is None assert result.parameters == RequestParameters( query={ 'limit': 5, 'page': 1, 'search': '', 'ids': [1, 2], }, )
def create(cls, request): method = request.method.lower() if request.url_rule is None: path_pattern = request.path else: path_pattern = cls.path_regex.sub(r"{\1}", request.url_rule.rule) header = Headers(request.headers) parameters = RequestParameters( path=request.view_args, query=request.args, header=header, cookie=request.cookies, ) full_url_pattern = urljoin(request.host_url, path_pattern) return OpenAPIRequest( full_url_pattern=full_url_pattern, method=method, parameters=parameters, body=request.data, mimetype=request.mimetype, )
def create(cls, request): method = request.method.lower() if request.url_rule is None: path_pattern = request.path else: path_pattern = cls.path_regex.sub(r'{\1}', request.url_rule.rule) parameters = RequestParameters( path=request.view_args, query=request.args, header=request.headers, cookie=request.cookies, ) return OpenAPIRequest( host_url=request.host_url, path=request.path, path_pattern=path_pattern, method=method, parameters=parameters, body=request.data, mimetype=request.mimetype, )
def test_get_pets_tags_param(self, spec, response_validator): host_url = 'http://petstore.swagger.io/v1' path_pattern = '/v1/pets' query_params = [ ('limit', '20'), ('tags', 'cats,dogs'), ] request = MockRequest( host_url, 'GET', '/pets', path_pattern=path_pattern, args=query_params, ) parameters = validate_parameters(spec, request) body = validate_body(spec, request) assert parameters == RequestParameters( query={ 'limit': 20, 'page': 1, 'search': '', 'tags': ['cats', 'dogs'], } ) assert body is None data_json = { 'data': [], } data = json.dumps(data_json) response = MockResponse(data) response_result = response_validator.validate(request, response) assert response_result.errors == [] assert isinstance(response_result.data, BaseModel) assert response_result.data.data == []
def _get_parameters(self, request, params): errors = [] seen = set() locations = {} for param_name, param in params: if (param_name, param.location.value) in seen: # skip parameter already seen # e.g. overriden path item paremeter on operation continue seen.add((param_name, param.location.value)) try: raw_value = param.get_raw_value(request) except MissingRequiredParameter as exc: errors.append(exc) continue except OpenAPIParameterError: continue try: casted = param.cast(raw_value) except OpenAPIParameterError as exc: errors.append(exc) continue try: unmarshalled = param.unmarshal( casted, self.custom_formatters, resolver=self.spec._resolver, ) except OpenAPIParameterError as exc: errors.append(exc) else: locations.setdefault(param.location.value, {}) locations[param.location.value][param_name] = unmarshalled return RequestParameters(**locations), errors
def test_post_no_one_of_schema(self, spec, spec_dict): host_url = 'https://staging.gigantic-server.com/v1' path_pattern = '/v1/pets' pet_name = 'Cat' alias = 'kitty' data_json = { 'name': pet_name, 'alias': alias, } data = json.dumps(data_json) headers = { 'api_key': self.api_key_encoded, } cookies = { 'user': '******', } request = MockRequest( host_url, 'POST', '/pets', path_pattern=path_pattern, data=data, headers=headers, cookies=cookies, ) parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ 'api_key': self.api_key, }, cookie={ 'user': 123, }, ) with pytest.raises(InvalidSchemaValue): validate_body(spec, request)
def test_simple(self, request_factory): from django.urls import resolve request = request_factory.get('/admin/') request.resolver_match = resolve('/admin/') openapi_request = DjangoOpenAPIRequest(request) path = {} query = {} headers = { 'Cookie': '', } cookies = {} assert openapi_request.parameters == RequestParameters( path=path, query=query, header=headers, cookie=cookies, ) assert openapi_request.method == request.method.lower() assert openapi_request.full_url_pattern == \ request._current_scheme_host + request.path assert openapi_request.body == request.body assert openapi_request.mimetype == request.content_type
def test_url_rule(self, request_factory, request): request = request_factory("GET", "/browse/12/", subdomain="kb") openapi_request = RequestsOpenAPIRequest(request) # empty when not bound to spec path = {} query = ImmutableMultiDict([]) headers = Headers({ "Content-Type": "application/json", }) cookies = {} assert openapi_request.parameters == RequestParameters( path=path, query=query, header=headers, cookie=cookies, ) prepared = request.prepare() assert openapi_request.method == request.method.lower() assert ( openapi_request.full_url_pattern == "http://localhost/browse/12/") assert openapi_request.body == prepared.body assert openapi_request.mimetype == "application/json"
def create(cls, request): method = request.method.lower() if request.resolver_match is None: path_pattern = request.path else: route = cls.path_regex.sub(r'{\1}', request.resolver_match.route) path_pattern = '/' + route path = request.resolver_match and request.resolver_match.kwargs or {} parameters = RequestParameters( path=path, query=request.GET, header=request.headers.items(), cookie=request.COOKIES, ) full_url_pattern = urljoin(request._current_scheme_host, path_pattern) return OpenAPIRequest( full_url_pattern=full_url_pattern, method=method, parameters=parameters, body=request.body, mimetype=request.content_type, )
def test_post_cats_boolean_string(self, spec, spec_dict): host_url = 'https://staging.gigantic-server.com/v1' path_pattern = '/v1/pets' pet_name = 'Cat' pet_tag = 'cats' pet_street = 'Piekna' pet_city = 'Warsaw' pet_healthy = False data_json = { 'name': pet_name, 'tag': pet_tag, 'position': 2, 'address': { 'street': pet_street, 'city': pet_city, }, 'healthy': pet_healthy, 'ears': { 'healthy': pet_healthy, } } data = json.dumps(data_json) headers = { 'api_key': self.api_key_encoded, } cookies = { 'user': '******', } request = MockRequest( host_url, 'POST', '/pets', path_pattern=path_pattern, data=data, headers=headers, cookies=cookies, ) parameters = validate_parameters(spec, request) assert parameters == RequestParameters( header={ 'api_key': self.api_key, }, cookie={ 'user': 123, }, ) body = validate_body(spec, request) schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] address_model = schemas['Address']['x-model'] assert body.__class__.__name__ == pet_model assert body.name == pet_name assert body.tag == pet_tag assert body.position == 2 assert body.address.__class__.__name__ == address_model assert body.address.street == pet_street assert body.address.city == pet_city assert body.healthy is False
def test_get_parameters_variables_for_simulation_from_file(self): endpoint = '/sed-ml/get-parameters-variables-for-simulation' model_filename = os.path.abspath( os.path.join(self.FIXTURES_DIR, 'Chaouiya-BMC-Syst-Biol-2013-EGF-TNFa-signaling.xml')) model_fid = open(model_filename, 'rb') data = MultiDict([ ('modelLanguage', 'urn:sedml:language:sbml'), ('modelingFramework', 'SBO_0000547'), ('simulationType', 'SedUniformTimeCourseSimulation'), ('simulationAlgorithm', 'KISAO_0000450'), ('modelFile', model_fid), ]) with app.app.app.test_client() as client: response = client.post(endpoint, data=data, content_type="multipart/form-data") model_fid.close() self.assertEqual(response.status_code, 200, response.json) sed_doc = response.json vars = [ data_gen['variables'][0] for data_gen in sed_doc['dataGenerators'] ] self.assertEqual(vars[0]['id'], 'time') self.assertEqual(vars[0]['name'], 'Time') self.assertEqual(vars[0]['symbol'], Symbol.time) self.assertNotIn('target', vars[0]) self.assertEqual(vars[-1]['id'], 'level_species_nik') self.assertEqual(vars[-1]['name'], 'Level of species "nik"') self.assertNotIn('symbol', vars[-1]) vars[-1]['target']['namespaces'].sort(key=lambda ns: ns['prefix']) self.assertEqual( vars[-1]['target'], { "_type": "SedTarget", "value": "/sbml:sbml/sbml:model/qual:listOfQualitativeSpecies/qual:qualitativeSpecies[@qual:id='nik']", "namespaces": [ { "_type": "Namespace", "prefix": "qual", "uri": "http://www.sbml.org/sbml/level3/version1/qual/version1" }, { "_type": "Namespace", "prefix": "sbml", "uri": "http://www.sbml.org/sbml/level3/version1/core" }, ] }, ) # validate request and response if hasattr(self, "request_validator"): with open(model_filename, 'rb') as file: model_content = file.read() request = OpenAPIRequest( full_url_pattern='https://127.0.0.1/' + endpoint, method='post', body={ 'modelLanguage': 'urn:sedml:language:sbml', 'modelingFramework': 'SBO_0000547', 'simulationType': 'SedUniformTimeCourseSimulation', 'simulationAlgorithm': 'KISAO_0000029', 'modelFile': model_content, }, mimetype='multipart/form-data', parameters=RequestParameters(), ) result = self.request_validator.validate(request) result.raise_for_errors() response = OpenAPIResponse(data=json.dumps(sed_doc), status_code=200, mimetype='application/json') result = self.response_validator.validate(request, response) result.raise_for_errors()
def test_get_manifest_for_combine_archive_error_handling(self): endpoint = '/combine/manifest' data = MultiDict([ ('url', 'x'), ]) with app.app.app.test_client() as client: response = client.post(endpoint, data=data, content_type="multipart/form-data") self.assertEqual(response.status_code, 400, response.json) self.assertTrue( response.json['title'].startswith('File could not be loaded from')) if hasattr(self, "response_validator"): request = OpenAPIRequest( full_url_pattern='https://127.0.0.1/combine/manifest', method='post', body={ 'url': 'x', }, mimetype=None, parameters=RequestParameters(), ) response = OpenAPIResponse(data=json.dumps(response.json), status_code=400, mimetype='application/json') result = self.response_validator.validate(request, response) result.raise_for_errors() response = mock.Mock( raise_for_status=lambda: None, content=b'.', ) with mock.patch('requests.get', return_value=response): with app.app.app.test_client() as client: response = client.post(endpoint, data=data, content_type="multipart/form-data") self.assertEqual(response.status_code, 400, response.json) self.assertIn( 'File is not a valid manifest or a COMBINE/OMEX which contains a valid manifest', response.json['title']) archive_filename = os.path.join(self.FIXTURES_DIR, 'no-manifest.omex') with open(archive_filename, 'rb') as file: archive_url_content = file.read() response = mock.Mock( raise_for_status=lambda: None, content=archive_url_content, ) with mock.patch('requests.get', return_value=response): with app.app.app.test_client() as client: response = client.post(endpoint, data=data, content_type="multipart/form-data") self.assertEqual(response.status_code, 400, response.json) self.assertIn('does not contain a manifest', response.json['title']) archive_filename = os.path.join(self.FIXTURES_DIR, 'bad-manifest.omex') with open(archive_filename, 'rb') as file: archive_url_content = file.read() response = mock.Mock( raise_for_status=lambda: None, content=archive_url_content, ) with mock.patch('requests.get', return_value=response): with app.app.app.test_client() as client: response = client.post(endpoint, data=data, content_type="multipart/form-data") self.assertEqual(response.status_code, 400, response.json) self.assertIn( 'File is not a valid manifest or a COMBINE/OMEX which contains a valid manifest', response.json['title'])
def test_invalid_complex_parameter(self, validator, spec_dict): pet_name = 'Cat' pet_tag = 'cats' pet_street = 'Piekna' pet_city = 'Warsaw' data_json = { 'name': pet_name, 'tag': pet_tag, 'position': 2, 'address': { 'street': pet_street, 'city': pet_city, }, 'ears': { 'healthy': True, } } data = json.dumps(data_json) headers = { 'api_key': self.api_key_encoded, } userdata = { 'name': 1, } userdata_json = json.dumps(userdata) cookies = { 'user': '******', 'userdata': userdata_json, } request = MockRequest( 'https://development.gigantic-server.com', 'post', '/v1/pets', path_pattern='/v1/pets', data=data, headers=headers, cookies=cookies, ) result = validator.validate(request) assert len(result.errors) == 1 assert type(result.errors[0]) == InvalidSchemaValue assert result.parameters == RequestParameters( header={ 'api_key': self.api_key, }, cookie={ 'user': 123, }, ) assert result.security == {} schemas = spec_dict['components']['schemas'] pet_model = schemas['PetCreate']['x-model'] address_model = schemas['Address']['x-model'] assert result.body.__class__.__name__ == pet_model assert result.body.name == pet_name assert result.body.tag == pet_tag assert result.body.position == 2 assert result.body.address.__class__.__name__ == address_model assert result.body.address.street == pet_street assert result.body.address.city == pet_city
def test_get_metadata_for_combine_archive_file_as_rdf_triples(self): archive_filename = os.path.join( self.FIXTURES_DIR, 'Ciliberto-J-Cell-Biol-2003-morphogenesis-checkpoint-continuous.omex' ) fid = open(archive_filename, 'rb') data = MultiDict([ ('file', fid), ('omexMetadataFormat', OmexMetadataInputFormat.rdfxml.value), ]) endpoint = '/combine/metadata/rdf' with app.app.app.test_client() as client: response = client.post(endpoint, data=data, content_type="multipart/form-data") self.assertEqual(response.status_code, 200, response.json) metadata = response.json self.assertEqual( metadata[0], { '_type': 'RdfTriple', 'subject': { '_type': 'RdfUriNode', 'value': 'http://omex-library.org/Ciliberto-J-Cell-Biol-2003-morphogenesis-checkpoint-continuous.omex', }, 'predicate': { '_type': 'RdfUriNode', 'value': 'http://purl.org/dc/elements/1.1/title', }, 'object': { '_type': 'RdfLiteralNode', 'value': 'Morphogenesis checkpoint in budding yeast (continuous) (Ciliberto et al., Journal Cell Biology, 2003)', } }) fid.close() # validate request and response if hasattr(self, "request_validator"): with open(archive_filename, 'rb') as file: file_content = file.read() request = OpenAPIRequest( full_url_pattern='https://127.0.0.1/combine/metadata/rdf', method='post', body={ 'file': file_content, 'omexMetadataFormat': OmexMetadataInputFormat.rdfxml.value, }, mimetype='multipart/form-data', parameters=RequestParameters(), ) result = self.request_validator.validate(request) result.raise_for_errors() response = OpenAPIResponse(data=json.dumps(metadata), status_code=200, mimetype='application/json') result = self.response_validator.validate(request, response) result.raise_for_errors()
def test_get_manifest_for_combine_archive_url(self): archive_filename = os.path.join(self.FIXTURES_DIR, self.TEST_CASE + '.omex') with open(archive_filename, 'rb') as file: archive_url_content = file.read() archive_url = 'https://archive.combine.org' data = MultiDict([ ('url', archive_url), ]) response = mock.Mock( raise_for_status=lambda: None, content=archive_url_content, ) endpoint = '/combine/manifest' with mock.patch('requests.get', return_value=response): with app.app.app.test_client() as client: response = client.post(endpoint, data=data, content_type="multipart/form-data") self.assertEqual(response.status_code, 200, response.json) manifest = response.json expected_manifest = { '_type': 'CombineArchiveManifest', 'contents': [{ '_type': 'CombineArchiveManifestContent', 'format': 'http://identifiers.org/combine.specifications/sbml', 'location': { '_type': 'CombineArchiveManifestLocation', 'path': './Caravagna2010.xml', 'value': { '_type': 'CombineArchiveContentFile', 'filename': 'Caravagna2010.xml', }, }, 'master': False }, { '_type': 'CombineArchiveManifestContent', 'format': 'http://identifiers.org/combine.specifications/sed-ml', 'location': { '_type': 'CombineArchiveManifestLocation', 'path': './BIOMD0000000912_sim.sedml', 'value': { '_type': 'CombineArchiveContentFile', 'filename': 'BIOMD0000000912_sim.sedml', }, }, 'master': True }, { '_type': 'CombineArchiveManifestContent', 'format': 'http://identifiers.org/combine.specifications/omex', 'location': { '_type': 'CombineArchiveManifestLocation', 'path': '.', 'value': { '_type': 'CombineArchiveContentFile', 'filename': '.', }, }, 'master': False }, { '_type': 'CombineArchiveManifestContent', 'format': 'http://identifiers.org/combine.specifications/omex-metadata', 'location': { '_type': 'CombineArchiveManifestLocation', 'path': 'metadata.rdf', 'value': { '_type': 'CombineArchiveContentFile', 'filename': 'metadata.rdf', }, }, 'master': False }] } self.assertEqual(manifest, expected_manifest, manifest) # validate request and response if hasattr(self, "request_validator"): request = OpenAPIRequest( full_url_pattern='https://127.0.0.1/combine/manifest', method='post', body={ 'url': archive_url, }, mimetype='multipart/form-data', parameters=RequestParameters(), ) result = self.request_validator.validate(request) result.raise_for_errors() response = OpenAPIResponse(data=json.dumps(expected_manifest), status_code=200, mimetype='application/json') result = self.response_validator.validate(request, response) result.raise_for_errors()