def setup(app: web.Application): """Setup the rest API module in the application in aiohttp fashion. - users "rest" section of configuration (see schema in rest_config.py) - loads and validate openapi specs from a remote (e.g. apihub) or local location - connects openapi specs paths to handlers (see rest_routes.py) - enables error, validation and envelope middlewares on API routes IMPORTANT: this is a critical subsystem. Any failure should stop the system startup. It CANNOT be simply disabled & continue """ log.debug("Setting up %s ...", __name__) spec_path = resources.get_path("api/v0/openapi.yaml") with spec_path.open() as fh: spec_dict = yaml.safe_load(fh) api_specs = openapi_core.create_spec(spec_dict, spec_path.as_uri()) # validated openapi specs app[APP_OPENAPI_SPECS_KEY] = api_specs # Connects handlers routes = rest_routes.create(api_specs) app.router.add_routes(routes) log.debug("routes:\n\t%s", "\n\t".join(map(str, routes))) # Enable error, validation and envelop middleware on API routes base_path = get_base_path(api_specs) append_rest_middlewares(app, base_path)
def setup(app: web.Application, *, debug=False): log.debug("Setting up %s %s...", __name__, "[DEBUG]" if debug else "") # main_cfg = app[APP_CONFIG_KEY]["main"] cfg = app[APP_CONFIG_KEY][CONFIG_SECTION_NAME] try: #specs = await create_openapi_specs(location=cfg["location"]) loop = asyncio.get_event_loop() location = cfg["location"] specs = loop.run_until_complete(get_specs(location)) # TODO: tmp removed but keep in case ... # sets servers variables to current server's config # extra_api_urls = cfg.get("extra_urls", list()) # if debug: # for host in {'127.0.0.1', 'localhost', main_cfg['host'] }: # for port in {9081, main_cfg['port']}: # extra_api_urls.append("http://{}:{}".format(host, port)) # server = get_server(specs.servers, "{publicUrl}/{basePath}") # for url in extra_api_urls: # new_server = deepcopy(server) # new_server.variables['publicUrl'].default = url # specs.servers.append(new_server) # TODO: What if many specs to expose? v0, v1, v2 ... perhaps a dict instead? # TODO: should freeze specs here?? app[APP_OPENAPI_SPECS_KEY] = specs # validated openapi specs # diagnostics routes routes = rest_routes.create(specs) app.router.add_routes(routes) # middlewares base_path = openapi.get_base_path(specs) version = cfg["version"] assert "/" + version == base_path, "Expected %s, got %s" % (version, base_path) append_rest_middlewares(app, base_path) except openapi.OpenAPIError: # TODO: protocol when some parts are unavailable because of failure # Define whether it is critical or this server can still # continue working offering partial services log.exception("Invalid rest API specs. Rest API is DISABLED")
def setup(app: web.Application, *, devel=False): """ Subsystem's setup :param app: aiohttp application :type app: web.Application :param devel: enables development mode, defaults to False :param devel: bool, optional """ log.debug("Setting up %s %s...", __name__, "[DEVEL]" if devel else "") cfg = app[APP_CONFIG_KEY][CONFIG_SECTION_NAME] try: loop = asyncio.get_event_loop() location = cfg["location"] if not URL(location).host: if not Path(location).exists(): # add resource location if resources.exists(location): location = resources.get_path(location) specs = loop.run_until_complete(get_specs(location)) # TODO: What if many specs to expose? v0, v1, v2 ... perhaps a dict instead? app[APP_OPENAPI_SPECS_KEY] = specs # validated openapi specs except openapi.OpenAPIError: # TODO: protocol when some parts are unavailable because of failure # Define whether it is critical or this server can still # continue working offering partial services log.exception("Invalid rest API specs. Rest API is DISABLED") else: # routes routes = create_routes(specs) log.debug("%s API routes:\n%s", CONFIG_SECTION_NAME, pformat(routes)) app.router.add_routes(routes) # middlewares base_path = openapi.get_base_path(specs) version = cfg["version"] assert "/" + version == base_path, "Expected %s, got %s" % (version, base_path) append_rest_middlewares(app, base_path)
def setup(app: web.Application): """Setup the rest API module in the application in aiohttp fashion. - users "rest" section of configuration (see schema in rest_config.py) - loads and validate openapi specs from a remote (e.g. apihub) or local location - connects openapi specs paths to handlers (see rest_routes.py) - enables error, validation and envelope middlewares on API routes IMPORTANT: this is a critical subsystem. Any failure should stop the system startup. It CANNOT be simply disabled & continue """ log.debug("Setting up %s ...", __name__) cfg = app[APP_CONFIG_KEY][CONFIG_SECTION_NAME] # app_config = app[APP_CONFIG_KEY]['main'] # TODO: define appconfig key based on config schema # api_specs = create_apispecs(app_config) loop = asyncio.get_event_loop() location = "{}/storage/{}/openapi.yaml".format(cfg["oas_repo"], API_VERSION_TAG) if is_url(location): loop.run_until_complete(assert_enpoint_is_ok(URL(location))) api_specs = loop.run_until_complete(create_openapi_specs(location)) # validated openapi specs app[APP_OPENAPI_SPECS_KEY] = api_specs # Connects handlers routes = rest_routes.create(api_specs) app.router.add_routes(routes) log.debug("routes:\n\t%s", "\n\t".join(map(str, routes))) # Enable error, validation and envelop middleware on API routes base_path = get_base_path(api_specs) append_rest_middlewares(app, base_path)