"""Application. The API is a Flask application. It provides simple features such as registering a URL for specific handlers. """ from flask import Flask, g, request from flask_executor import Executor from owslogger import flask_logger, logger from owsrequest import flask_request from owsrequest.constants import headers as owsrequest_headers from snowflake_connector.snowflake_conn import set_default_sessionmaker from analytics import config app = Flask(config.SERVICE_NAME) exclude_paths = [config.HEALTH_CHECK_PATH] flask_logger.setup( app, config.ENVIRONMENT, config.LOGGER_NAME, config.LOGGER_LEVEL, config.SERVICE_NAME, config.SERVICE_VERSION, exclude_paths, True, True, ) logger.setup( config.ENVIRONMENT, config.LOGGER_NAME, config.LOGGER_LEVEL, "owsrequest", config.SERVICE_VERSION, None, True, ) try: import uwsgi # noqa uwsgiRunning = True except ImportError: uwsgiRunning = False flask_request.setup( app, config.ENVIRONMENT, add_request_context=True, label_profile=True, uwsgi_cache_enabled=uwsgiRunning, verify_access=True, rules_file="analytics/access_rules.yml", access_log_only=config.ONLY_LOG_ACCESS_ERRORS, exclude_paths=exclude_paths, ) @app.before_request def log_artist_profile_request(): # Observability trip-wire for the ArtistProfile removal workstream. # Queryable in Datadog as: # env:prod service:ows-analytics "ArtistProfile request received" # Delete this hook once ArtistProfile handling is fully removed. profile_type = request.headers.get(owsrequest_headers.ORCHARD_PROFILE_TYPE) if profile_type == owsrequest_headers.PROFILE_TYPE_ARTIST: g.log.warning( "ArtistProfile request received", resources={ "profile_id": request.headers.get( owsrequest_headers.ORCHARD_PROFILE_ID ), "path": request.path, "method": request.method, }, ) executor = Executor(app) sf_config = { "role": config.SNOWFLAKE_ROLE, "account": config.SNOWFLAKE_ACCOUNT, "user": config.SNOWFLAKE_USER, "password": "dummy_password", # we're using key pair auth, pk is passed in config.SNOWFLAKE_CONNECT_ARGS # noqa "database": config.SNOWFLAKE_DATABASE, "schema": config.SNOWFLAKE_SCHEMA, "warehouse": config.SNOWFLAKE_WAREHOUSE, "client_session_keep_alive": True, } # service-wide Snowflake connection pool settings set_default_sessionmaker( pool_size=config.SNOWFLAKE_POOL_SIZE, pool_recycle=config.SNOWFLAKE_POOL_RECYCLE, pool_pre_ping=config.SNOWFLAKE_POOL_PRE_PING, pool_reset_on_return=config.SNOWFLAKE_POOL_RESET_ON_RETURN, max_overflow=config.SNOWFLAKE_POOL_MAX_OVERFLOW, connect_args=config.SNOWFLAKE_CONNECT_ARGS, sf_config=sf_config, ) if config.ENVIRONMENT == config.DEV_ENVIRONMENT: from flasgger import Swagger app.config["SWAGGER"] = {"title": "ows-analytics 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))