import colors import redis as redis import sentry_sdk import logging from flask import Flask, request from flask_caching import Cache from flask_compress import Compress from flask_cors import CORS from flask_marshmallow import Marshmallow from sentry_sdk.integrations.flask import FlaskIntegration from sentry_sdk.utils import BadDsn from werkzeug.debug import DebuggedApplication import config from utils.flask_utils import CustomResponse, swagger_force_type from utils.flusk_etag import handle_etag from utils.json_encoder import CustomJSONEncoder from elasticsearch import Elasticsearch, RequestsHttpConnection if config.SENTRY_DSN: try: sentry_sdk.init(dsn=config.SENTRY_DSN, environment=config.SENTRY_ENV, integrations=[FlaskIntegration()]) except BadDsn: pass def create_app(): app = Flask(config.SERVICE_NAME) app.json_encoder = CustomJSONEncoder app.config.from_object(config.runtime_config()) app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False app.config['APISPEC_FORMAT_RESPONSE'] = swagger_force_type app.response_class = CustomResponse compress = Compress() compress.init_app(app) app.after_request(handle_etag) return app app = create_app() elastic_search = Elasticsearch( hosts=[{"host": config.ELASTIC_HOST, "port": config.ELASTIC_PORT}], use_ssl=config.ELASTIC_SSL, verify_certs=True, connection_class=RequestsHttpConnection, ) ma = Marshmallow(app) cache = Cache(app) redis_cache = redis.Redis(host=config.REDIS_HOST) if app.debug: app.config["SQLALCHEMY_ECHO"] = True app.wsgi_app = DebuggedApplication(app.wsgi_app, evalex=True) CORS(app, origins=config.ALLOWED_ORIGINS) @app.before_first_request def setup_logging(): if not app.debug: app.logger.addHandler(logging.StreamHandler()) app.logger.setLevel(logging.INFO) @app.after_request def log_request(response): if request.path == "/favicon.ico": return response elif request.path.startswith("/static"): return response ip = request.headers.get("X-Forwarded-For", request.remote_addr) host = request.host.split(":", 1)[0] args = dict(request.args) log_params = [ ("[{}] {}".format(request.method, request.path), "blue"), ("Code: {}".format(response.status_code), "yellow"), ("Host: {} ({})".format(host, ip), "red"), ("Params: {}".format(args), "blue"), ] if config.runtime_config().DEBUG: parts = [colors.color("{}".format(value), fg=color) for value, color in log_params] else: parts = [value for value, color in log_params] app.logger.info(" ".join(parts)) return response