"""Application configuration.""" import os from os.path import abspath, dirname, join, pardir from typing import Any import sqlalchemy from audience_common.logger import LogFormat, configure_logging from environs import Env from secrets_manager.python_ext import PythonSecretsManager env = Env() # Load environment variables from a .env file if present dotenv_path = abspath(join(dirname(__file__), pardir, ".env")) env.read_env(dotenv_path, recurse=False) ENVIRONMENT = os.environ.get("Environment", default="dev") PROD_ENVIRONMENT = "prod" QA_ENVIRONMENT = "qa" TEST_ENVIRONMENT = "test" DEV_ENVIRONMENT = "dev" secrets_manager_client = PythonSecretsManager( application_context=False, environment=ENVIRONMENT, service_name="ows-product-staging", force_remote=(ENVIRONMENT not in (DEV_ENVIRONMENT, TEST_ENVIRONMENT)), ) APP_DEBUG: bool = os.environ.get("APP_DEBUG", default=False) # type:ignore SERVICE_NAME = "ows-product-staging" SERVICE_VERSION = "1.0.0" SENTRY_DSN = os.environ.get("SENTRY_DSN") or None REDIS_HOST = env.str("REDIS_HOST", default=None) REDIS_PORT = env.int("REDIS_PORT", default=6379) REDIS_SSL = env.bool("REDIS_SSL", default=True) CACHE_USE_REDIS = env.bool("CACHE_USE_REDIS", default=False) REDIS_CACHE_TTL = env.int("REDIS_CACHE_TTL_SECONDS", default=60 * 5) REDIS_SOCKET_TIMEOUT = env.float("REDIS_SOCKET_TIMEOUT", default=1.0) REDIS_SOCKET_CONNECT_TIMEOUT = env.float("REDIS_SOCKET_CONNECT_TIMEOUT", 10.0) POOL_CLASS: Any # Database config if ENVIRONMENT == TEST_ENVIRONMENT: DB_URL = "sqlite+aiosqlite://" POOL_CLASS = sqlalchemy.pool.StaticPool CONNECT_ARGS = {"check_same_thread": False} SQLALCHEMY_TRACK_MODIFICATIONS = False else: MYSQL_DB_PASSWORD = os.environ.get("MYSQL_DB_PASSWORD") or None if not MYSQL_DB_PASSWORD: MYSQL_DB_PASSWORD = secrets_manager_client.get_cred("MYSQL_DB_PASSWORD") POOL_CLASS = sqlalchemy.pool.QueuePool POOL_SIZE = 15 POOL_RECYCLE_MS = 3600 # Avoids connections going stale POOL_MAX_OVERFLOW = 0 POOL_PRE_PING = False DB_URL = ( "mysql+aiomysql://{user}:{password}@{host}/{db_name}?charset={charset}".format( user=os.environ.get("MYSQL_DB_USER"), password=MYSQL_DB_PASSWORD, host=os.environ.get("MYSQL_DB_HOST"), db_name=os.environ.get("MYSQL_DB_NAME"), charset="utf8mb4", ) ) LOGGING_CONFIG = { "version": 1, "disable_existing_loggers": False, "handlers": { "stream": { "level": "INFO", "class": "audience_common.logger.OwsStreamHandler", }, "null": { "level": "INFO", "class": "logging.NullHandler", }, }, "loggers": { "product_staging": { "handlers": ["stream"], "level": "INFO", }, "audience_common.logger.asgi.middleware": { "handlers": ["stream"], "level": "INFO", }, "uvicorn": { "handlers": ["stream"], "level": "INFO", }, "uvicorn.access": { "handlers": ["null"], "level": "INFO", }, "splitio": { "handlers": ["null"], "level": "INFO", }, }, } configure_logging( LOGGING_CONFIG, environment=ENVIRONMENT, service_name="ows-product-staging", service_version="1.0.0", log_format=LogFormat(os.environ.get("LOG_FORMAT", LogFormat.JSON)), logger_name="ows1", debug=APP_DEBUG, ) # Prevent third-party modules from generating sentry alerts. # This config will ignore ALL ERRORs for modules listed in IGNORED_SENTRY_LOGGERS. IGNORED_SENTRY_LOGGERS = {"splitio"} # Split.io configuration SPLITIO_LOCALHOST_ENV = "localhost" DEFAULT_SPLIT_FILE_PATH = "tests/.split" SPLIT_FILE_PATH = os.environ.get("SPLIT_FILE_PATH", DEFAULT_SPLIT_FILE_PATH) SPLITIO_API_KEY = os.environ.get("SPLITIO_API_KEY") SPLITIO_IMPRESSIONS_MODE = os.environ.get("SPLITIO_IMPRESSIONS_MODE", "optimized") SPLITIO_PREFORKED_INIT = env.bool("SPLITIO_PREFORKED_INIT", default=False) # AWS region configuration DEFAULT_AWS_REGION = "us-east-1" AWS_REGION = os.environ.get("AWS_REGION", DEFAULT_AWS_REGION) TOKEN_STARTER = PROD_ENVIRONMENT if ENVIRONMENT == PROD_ENVIRONMENT else QA_ENVIRONMENT # M2M token M2M_TOKEN_SECRET_KEY_NAME = f"{TOKEN_STARTER}/lambda-jwt-refresh/jwt_token" M2M_TOKEN_SECRET_EXPIRY_KEY_NAME = ( f"{TOKEN_STARTER}/lambda-jwt-refresh/jwt_token_expiration" ) OWS_PRODUCT_STAGING_S3_BUCKET = os.environ.get( "OWS_PRODUCT_STAGING_S3_BUCKET", "qa-ows-product-staging" ) # neo4j settings NEO4J_URL = os.environ.get("NEO4J_URL") NEO4J_USERNAME = os.environ.get("NEO4J_USERNAME") NEO4J_PASSWORD = os.environ.get("NEO4J_PASSWORD") or None NEO4J_DATABASE_NAME = os.environ.get("NEO4J_DATABASE_NAME", "graph.db") if not NEO4J_PASSWORD: NEO4J_PASSWORD = secrets_manager_client.get_cred("NEO4J_PASSWORD") BULK_SESSION_INGEST_SFN_ARN = os.environ.get("BULK_SESSION_INGEST_SFN_ARN") BULK_SESSION_INGEST_QUEUE_SFN_ARN = os.environ.get("BULK_SESSION_INGEST_QUEUE_SFN_ARN") EXPORT_CATALOG_LAMBDA_ARN = os.environ.get("EXPORT_CATALOG_LAMBDA_ARN") TRIGGER_INGEST_LAMBDA_ARN = os.environ.get("TRIGGER_INGEST_LAMBDA_ARN") BULK_SESSION_INGEST_QUEUE_MAX_CONCURRENCY = int( os.environ.get("BULK_SESSION_INGEST_QUEUE_MAX_CONCURRENCY", 3) ) INGESTION_SQS_QUEUE_URL = os.environ.get("INGESTION_SQS_QUEUE_URL") INGESTION_SQS_QUEUE_MESSAGE_GROUP_ID = "ingestion-queue-message-group-id" INGESTION_SQS_QUEUE_MESSAGE_PROCESSING_TIME = 19 FINALIZE_SQS_QUEUE_URL = os.environ.get("FINALIZE_SQS_QUEUE_URL") # Google auth DYNAMODB_TABLE_NAME = os.environ.get("DYNAMODB_TABLE_NAME") KMS_KEY_ID = os.environ.get("KMS_KEY_ID") GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID") GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET") if not GOOGLE_CLIENT_SECRET: GOOGLE_CLIENT_SECRET = secrets_manager_client.get_cred("GOOGLE_CLIENT_SECRET") GOOGLE_TRANSFER_JOB_NAME = "google-drive-asset-transfer" SPOTIFY_EXPORT_CATALOG_JOB_NAME = "export-spotify-catalog" # Spotify SPOTIFY_API_CLIENT_ID = os.environ.get("SPOTIFY_API_CLIENT_ID") SPOTIFY_API_CLIENT_SECRET = os.environ.get("SPOTIFY_API_CLIENT_SECRET") if not SPOTIFY_API_CLIENT_SECRET: SPOTIFY_API_CLIENT_SECRET = secrets_manager_client.get_cred( "SPOTIFY_API_CLIENT_SECRET" )