"""Application. The API application is a `flask` application. It provides simple features such as registering a url for a specific handlers. """ import logging from ddtrace import tracer from flask import Flask, g from owslogger import flask_logger, logger from owsrequest import flask_request from owsresponse import response from owsresponse.adaptors.flask import flaskify from werkzeug.exceptions import InternalServerError from permissions import config app = Flask(config.SERVICE_NAME) flask_logger.setup( app, config.ENVIRONMENT, config.LOGGER_NAME, config.LOGGER_LEVEL, config.SERVICE_NAME, config.SERVICE_VERSION, exclude_paths=[config.HEALTH_CHECK], ) logger.setup( config.ENVIRONMENT, 'owsrequest', config.LOGGER_LEVEL, config.SERVICE_NAME, config.SERVICE_VERSION, ) logger.setup(config.ENVIRONMENT, 'neo4j', logging.INFO, config.SERVICE_NAME, config.SERVICE_VERSION) try: import uwsgi # noqa uwsgiRunning = True except ImportError: uwsgiRunning = False flask_request.setup( app, config.ENVIRONMENT, add_request_context=True, uwsgi_cache_enabled=uwsgiRunning ) @app.errorhandler(500) def exception_handler(error): """Handle error when uncaught exception is raised. Default exception handler. Note: Exception will also be sent to Sentry if config.SENTRY is set. Returns: flask.Response: A 500 response with JSON 'code' & 'message' payload. """ exception = ( error.original_exception if isinstance(error, InternalServerError) and error.original_exception is not None else error ) root_span = tracer.current_root_span() if root_span is not None: root_span.set_exc_info(type(exception), exception, exception.__traceback__) message = 'The server encountered an internal error ' 'and was unable to complete your request.' g.log.exception(exception) return flaskify(response.create_fatal_response(message)) @app.after_request def set_span_error_from_response(resp): """Set span error tags from direct 5xx responses with JSON payloads.""" if resp.status_code < 500: return resp root_span = tracer.current_root_span() if root_span is None or root_span.get_tag('error.message'): return resp try: payload = resp.get_json(silent=True) if isinstance(payload, dict): message = payload.get('message') if message: root_span.set_tag('error.message', message) error_code = payload.get('code') or response.error.ERROR_CODE_INTERNAL_ERROR root_span.set_tag('error.type', error_code) except Exception: pass return resp if config.ENVIRONMENT == config.DEV_ENVIRONMENT: from flasgger import Swagger app.config['SWAGGER'] = {'title': 'ows-permissions Documentation', 'uiversion': 2} try: Swagger(app, template_file=config.SWAGGER_FILE_PATH) except FileNotFoundError: print('Could not find swagger file at {}'.format(config.SWAGGER_FILE_PATH))