def _load_swagger_resource(self, endpoint_name: str): """ Get Swagger spec of specified service and create an app instance to be able to validate requests/responses and perform request. :param endpoint_name: name of the service endpoint that data will be retrieved :return PySwagger.App: an app instance """ # load Swagger resource file logic_module = self._get_logic_module(endpoint_name) schema_url = utils.get_swagger_url_by_logic_module(logic_module) if schema_url not in self._data: # load swagger json as a raw App and prepare it try: app = App.load(schema_url) except URLError: raise URLError(f'Make sure that {schema_url} is accessible.') if app.raw.basePath == '/': getattr(app, 'raw').update_field('basePath', '') app.prepare() self._data[schema_url] = app return self._data[schema_url]
async def _get_swagger_spec(self, endpoint_name: str) -> Spec: """ Gets swagger spec asynchronously and adds it to specs cache """ logic_module = self._get_logic_module(endpoint_name) schema_url = utils.get_swagger_url_by_logic_module(logic_module) if schema_url not in self._specs: # Use stored specification of the module spec_dict = logic_module.api_specification # Pull specification of the module from its service and store it if spec_dict is None: async with aiohttp.ClientSession() as session: async with session.get(schema_url) as response: try: spec_dict = await response.json() except aiohttp.ContentTypeError: raise exceptions.GatewayError( f'Failed to parse swagger schema from {schema_url}. Should be JSON.' ) logic_module.api_specification = spec_dict logic_module.save() swagger_spec = Spec.from_dict(spec_dict, config=self.SWAGGER_CONFIG) self._specs[schema_url] = swagger_spec return self._specs[schema_url]
def _get_swagger_spec(self, endpoint_name: str) -> Spec: """Get Swagger spec of specified service.""" logic_module = self._get_logic_module(endpoint_name) schema_url = utils.get_swagger_url_by_logic_module(logic_module) if schema_url not in self._specs: try: # Use stored specification of the module spec_dict = logic_module.api_specification # Pull specification of the module from its service and store it if spec_dict is None: response = utils.get_swagger_from_url(schema_url) spec_dict = response.json() logic_module.api_specification = spec_dict logic_module.save() except URLError: raise URLError(f'Make sure that {schema_url} is accessible.') swagger_spec = Spec.from_dict(spec_dict, config=self.SWAGGER_CONFIG) self._specs[schema_url] = swagger_spec return self._specs[schema_url]
def test_get_swagger_urls(self): modules = factories.LogicModule.create_batch(3) urls = get_swagger_urls() for module in modules: assert module.endpoint_name in urls assert urls[ module.endpoint_name] == get_swagger_url_by_logic_module( module)
def update_api_specification(self, request, *args, **kwargs): """ Updates the API specification of given logic module """ instance = self.get_object() schema_url = utils.get_swagger_url_by_logic_module(instance) response = utils.get_swagger_from_url(schema_url) spec_dict = response.json() data = {'api_specification': spec_dict} serializer = self.get_serializer(instance, data=data, partial=True) serializer.is_valid(raise_exception=True) self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} return Response(serializer.data)
def test_get_swagger_url_by_logic_module(self): module = factories.LogicModule.create() url = get_swagger_url_by_logic_module(module) assert url.startswith(module.endpoint)
def test_get_swagger_url_by_logic_module_specified_docs(self): module = factories.LogicModule.create(docs_endpoint="api-docs") url = get_swagger_url_by_logic_module(module) assert url.startswith(module.endpoint) assert module.docs_endpoint in url