#!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import json import logging import os import sys import boto3 from django.utils.termcolors import colorize from dotenv import load_dotenv logger = logging.getLogger(__name__) def main(): """Run administrative tasks.""" AWS_REGION_NAME = "us-east-2" AWS_SECRET_ID = "arn:aws:secretsmanager:us-east-2:734185074900:secret:studio-api-dev-envs-PUGU7a" env_name = os.getenv("ENV_NAME") or "dev" # Load local environment variables if .env exists load_dotenv() # Load development environment variables from AWS Secrets Manager. # Note values from .env file take precedence. if env_name == "dev": try: secrets_client = boto3.client("secretsmanager", region_name=AWS_REGION_NAME) secret_response = secrets_client.get_secret_value(SecretId=AWS_SECRET_ID) if "SecretString" in secret_response: secret_dict = json.loads(secret_response["SecretString"]) for k, v in secret_dict.items(): os.environ.setdefault(k, v) sys.stderr.write( f"Loaded environment variables for env_name={env_name} secret={AWS_SECRET_ID}\n" ) except Exception as e: sys.stderr.write( colorize( f"Failed to load environment variables from env_name={env_name} secret={AWS_SECRET_ID}. " f"Falling back to local values. Reason: {e}\n", fg="yellow", ) ) env_name = os.getenv("ENV_NAME") or "dev" # Exit early if we can't load configuration current_database_url = os.getenv("DATABASE_URL") suno_2_database_url = os.getenv("DATABASE_URL_2") if current_database_url is None or suno_2_database_url is None: sys.stderr.write( colorize( "Misconfigured: DATABASE_URL or DATABASE_URL_2 environment variable is not set.\n" "Please make sure you're logged into AWS and have correct permissions to access the secret.\n" "Run `aws sts get-caller-identity` to check your credentials.\n" "If you're not sure how to do this, please ask in the #pod-core channel on Slack.\n", fg="red", ) ) sys.exit(1) # if environment is staging or prod, skip the DB URL check # check if database url is pointing to the local database # this check primarily exists to prevent local migrations from being run against staging/prod DBs is_staging_or_prod = env_name == "staging" or env_name == "prod" is_running_locally = os.getenv("RUNNING_LOCALLY", False) if not is_staging_or_prod or is_running_locally: logger.info("Environment is not staging or prod. checking database url.") database_is_localhost = "@localhost" in current_database_url suno_2_database_is_localhost = "@localhost" in suno_2_database_url if not database_is_localhost or not suno_2_database_is_localhost: logger.warning( f"Warning: DATABASE_URL or DATABASE_URL_2 is set to non-localhost database '{current_database_url}' or '{suno_2_database_url}', expected localhost URL like 'postgresql://suno:suno@localhost/suno_studio'" ) # Exit the script if the database url is not pointing to the local database when doing database migrations invalid_args = ["migrate", "makemigrations", "migrate_all"] if any(arg in sys.argv for arg in invalid_args): logger.warning( f"Database URL is not pointing to the local database when running {invalid_args}. Exiting." ) sys.exit(1) os.environ.setdefault("DJANGO_SETTINGS_MODULE", "studio_api.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) from exc # Initialize feature flags from studio_api.bots.singletons import feature_flags feature_flags.initialize() execute_from_command_line(sys.argv) if __name__ == "__main__": main()