import os from os import environ, path from datetime import timedelta import redis from common.utils.prompt_loader import load_prompt_templates basedir = path.abspath(path.dirname(__file__)) class Config(object): DEBUG = False DEVELOPMENT = False SECRET_KEY = environ.get('SECRET_KEY') COMPONENT_NAME = environ.get('COMPONENT_NAME') # Database Settings DB_HOST = environ.get('DB_HOST') DB_USER = environ.get('DB_USER') DB_PASS = environ.get('DB_PASS') DB_NAME = environ.get('DB_NAME') DB_PORT = environ.get('DB_PORT') SQLALCHEMY_DATABASE_URI = f'postgresql+pg8000://{DB_USER}:{DB_PASS}@{DB_HOST}:{DB_PORT}/{DB_NAME}' SQLALCHEMY_BINDS = {'public': SQLALCHEMY_DATABASE_URI} WTF_CSRF_ENABLED = True WTF_CSRF_TIME_LIMIT = None WTF_CSRF_SSL_STRICT = False # Set to True if using HTTPS # flask-security-too settings # SECURITY_URL_PREFIX = '/admin' SECURITY_LOGIN_URL = '/admin/login' SECURITY_LOGOUT_URL = '/admin/logout' # SECURITY_REGISTER_URL = '/admin/register' # SECURITY_RESET_URL = '/admin/reset' # SECURITY_CHANGE_URL = '/admin/change' # SECURITY_POST_LOGIN_VIEW = '/admin/user/tenant_overview' # SECURITY_POST_LOGOUT_VIEW = '/admin' # SECURITY_POST_REGISTER_VIEW = '/admin/user/tenant_overview' # SECURITY_POST_RESET_VIEW = '/admin/login' # SECURITY_POST_CHANGE_VIEW = '/admin/login' # SECURITY_BLUEPRINT_NAME = 'security_bp' SECURITY_PASSWORD_SALT = environ.get('SECURITY_PASSWORD_SALT') SECURITY_CONFIRMABLE = True SECURITY_TRACKABLE = True SECURITY_PASSWORD_COMPLEXITY_CHECKER = 'zxcvbn' SECURITY_POST_LOGIN_VIEW = '/user/tenant_overview' SECURITY_RECOVERABLE = True SECURITY_EMAIL_SENDER = "eveai_super@flow-it.net" SECURITY_EMAIL_SUBJECT_PASSWORD_RESET = 'Reset Your Password' SECURITY_EMAIL_SUBJECT_PASSWORD_NOTICE = 'Your Password Has Been Reset' SECURITY_EMAIL_PLAINTEXT = False SECURITY_EMAIL_HTML = True SECURITY_SESSION_PROTECTION = 'basic' # of 'basic' als 'strong' problemen geeft SECURITY_REMEMBER_TOKEN_VALIDITY = timedelta(minutes=60) # Zelfde als session lifetime SECURITY_AUTO_LOGIN_AFTER_CONFIRM = True SECURITY_AUTO_LOGIN_AFTER_RESET = True # Ensure Flask-Security-Too is handling CSRF tokens when behind a proxy SECURITY_CSRF_PROTECT_MECHANISMS = ['session'] SECURITY_CSRF_COOKIE_NAME = 'XSRF-TOKEN' SECURITY_CSRF_HEADER = 'X-XSRF-TOKEN' WTF_CSRF_CHECK_DEFAULT = False # file upload settings MAX_CONTENT_LENGTH = 50 * 1024 * 1024 # supported languages SUPPORTED_LANGUAGE_DETAILS = { "English": { "iso 639-1": "en", "iso 639-2": "eng", "iso 639-3": "eng", "flag": "🇬🇧" }, "French": { "iso 639-1": "fr", "iso 639-2": "fre", # of 'fra' "iso 639-3": "fra", "flag": "🇫🇷" }, "German": { "iso 639-1": "de", "iso 639-2": "ger", # of 'deu' "iso 639-3": "deu", "flag": "🇩🇪" }, "Spanish": { "iso 639-1": "es", "iso 639-2": "spa", "iso 639-3": "spa", "flag": "🇪🇸" }, "Italian": { "iso 639-1": "it", "iso 639-2": "ita", "iso 639-3": "ita", "flag": "🇮🇹" }, "Portuguese": { "iso 639-1": "pt", "iso 639-2": "por", "iso 639-3": "por", "flag": "🇵🇹" }, "Dutch": { "iso 639-1": "nl", "iso 639-2": "dut", # of 'nld' "iso 639-3": "nld", "flag": "🇳🇱" }, "Russian": { "iso 639-1": "ru", "iso 639-2": "rus", "iso 639-3": "rus", "flag": "🇷🇺" }, "Chinese": { "iso 639-1": "zh", "iso 639-2": "chi", # of 'zho' "iso 639-3": "zho", "flag": "🇨🇳" }, "Japanese": { "iso 639-1": "ja", "iso 639-2": "jpn", "iso 639-3": "jpn", "flag": "🇯🇵" }, "Korean": { "iso 639-1": "ko", "iso 639-2": "kor", "iso 639-3": "kor", "flag": "🇰🇷" }, "Arabic": { "iso 639-1": "ar", "iso 639-2": "ara", "iso 639-3": "ara", "flag": "🇸🇦" }, "Hindi": { "iso 639-1": "hi", "iso 639-2": "hin", "iso 639-3": "hin", "flag": "🇮🇳" }, } # Afgeleide taalconstanten SUPPORTED_LANGUAGES = [lang_details["iso 639-1"] for lang_details in SUPPORTED_LANGUAGE_DETAILS.values()] SUPPORTED_LANGUAGES_FULL = list(SUPPORTED_LANGUAGE_DETAILS.keys()) SUPPORTED_LANGUAGE_ISO639_1_LOOKUP = {lang_details["iso 639-1"]: lang_name for lang_name, lang_details in SUPPORTED_LANGUAGE_DETAILS.items()} # supported currencies SUPPORTED_CURRENCIES = ['€', '$'] # supported LLMs # SUPPORTED_EMBEDDINGS = ['openai.text-embedding-3-small', 'openai.text-embedding-3-large', 'mistral.mistral-embed'] SUPPORTED_EMBEDDINGS = ['mistral.mistral-embed'] SUPPORTED_LLMS = ['mistral.mistral-large-latest', 'mistral.mistral-medium_latest', 'mistral.mistral-small-latest'] # Annotation text chunk length ANNOTATION_TEXT_CHUNK_LENGTH = 10000 # Environemnt Loaders OPENAI_API_KEY = environ.get('OPENAI_API_KEY') MISTRAL_API_KEY = environ.get('MISTRAL_API_KEY') # Celery settings CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_ACCEPT_CONTENT = ['json'] CELERY_TIMEZONE = 'UTC' CELERY_ENABLE_UTC = True # SocketIO settings # SOCKETIO_ASYNC_MODE = 'threading' # SOCKETIO_ASYNC_MODE = 'gevent' # Session Settings SESSION_TYPE = 'redis' SESSION_PERMANENT = True SESSION_USE_SIGNER = True PERMANENT_SESSION_LIFETIME = timedelta(minutes=60) SESSION_REFRESH_EACH_REQUEST = True SESSION_COOKIE_NAME = f'{COMPONENT_NAME}_session' SESSION_COOKIE_DOMAIN = None # Laat Flask dit automatisch bepalen SESSION_COOKIE_PATH = '/' SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SECURE = False # True voor production met HTTPS SESSION_COOKIE_SAMESITE = 'Lax' REMEMBER_COOKIE_SAMESITE = 'strict' SESSION_KEY_PREFIX = f'{COMPONENT_NAME}_' # JWT settings JWT_SECRET_KEY = environ.get('JWT_SECRET_KEY') JWT_ACCESS_TOKEN_EXPIRES = timedelta(hours=1) # Set token expiry to 1 hour JWT_ACCESS_TOKEN_EXPIRES_DEPLOY = timedelta(hours=24) # Set long-lived token for deployment # API Encryption API_ENCRYPTION_KEY = environ.get('API_ENCRYPTION_KEY') # Fallback Algorithms FALLBACK_ALGORITHMS = [ "RAG_TENANT", "RAG_WIKIPEDIA", "RAG_GOOGLE", "LLM" ] # Interaction algorithms INTERACTION_ALGORITHMS = { "RAG_TENANT": {"name": "RAG_TENANT", "description": "Algorithm using only information provided by the tenant"}, "RAG_WIKIPEDIA": {"name": "RAG_WIKIPEDIA", "description": "Algorithm using information provided by Wikipedia"}, "RAG_GOOGLE": {"name": "RAG_GOOGLE", "description": "Algorithm using information provided by Google"}, "LLM": {"name": "LLM", "description": "Algorithm using information integrated in the used LLM"} } # Email settings for API key notifications PROMOTIONAL_IMAGE_URL = 'https://askeveai.com/wp-content/uploads/2024/07/Evie-Call-scaled.jpg' # Replace with your actual URL # Langsmith settings LANGCHAIN_TRACING_V2 = True LANGCHAIN_ENDPOINT = 'https://api.smith.langchain.com' LANGCHAIN_PROJECT = "eveai" TENANT_TYPES = ['Active', 'Demo', 'Inactive', 'Test'] # The maximum number of seconds allowed for audio compression (to save resources) MAX_COMPRESSION_DURATION = 60*10 # 10 minutes # The maximum number of seconds allowed for transcribing audio MAX_TRANSCRIPTION_DURATION = 60*10 # 10 minutes # Maximum CPU usage for a compression task COMPRESSION_CPU_LIMIT = 50 # Delay between compressing chunks in seconds COMPRESSION_PROCESS_DELAY = 1 # WordPress Integration Settings WORDPRESS_PROTOCOL = environ.get('WORDPRESS_PROTOCOL', 'http') WORDPRESS_HOST = environ.get('WORDPRESS_HOST', 'host.docker.internal') WORDPRESS_PORT = environ.get('WORDPRESS_PORT', '10003') WORDPRESS_BASE_URL = f"{WORDPRESS_PROTOCOL}://{WORDPRESS_HOST}:{WORDPRESS_PORT}" EXTERNAL_WORDPRESS_BASE_URL = 'localhost:10003' # Prometheus PUSH Gataway PUSH_GATEWAY_HOST = environ.get('PUSH_GATEWAY_HOST', 'pushgateway') PUSH_GATEWAY_PORT = environ.get('PUSH_GATEWAY_PORT', '9091') PUSH_GATEWAY_URL = f"{PUSH_GATEWAY_HOST}:{PUSH_GATEWAY_PORT}" # Scaleway parameters SW_EMAIL_ACCESS_KEY = environ.get('SW_EMAIL_ACCESS_KEY') SW_EMAIL_SECRET_KEY = environ.get('SW_EMAIL_SECRET_KEY') SW_EMAIL_SENDER = environ.get('SW_EMAIL_SENDER') SW_EMAIL_NAME = environ.get('SW_EMAIL_NAME') SW_PROJECT = environ.get('SW_PROJECT') # Entitlement Constants ENTITLEMENTS_MAX_PENDING_DAYS = 5 # Defines the maximum number of days a pending entitlement can be active # Content Directory for static content like the changelog, terms & conditions, privacy statement, ... CONTENT_DIR = '/app/content' class DevConfig(Config): DEVELOPMENT = True DEBUG = True FLASK_DEBUG = True EXPLAIN_TEMPLATE_LOADING = False # Define the nginx prefix used for the specific apps EVEAI_APP_LOCATION_PREFIX = '/admin' EVEAI_CHAT_LOCATION_PREFIX = '/chat' CHAT_CLIENT_PREFIX = 'chat-client/chat/' # file upload settings # UPLOAD_FOLDER = '/app/tenant_files' # Redis Settings REDIS_URL = 'redis' REDIS_PORT = '6379' REDIS_BASE_URI = f'redis://{REDIS_URL}:{REDIS_PORT}' # Celery settings # eveai_app Redis Settings CELERY_BROKER_URL = f'{REDIS_BASE_URI}/0' CELERY_RESULT_BACKEND = f'{REDIS_BASE_URI}/0' # eveai_chat Redis Settings CELERY_BROKER_URL_CHAT = f'{REDIS_BASE_URI}/3' CELERY_RESULT_BACKEND_CHAT = f'{REDIS_BASE_URI}/3' # eveai_chat_workers cache Redis Settings CHAT_WORKER_CACHE_URL = f'{REDIS_BASE_URI}/4' # specialist execution pub/sub Redis Settings SPECIALIST_EXEC_PUBSUB = f'{REDIS_BASE_URI}/5' # eveai_model cache Redis setting MODEL_CACHE_URL = f'{REDIS_BASE_URI}/6' # Session settings SESSION_REDIS = redis.from_url(f'{REDIS_BASE_URI}/2') # PATH settings ffmpeg_path = '/usr/bin/ffmpeg' # OBJECT STORAGE OBJECT_STORAGE_TYPE = 'MINIO' OBJECT_STORAGE_TENANT_BASE = 'Bucket' # MINIO MINIO_ENDPOINT = 'minio:9000' MINIO_ACCESS_KEY = 'minioadmin' MINIO_SECRET_KEY = 'minioadmin' MINIO_USE_HTTPS = False class StagingConfig(Config): DEVELOPMENT = False DEBUG = True FLASK_DEBUG = True EXPLAIN_TEMPLATE_LOADING = False # Define the nginx prefix used for the specific apps EVEAI_APP_LOCATION_PREFIX = '/admin' EVEAI_CHAT_LOCATION_PREFIX = '/chat' CHAT_CLIENT_PREFIX = 'chat-client/chat/' # file upload settings # UPLOAD_FOLDER = '/app/tenant_files' # Redis Settings REDIS_URL = environ.get('REDIS_URL') REDIS_PORT = environ.get('REDIS_PORT', '6379') REDIS_USER = environ.get('REDIS_USER') REDIS_PASS = environ.get('REDIS_PASS') REDIS_BASE_URI = f'rediss://{REDIS_USER}:{REDIS_PASS}@{REDIS_URL}:{REDIS_PORT}' # Celery settings # eveai_app Redis Settings CELERY_BROKER_URL = f'{REDIS_BASE_URI}/0' CELERY_RESULT_BACKEND = f'{REDIS_BASE_URI}/0' # eveai_chat Redis Settings CELERY_BROKER_URL_CHAT = f'{REDIS_BASE_URI}/3' CELERY_RESULT_BACKEND_CHAT = f'{REDIS_BASE_URI}/3' # eveai_chat_workers cache Redis Settings CHAT_WORKER_CACHE_URL = f'{REDIS_BASE_URI}/4' # specialist execution pub/sub Redis Settings SPECIALIST_EXEC_PUBSUB = f'{REDIS_BASE_URI}/5' # eveai_model cache Redis setting MODEL_CACHE_URL = f'{REDIS_BASE_URI}/6' # Session settings SESSION_REDIS = redis.from_url(f'{REDIS_BASE_URI}/2') # PATH settings ffmpeg_path = '/usr/bin/ffmpeg' # OBJECT STORAGE OBJECT_STORAGE_TYPE = 'SCALEWAY' OBJECT_STORAGE_TENANT_BASE = 'Folder' OBJECT_STORAGE_BUCKET_NAME = 'eveai-staging' # MINIO MINIO_ENDPOINT = environ.get('MINIO_ENDPOINT') MINIO_ACCESS_KEY = environ.get('MINIO_ACCESS_KEY') MINIO_SECRET_KEY = environ.get('MINIO_SECRET_KEY') MINIO_USE_HTTPS = True class ProdConfig(Config): DEVELOPMENT = False DEBUG = False FLASK_DEBUG = False EXPLAIN_TEMPLATE_LOADING = False # SESSION SETTINGS SESSION_COOKIE_SECURE = True WTF_CSRF_SSL_STRICT = True # Set to True if using HTTPS # Define the nginx prefix used for the specific apps EVEAI_APP_LOCATION_PREFIX = '/admin' EVEAI_CHAT_LOCATION_PREFIX = '/chat' # flask-mailman settings MAIL_USERNAME = 'eveai_super@flow-it.net' MAIL_PASSWORD = '$6xsWGbNtx$CFMQZqc*' # file upload settings # UPLOAD_FOLDER = '/app/tenant_files' # Redis Settings REDIS_USER = environ.get('REDIS_USER') REDIS_PASS = environ.get('REDIS_PASS') REDIS_URL = environ.get('REDIS_URL') REDIS_PORT = environ.get('REDIS_PORT', '6379') REDIS_BASE_URI = f'redis://{REDIS_USER}:{REDIS_PASS}@{REDIS_URL}:{REDIS_PORT}' # Celery settings # eveai_app Redis Settings CELERY_BROKER_URL = f'{REDIS_BASE_URI}/0' CELERY_RESULT_BACKEND = f'{REDIS_BASE_URI}/0' # eveai_chat Redis Settings CELERY_BROKER_URL_CHAT = f'{REDIS_BASE_URI}/3' CELERY_RESULT_BACKEND_CHAT = f'{REDIS_BASE_URI}/3' # eveai_chat_workers cache Redis Settings CHAT_WORKER_CACHE_URL = f'{REDIS_BASE_URI}/4' # specialist execution pub/sub Redis Settings SPECIALIST_EXEC_PUBSUB = f'{REDIS_BASE_URI}/5' # Session settings SESSION_REDIS = redis.from_url(f'{REDIS_BASE_URI}/2') # PATH settings ffmpeg_path = '/usr/bin/ffmpeg' # MINIO MINIO_ENDPOINT = environ.get('MINIO_ENDPOINT') MINIO_ACCESS_KEY = environ.get('MINIO_ACCESS_KEY') MINIO_SECRET_KEY = environ.get('MINIO_SECRET_KEY') MINIO_USE_HTTPS = True def get_config(config_name='dev'): configs = { 'dev': DevConfig, 'staging': StagingConfig, 'prod': ProdConfig, 'default': DevConfig, } return configs.get(config_name)