def main(): options = {"swagger_ui": True} specification_dir = os.path.join(os.path.dirname(__file__), 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options, server_args=dict(middlewares=[db])) setup(app.app, EncryptedCookieStorage(Fernet.generate_key().decode())) db.init_app(app.app, config=dict(host=Const.DB_HOST, port=Const.DB_PORT, user=Const.DB_USER, password=Const.DB_PASSWORD, database=Const.DB_NAME)) app.add_api('openapi.yaml', arguments={'title': 'DSM Auth server'}, pythonic_params=True, pass_context_arg_name='request') app.app.cleanup_ctx.extend([get_public_key]) app.app.on_startup.append(create_tables) app.run(port=8080)
def get_app(setup_telegram_client: Callable) -> connexion.AioHttpApp: app = connexion.AioHttpApp(__name__) api = app.add_api(os.path.join(os.getcwd(), API_SPECS_PATH), pass_context_arg_name='request', strict_validation=True) app.app.on_startup.append(setup_telegram_client(api.subapp)) return app
async def get_app(): """Get the app.""" opts = {"swagger_ui": True} app = connexion.AioHttpApp(__name__, only_one_api=True, options=opts, specification_dir='spec/') app.add_api('resolved.yaml', pass_context_arg_name='request', strict_validation=True) # Removed validate_responses=True because of protocol buffers # Can also use debug=True if needed in dev # Add db connection pool dsn = 'dbname=tutorial_openapi_aiohttp user={user} host={host} port={port}'.format( host=os.environ.get('DB_HOST', 'localhost'), port=os.environ.get('DB_PORT', 5432), user=os.environ.get('DB_USER', 'dev'), ) app.app['db_conn'] = await aiopg.create_pool(dsn, minsize=10, maxsize=500, timeout=10) return app
def client(loop, aiohttp_client): logging.getLogger('connexion.operation').setLevel('ERROR') options = { "swagger_ui": True } specification_dir = os.path.join(os.path.dirname(__file__), '..', 'auth_server', 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options) app.app.cleanup_ctx.extend([ get_public_key ]) db.init_app(app.app, config=dict( host=Const.DB_HOST, port=Const.DB_PORT, user=Const.DB_USER, password=Const.DB_PASSWORD, database=Const.DB_NAME )) app.add_api('openapi.yaml', pythonic_params=True, pass_context_arg_name='request') fernet_key = fernet.Fernet.generate_key() Const.SESSION_KEY = fernet_key secret_key = base64.urlsafe_b64decode(fernet_key) setup(app.app, EncryptedCookieStorage(secret_key, cookie_name='auth_session')) return loop.run_until_complete(aiohttp_client(app.app))
def create_connexion_app(): """Create and configure a connexion app.""" settings = get_settings() app_options = { "import_name": __name__, "port": settings["PORT"], "specification_dir": settings["SPECIFICATION_DIR"], "debug": settings["DEBUG"], "options": { "swagger_ui": True, "swagger_path": swagger_ui_3_path, }, } app = connexion.AioHttpApp(**app_options) # Add the specification file. app.add_api( settings["SPECIFICATION_FILE"], resolver=RestyResolver(settings["RESOLVER_MODULE_NAME"]), base_path="/api", ) # Add CORS support. # CORS(app.app) return app
def client(loop, aiohttp_client): logging.getLogger('connexion.operation').setLevel('ERROR') options = {"swagger_ui": True} specification_dir = os.path.join(os.path.dirname(__file__), '..', 'openapi_server', 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options) app.add_api('openapi.yaml', pass_context_arg_name='request') return loop.run_until_complete(aiohttp_client(app.app))
def main(): options = {"swagger_ui": True} specification_dir = os.path.join(os.path.dirname(__file__), 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options) app.add_api('openapi.yaml', arguments={'title': 'OpenAPI Petstore'}, pass_context_arg_name='request') app.run(port=8080)
def main(): options = {"swagger_ui": True} specification_dir = os.path.join(os.path.dirname(__file__), 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options) app.add_api('openapi.yaml', arguments={'title': 'Reference data and Mappings API'}, pythonic_params=True, pass_context_arg_name='request') app.run(port=8080)
def get_app(init_db: Callable = None, init_mq: Optional[Dict[str, Callable]] = None) -> connexion.AioHttpApp: app = connexion.AioHttpApp(__name__) api = app.add_api(os.path.join(os.getcwd(), API_SPECS_PATH), pass_context_arg_name='request', strict_validation=True) if init_db: app.app.on_startup.append(setup_db_base(init_db, api.subapp)) if isinstance(init_mq, dict): app.app.on_startup.append(setup_mq_base(init_mq, api.subapp)) return app
def create_app(): app = connexion.AioHttpApp(__name__, port=5000, specification_dir="", only_one_api=True) spec_path = Path(__file__).parent / "api-spec.yaml" spec, _ = load_api_spec(spec_path, version=__version__, components=[BaseType]) app.add_api( spec, options={"swagger_ui": True}, resolver=AppResolver(), pass_context_arg_name="request", ) aiohttp_app: aiohttp.web.Application = app.app aiohttp_app.add_routes([web.get("/", swagger_ui_redirect)]) return app
def client(loop, aiohttp_client, get_access_token): logging.getLogger('connexion.operation').setLevel('ERROR') options = {"swagger_ui": True} specification_dir = os.path.join(os.path.dirname(__file__), '..', 'airport_load_server', 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options) app.app.cleanup_ctx.extend([set_auth_public_key]) app.add_api('openapi.yaml', pythonic_params=True, pass_context_arg_name='request') return loop.run_until_complete(aiohttp_client(app.app))
def main(): options = {"swagger_ui": True} specification_dir = os.path.join(os.path.dirname(__file__), 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options) app.add_api('openapi.yaml', arguments={ 'title': 'An example of generating swagger via gRPC ecosystem.' }, pythonic_params=True, pass_context_arg_name='request') app.run(port=8080)
def create_app(test_db_uri: Optional[str] = None): app = connexion.AioHttpApp(__name__, port=5000, specification_dir="", only_one_api=True) config = Config() spec_path = Path(__file__).parent / "api-spec.yaml" spec, operation_parameters = load_api_spec(spec_path, version=__version__, components=[BaseType]) if config.SCRIPT_NAME: spec["servers"] = [{"url": config.SCRIPT_NAME}] app.add_api( spec, options={"swagger_ui": True, "middlewares": [compression_middleware, set_schema,]}, resolver=AppResolver(operation_parameters), pass_context_arg_name="request", ) aiohttp_app: aiohttp.web.Application = app.app aiohttp_app._client_max_size = config.MAX_REQUEST_SIZE aiohttp_app.add_routes([web.get("/", swaggr_ui_redirect)]) aiohttp_app["HTTPS"] = config.HTTPS aiohttp_app["config"] = config # register_login_handlers(aiohttp_app, config.AUTH_SERVICE_URL) cors_options = aiohttp_cors.ResourceOptions( allow_credentials=True, expose_headers="*", allow_headers="*", allow_methods=["DELETE", "GET", "PATCH", "POST"] ) origins = ["http://localhost:8080"] cors = aiohttp_cors.setup(app.app, defaults={origin: cors_options for origin in origins}) for route in app.app.router.routes(): cors.add(route) if config.SCRIPT_NAME: app.app._router = RouterSubpathMiddleware(app.app.router, config.SCRIPT_NAME or "") async def on_startup(app: web.Application): if test_db_uri: uri = test_db_uri else: uri = config.SQLALCHEMY_DATABASE_URI app["engine"] = await gino.create_engine(uri) from .models import db db.bind = app["engine"] aiohttp_app.on_startup.append(on_startup) return app
def main(): if START_DELAY > 0: print(f"Sleeping for {START_DELAY} seconds") time.sleep(START_DELAY) options = {"swagger_ui": True} specification_dir = os.path.join(os.path.dirname(__file__), 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options) app.app.cleanup_ctx.extend([set_auth_public_key]) app.add_api('openapi.yaml', arguments={'title': 'API to show passenger load in airports'}, pythonic_params=True, pass_context_arg_name='request') app.run(port=SERVER_PORT)
def main(): """ KGE Archive Web Services application entry point """ options = {"swagger_ui": True} specification_dir = path.join(path.dirname(__file__), 'openapi') app = connexion.AioHttpApp(__name__, specification_dir=specification_dir, options=options, server_args={"client_max_size": 256 * 1024**3}) app.add_api( 'openapi.yaml', arguments={ 'title': 'OpenAPI for the Biomedical Translator Knowledge Graph EXchange Archive. ' + 'Although this API is SmartAPI compliant, it will not normally be visible in the ' + 'Translator SmartAPI Registry since it is mainly meant to be accessed through ' + 'Registry indexed KGE File Sets, which will have distinct entries in the Registry.' }, pythonic_params=True, pass_context_arg_name='request') # See https://github.com/aio-libs/aiohttp-cors#usage # Enable CORS for all origins. cors = aiohttp_cors.setup(app.app, defaults={ "*": aiohttp_cors.ResourceOptions( allow_credentials=True, expose_headers="*", allow_headers="*", ) }) # Register all routers for CORS. for route in list(app.app.router.routes()): cors.add(route) KgeaSession.initialize(app.app) app.run(port=8080, server="aiohttp", use_default_access_log=True) KgeaSession.close_global_session()
def create_app(): """ Create an application instance for adev to pickup up Returns: aiohttp.web.Application instance """ app = connexion.AioHttpApp(__name__, specification_dir='specs/', port=8000) app.add_api( 'service.yaml', resolver=RestyResolver('api'), strict_validation=True, validate_responses=True, pass_context_arg_name= 'request' # aiohttp param to pass the context into each request - gets headers, etc ) return app.app
def setup_app(): app = connexion.AioHttpApp(__name__, specification_dir='swagger/') app.add_api('api.spec.yaml', resolver=RestyResolver('api')) cors = aiohttp_cors.setup(app.app, defaults={ "*": aiohttp_cors.ResourceOptions( allow_credentials=True, expose_headers="*", allow_headers="*", allow_methods=["GET", "POST", "PUT"]) }) for route in list(app.app.router.routes()): cors.add(route) return app
def main(): logger.info('Starting') loop = asyncio.get_event_loop() db = DBClient(loop.run_until_complete(asyncpg.create_pool(**configurations['db'])), logger) logger.info('Инициализация API') app = connexion.AioHttpApp(__name__, specification_dir=f'{BASE_DIR}/spec/',) api = app.add_api('openapi.yaml', validate_responses=True, strict_validation=True, resolver=RestyResolver('user_service.api.handlers'), pass_context_arg_name='request') api.subapp['db'] = db # Раз в 10 минут считаем балансы loop.create_task(subtract_balance(db, 600)) app.run(port=80) logger.info('Stopped')
def prepare_web_controllers(options: dict) -> connexion.AioHttpApp: specification_dir = os.path.join(os.path.dirname(__file__), "openapi") app = connexion.AioHttpApp( __name__, specification_dir=specification_dir, options=options, only_one_api=True, ) resolver = SpecTagsResolver( "{{ cookiecutter.pymodule }}.web.controllers", default_module_name="default_controller" ) # resolves the controller based on tags in the spec app.add_api( "openapi.yaml", arguments={"title": "{{ cookiecutter.project_name }}"}, pythonic_params=True, pass_context_arg_name="request", resolver=resolver, ) return app
def run_app(run=True, port=8080): """ runs the web application """ checkenv() log.debug("initiating application") cxapp = connexion.AioHttpApp( __name__, port=port, specification_dir="swagger/", ) allocate = cxapp.add_api( "allocate.yml", base_path="/api", pass_context_arg_name="request", ) allocate.subapp["websockets"] = weakref.WeakSet() allocate.subapp["redis"] = REDIS cxapp.app.on_startup.append(startup_daemons) cxapp.app.on_cleanup.append(cleanup_daemons) if run: return cxapp.run() return cxapp.app
def run_app(run=True, port=8080): """ runs the web application """ checkenv() log.debug("initiating application") cxapp = connexion.AioHttpApp( __name__, port=port, specification_dir="swagger/", ) heartbeats = cxapp.add_api( "heartbeats.yml", base_path="/api", pass_context_arg_name="request", ) heartbeats.subapp["websockets"] = weakref.WeakSet() heartbeats.subapp["redis"] = REDIS if run: return cxapp.run() return cxapp.app
def main(): options = {"swagger_ui": True} connexion_app = connexion.AioHttpApp(__name__, options=options, only_one_api=True) connexion_app.add_api('openapi.yaml', arguments={'title': 'url-shortener'}, pythonic_params=True, pass_context_arg_name='request') loop.run_until_complete(db_init(loop)) async def start_background_tasks(app): app['database_writes'] = asyncio.create_task(listen_for_writes(app)) async def cleanup_background_tasks(app): app['database_writes'].cancel() await app['database_writes'] connexion_app.app.on_startup.append(start_background_tasks) connexion_app.app.on_cleanup.append(cleanup_background_tasks) connexion_app.run(port=8080, debug=True)
def client(loop, aiohttp_client, base_test_config): logging.getLogger("connexion.operation").setLevel("ERROR") options = base_test_config["web"] specification_dir = os.path.join( os.path.dirname(__file__), "..", "..", "src", "{{ cookiecutter.pymodule }}", "openapi" ) app = connexion.AioHttpApp( __name__, specification_dir=specification_dir, options=options, only_one_api=True, ) resolver = SpecTagsResolver( "{{ cookiecutter.pymodule }}.web.controllers", default_module_name="default_controller" ) app.add_api( "openapi.yaml", pythonic_params=True, pass_context_arg_name="request", resolver=resolver, ) app_client = aiohttp_client(app.app) return loop.run_until_complete(app_client)
def start(foreground, root, config_file): """Run the Wazuh API. If another Wazuh API is running, this function fails. This function exits with 0 if successful or 1 if failed because the API was already running. Arguments --------- foreground : bool If the API must be daemonized or not root : bool If true, the daemon is run as root. Normally not recommended for security reasons config_file : str Path to the API config file """ import asyncio import logging import os import ssl import connexion import uvloop from aiohttp_cache import setup_cache import wazuh.security from api import __path__ as api_path # noinspection PyUnresolvedReferences from api import validator from api.api_exception import APIError from api.constants import CONFIG_FILE_PATH from api.middlewares import set_user_name, security_middleware, response_postprocessing, request_logging, \ set_secure_headers from api.uri_parser import APIUriParser from api.util import to_relative_path from wazuh.core import pyDaemonModule configuration.api_conf.update( configuration.read_yaml_config(config_file=config_file)) api_conf = configuration.api_conf security_conf = configuration.security_conf log_path = api_conf['logs']['path'] # Set up logger set_logging(log_path=log_path, debug_mode=api_conf['logs']['level'], foreground_mode=foreground) logger = logging.getLogger('wazuh-api') # Set correct permissions on api.log file if os.path.exists(os.path.join(common.wazuh_path, log_path)): os.chown(os.path.join(common.wazuh_path, log_path), common.wazuh_uid(), common.wazuh_gid()) os.chmod(os.path.join(common.wazuh_path, log_path), 0o660) # Configure https ssl_context = None if api_conf['https']['enabled']: try: # Generate SSL if it does not exist and HTTPS is enabled if not os.path.exists( api_conf['https']['key']) or not os.path.exists( api_conf['https']['cert']): logger.info( 'HTTPS is enabled but cannot find the private key and/or certificate. ' 'Attempting to generate them') private_key = configuration.generate_private_key( api_conf['https']['key']) logger.info( f"Generated private key file in WAZUH_PATH/{to_relative_path(api_conf['https']['key'])}" ) configuration.generate_self_signed_certificate( private_key, api_conf['https']['cert']) logger.info( f"Generated certificate file in WAZUH_PATH/{to_relative_path(api_conf['https']['cert'])}" ) # Load SSL context allowed_ssl_ciphers = { 'tls': ssl.PROTOCOL_TLS, 'tlsv1': ssl.PROTOCOL_TLSv1, 'tlsv1.1': ssl.PROTOCOL_TLSv1_1, 'tlsv1.2': ssl.PROTOCOL_TLSv1_2 } try: ssl_cipher = allowed_ssl_ciphers[api_conf['https'] ['ssl_cipher'].lower()] except (KeyError, AttributeError): # KeyError: invalid string value # AttributeError: invalid boolean value logger.error( str( APIError( 2003, details='SSL cipher is not valid. Allowed values: ' 'TLS, TLSv1, TLSv1.1, TLSv1.2'))) sys.exit(1) ssl_context = ssl.SSLContext(protocol=ssl_cipher) if api_conf['https']['use_ca']: ssl_context.verify_mode = ssl.CERT_REQUIRED ssl_context.load_verify_locations(api_conf['https']['ca']) ssl_context.load_cert_chain(certfile=api_conf['https']['cert'], keyfile=api_conf['https']['key']) except ssl.SSLError: logger.error( str( APIError( 2003, details= 'Private key does not match with the certificate'))) sys.exit(1) except IOError as e: if e.errno == 22: logger.error( str(APIError(2003, details='PEM phrase is not correct'))) elif e.errno == 13: logger.error( str( APIError( 2003, details= 'Ensure the certificates have the correct permissions' ))) else: print( 'Wazuh API SSL ERROR. Please, ensure if path to certificates is correct in the configuration ' f'file WAZUH_PATH/{to_relative_path(CONFIG_FILE_PATH)}') sys.exit(1) # Drop privileges to wazuh if not root: if api_conf['drop_privileges']: os.setgid(common.wazuh_gid()) os.setuid(common.wazuh_uid()) else: print(f"Starting API as root") # Foreground/Daemon if not foreground: pyDaemonModule.pyDaemon() pyDaemonModule.create_pid('wazuh-apid', os.getpid()) else: print(f"Starting API in foreground") # Load the SPEC file into memory to use as a reference for future calls wazuh.security.load_spec() # Set up API asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) app = connexion.AioHttpApp(__name__, host=api_conf['host'], port=api_conf['port'], specification_dir=os.path.join( api_path[0], 'spec'), options={ "swagger_ui": False, 'uri_parser_class': APIUriParser }, only_one_api=True) app.add_api('spec.yaml', arguments={ 'title': 'Wazuh API', 'protocol': 'https' if api_conf['https']['enabled'] else 'http', 'host': api_conf['host'], 'port': api_conf['port'] }, strict_validation=True, validate_responses=False, pass_context_arg_name='request', options={ "middlewares": [ response_postprocessing, set_user_name, security_middleware, request_logging, set_secure_headers ] }) # Enable CORS if api_conf['cors']['enabled']: import aiohttp_cors cors = aiohttp_cors.setup( app.app, defaults={ api_conf['cors']['source_route']: aiohttp_cors.ResourceOptions( expose_headers=api_conf['cors']['expose_headers'], allow_headers=api_conf['cors']['allow_headers'], allow_credentials=api_conf['cors']['allow_credentials']) }) # Configure CORS on all endpoints. for route in list(app.app.router.routes()): cors.add(route) # Enable cache plugin if api_conf['cache']['enabled']: setup_cache(app.app) # API configuration logging logger.debug(f'Loaded API configuration: {api_conf}') logger.debug(f'Loaded security API configuration: {security_conf}') # Start API app.run(port=api_conf['port'], host=api_conf['host'], ssl_context=ssl_context, access_log_class=alogging.AccessLogger, use_default_access_log=True)
import connexion app = connexion.AioHttpApp(__name__) app.add_api("swagger/tuya-gateway.yaml", base_path="/api/v1") app.run(port=65080)
#!/usr/bin/env python3 import connexion from aiohttp import web async def post_greeting(name): return web.Response(text='Hello {name}'.format(name=name)) if __name__ == '__main__': app = connexion.AioHttpApp(__name__, port=9090, specification_dir='openapi/') app.add_api('helloworld-api.yaml', arguments={'title': 'Hello World Example'}) app.run()
def create_app(): """Create VmaaS application and servers""" init_logging() LOGGER.info("Starting (version %s).", VMAAS_VERSION) LOGGER.info('Hotcache enabled: %s', os.getenv("HOTCACHE_ENABLED", "YES")) with open('webapp.spec.yaml', 'rb') as specfile: SPEC = yaml.safe_load(specfile) # pylint: disable=invalid-name @web.middleware async def timing_middleware(request, handler, **kwargs): """ Middleware that handles timing of requests""" start_time = time.time() if asyncio.iscoroutinefunction(handler): res = await handler(request, **kwargs) else: res = handler(request, **kwargs) duration = (time.time() - start_time) # (0) /(1) /(2) /(3) # /api /v1 /updates const_path = '/'.join(request.path.split('/')[:4]) REQUEST_TIME.labels(request.method, const_path).observe(duration) REQUEST_COUNTS.labels(request.method, const_path, res.status).inc() return res @web.middleware async def error_formater(request, handler, **kwargs): #pylint: disable=broad-except def build_error(detail, status): errors = {"detail": detail, "status": status} return {"errors": [errors]} res = await handler(request, **kwargs) try: if res.status >= 400: original_error = loads(res.body) better_error = build_error(original_error["detail"], original_error["status"]) return web.json_response(better_error, status=res.status) return res except TypeError: # The error response is not made by connexion better_error = build_error(original_error, res.status) return web.json_response(better_error, status=res.status) except Exception as _: LOGGER.exception(_) return web.json_response(build_error("Internal server error", 500), status=500) app = connexion.AioHttpApp(__name__, options={ 'swagger_ui': True, 'openapi_spec_path': '/openapi.json', 'middlewares': [error_formater, timing_middleware] }) def metrics(request, **kwargs): #pylint: disable=unused-argument """Provide current prometheus metrics""" # /metrics API shouldn't be visible in the API documentation, # hence it's added here in the create_app step return web.Response(text=generate_latest().decode('utf-8')) async def on_prepare(request, response): #pylint: disable=unused-argument """Hook for preparing new responses""" response.headers["Access-Control-Allow-Origin"] = "*" response.headers["Access-Control-Allow-Headers"] = "Content-Type" app.app.on_response_prepare.append(on_prepare) app.app.router.add_get("/metrics", metrics) app.add_api(SPEC, resolver=connexion.RestyResolver('app'), validate_responses=False, strict_validation=False, base_path='/api', pass_context_arg_name='request' ) BaseHandler.db_cache = Cache() load_cache_to_apis() return app
import connexion import aiohttp import logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) if __name__ == "__main__": app = connexion.AioHttpApp(__name__, port=8000) app._only_one_api = True app._api_added = False app.add_api("recommendations.openapi") aiohttp.web.run_app(app.app, port=8000, access_log=logger)
import logging import connexion from service import database from service import middlewares LOG = logging.getLogger(__name__) connexion_app = connexion.AioHttpApp( __name__, only_one_api=True, options={ 'swagger_ui': True, 'server_spec': True, 'debug': True, 'middlewares': middlewares.get(), }, ) connexion_app.add_api( 'swagger.yaml', strict_validation=True, validate_responses=True, pythonic_params=True, ) application = connexion_app.app application.cleanup_ctx.append(database.get_db_engine)
def create_app(): """Create VmaaS application and servers""" init_logging() LOGGER.info("Starting (version %s).", VMAAS_VERSION) with open('webapp.spec.yaml', 'rb') as specfile: SPEC = yaml.safe_load(specfile) # pylint: disable=invalid-name SPEC['info']['version'] = VMAAS_VERSION @web.middleware async def timing_middleware(request, handler, **kwargs): """ Middleware that handles timing of requests""" start_time = time.time() if asyncio.iscoroutinefunction(handler): res = await handler(request, **kwargs) else: res = handler(request, **kwargs) duration = (time.time() - start_time) # (0) /(1) /(2) /(3) # /api /v1 /updates const_path = '/'.join(request.path.split('/')[:4]) REQUEST_TIME.labels(request.method, const_path).observe(duration) REQUEST_COUNTS.labels(request.method, const_path, res.status).inc() return res @web.middleware async def gzip_middleware(request, handler, **kwargs): """ Middleware that compress response using gzip""" res = await handler(request, **kwargs) header = 'Accept-Encoding' if header in request.headers and "gzip" in request.headers[header]: gzipped_body = gzip.compress(res.body, compresslevel=GZIP_COMPRESS_LEVEL) res.body = gzipped_body res.headers["Content-Encoding"] = "gzip" return res @web.middleware async def error_handler(request, handler, **kwargs): def format_error(detail, status): res = {} res["type"] = "about:blank" res["detail"] = detail res["status"] = status return res res = await handler(request, **kwargs) if res.status >= 400: body = loads(res.body) better_error = format_error(body, res.status) return web.json_response(better_error, status=res.status) return res middlewares = [] if GZIP_RESPONSE_ENABLE: middlewares.append(gzip_middleware) middlewares.extend([error_handler, timing_middleware]) app = connexion.AioHttpApp(__name__, options={ 'swagger_ui': True, 'openapi_spec_path': '/openapi.json', 'middlewares': middlewares }) def metrics(request, **kwargs): # pylint: disable=unused-argument """Provide current prometheus metrics""" # /metrics API shouldn't be visible in the API documentation, # hence it's added here in the create_app step return web.Response(text=generate_latest().decode('utf-8')) async def on_prepare(request, response): # pylint: disable=unused-argument """Hook for preparing new responses""" response.headers["Access-Control-Allow-Origin"] = "*" response.headers["Access-Control-Allow-Headers"] = "Content-Type" app.app.on_response_prepare.append(on_prepare) app.app.router.add_get("/metrics", metrics) app.add_api(SPEC, resolver=connexion.RestyResolver('app'), validate_responses=False, strict_validation=False, base_path='/api', pass_context_arg_name='request') BaseHandler.db_cache = Cache() load_cache_to_apis() return app