| import datetime as dt |
| import importlib.metadata |
| import json |
| import logging |
| import os |
| import pkgutil |
| import re |
| import shutil |
| import sys |
| import traceback |
| from pathlib import Path |
| from typing import Any, Optional |
| from uuid import uuid4 |
|
|
| import markdown |
| from bs4 import BeautifulSoup |
| from cryptography.hazmat.primitives import serialization |
|
|
| |
| |
| |
|
|
| |
| ENV_FILE_PATH = Path(__file__).resolve() |
|
|
| |
| OPEN_WEBUI_DIR = ENV_FILE_PATH.parent |
|
|
| |
| BACKEND_DIR = OPEN_WEBUI_DIR.parent |
|
|
| |
| BASE_DIR = BACKEND_DIR.parent |
|
|
| try: |
| from dotenv import find_dotenv, load_dotenv |
|
|
| load_dotenv(find_dotenv(str(BASE_DIR / '.env'))) |
| except ImportError: |
| print('dotenv not installed, skipping...') |
|
|
| DOCKER = os.getenv('DOCKER', 'False').lower() == 'true' |
|
|
| USE_CUDA = os.getenv('USE_CUDA_DOCKER', 'false') |
| DEVICE_TYPE = 'cpu' |
| _cuda_error: Optional[str] = None |
|
|
| if USE_CUDA.lower() == 'true': |
| try: |
| import torch |
|
|
| if not torch.cuda.is_available(): |
| raise RuntimeError('CUDA not available') |
| DEVICE_TYPE = 'cuda' |
| except Exception as exc: |
| _cuda_error = f'CUDA unavailable (USE_CUDA_DOCKER=true), falling back to CPU: {exc}' |
| os.environ['USE_CUDA_DOCKER'] = 'false' |
| USE_CUDA = 'false' |
|
|
| if sys.platform == 'darwin' and DEVICE_TYPE == 'cpu': |
| try: |
| import torch |
|
|
| if torch.backends.mps.is_available() and torch.backends.mps.is_built(): |
| DEVICE_TYPE = 'mps' |
| except Exception: |
| pass |
|
|
| |
| |
| |
|
|
| _LEVEL_MAP = { |
| 'DEBUG': 'debug', |
| 'INFO': 'info', |
| 'WARNING': 'warn', |
| 'ERROR': 'error', |
| 'CRITICAL': 'fatal', |
| } |
|
|
|
|
| class JSONFormatter(logging.Formatter): |
| """Format log records as single-line JSON objects for structured logging.""" |
|
|
| def format(self, record: logging.LogRecord) -> str: |
| log_entry: dict[str, Any] = { |
| 'ts': dt.datetime.fromtimestamp(record.created, tz=dt.UTC).isoformat(timespec='milliseconds'), |
| 'level': _LEVEL_MAP.get(record.levelname, record.levelname.lower()), |
| 'msg': record.getMessage(), |
| 'caller': record.name, |
| } |
|
|
| if record.exc_info and record.exc_info[0] is not None: |
| log_entry['error'] = ''.join(traceback.format_exception(*record.exc_info)).rstrip() |
| elif record.exc_text: |
| log_entry['error'] = record.exc_text |
|
|
| if record.stack_info: |
| log_entry['stacktrace'] = record.stack_info |
|
|
| return json.dumps(log_entry, ensure_ascii=False, default=str) |
|
|
|
|
| LOG_FORMAT = os.getenv('LOG_FORMAT', '').lower() |
|
|
| GLOBAL_LOG_LEVEL = os.getenv('GLOBAL_LOG_LEVEL', '').upper() |
| if GLOBAL_LOG_LEVEL in logging.getLevelNamesMapping(): |
| _log_cfg: dict[str, Any] = {'level': GLOBAL_LOG_LEVEL, 'force': True} |
| if LOG_FORMAT == 'json': |
| _json_handler = logging.StreamHandler(sys.stdout) |
| _json_handler.setFormatter(JSONFormatter()) |
| _log_cfg['handlers'] = [_json_handler] |
| else: |
| _log_cfg['stream'] = sys.stdout |
| logging.basicConfig(**_log_cfg) |
| else: |
| GLOBAL_LOG_LEVEL = 'INFO' |
|
|
| log = logging.getLogger(__name__) |
| log.info('GLOBAL_LOG_LEVEL: %s', GLOBAL_LOG_LEVEL) |
|
|
| if _cuda_error: |
| log.error(_cuda_error) |
| _cuda_error = None |
|
|
| SRC_LOG_LEVELS = {} |
|
|
| |
| |
| |
|
|
| ENV = os.getenv('ENV', 'dev') |
|
|
| FROM_INIT_PY = os.getenv('FROM_INIT_PY', 'False').lower() == 'true' |
|
|
| if FROM_INIT_PY: |
| PACKAGE_DATA = {'version': importlib.metadata.version('open-webui')} |
| else: |
| try: |
| PACKAGE_DATA = json.loads((BASE_DIR / 'package.json').read_text()) |
| except Exception: |
| PACKAGE_DATA = {'version': '0.0.0'} |
|
|
| VERSION = PACKAGE_DATA['version'] |
|
|
|
|
| DEPLOYMENT_ID = os.getenv('DEPLOYMENT_ID', '') |
| INSTANCE_ID = os.getenv('INSTANCE_ID', str(uuid4())) |
|
|
| ENABLE_DB_MIGRATIONS = os.getenv('ENABLE_DB_MIGRATIONS', 'True').lower() == 'true' |
|
|
|
|
| |
| def parse_section(section): |
| items = [] |
| for li in section.find_all('li'): |
| |
| raw_html = str(li) |
|
|
| |
| text = li.get_text(separator=' ', strip=True) |
|
|
| |
| parts = text.split(': ', 1) |
| title = parts[0].strip() if len(parts) > 1 else '' |
| content = parts[1].strip() if len(parts) > 1 else text |
|
|
| items.append({'title': title, 'content': content, 'raw': raw_html}) |
| return items |
|
|
|
|
| try: |
| changelog_path = BASE_DIR / 'CHANGELOG.md' |
| with open(str(changelog_path.absolute()), encoding='utf8') as file: |
| changelog_content = file.read() |
|
|
| except Exception: |
| changelog_content = (pkgutil.get_data('open_webui', 'CHANGELOG.md') or b'').decode() |
|
|
| |
| html_content = markdown.markdown(changelog_content) |
|
|
| |
| soup = BeautifulSoup(html_content, 'html.parser') |
|
|
| |
| changelog_json = {} |
|
|
| |
| for version in soup.find_all('h2'): |
| version_number = version.get_text().strip().split(' - ')[0][1:-1] |
| date = version.get_text().strip().split(' - ')[1] |
|
|
| version_data = {'date': date} |
|
|
| |
| current = version.find_next_sibling() |
|
|
| while current and current.name != 'h2': |
| if current.name == 'h3': |
| section_title = current.get_text().lower() |
| section_items = parse_section(current.find_next_sibling('ul')) |
| version_data[section_title] = section_items |
|
|
| |
| current = current.find_next_sibling() |
|
|
| changelog_json[version_number] = version_data |
|
|
| CHANGELOG = changelog_json |
|
|
| |
| |
| |
|
|
| DATA_DIR = Path(os.getenv('DATA_DIR', BACKEND_DIR / 'data')).resolve() |
|
|
| if FROM_INIT_PY: |
| NEW_DATA_DIR = Path(os.getenv('DATA_DIR', OPEN_WEBUI_DIR / 'data')).resolve() |
| NEW_DATA_DIR.mkdir(parents=True, exist_ok=True) |
|
|
| |
| if DATA_DIR.exists() and DATA_DIR != NEW_DATA_DIR: |
| log.info(f'Moving {DATA_DIR} to {NEW_DATA_DIR}') |
| for item in DATA_DIR.iterdir(): |
| dest = NEW_DATA_DIR / item.name |
| if item.is_dir(): |
| shutil.copytree(item, dest, dirs_exist_ok=True) |
| else: |
| shutil.copy2(item, dest) |
|
|
| |
| shutil.make_archive(DATA_DIR.parent / 'open_webui_data', 'zip', DATA_DIR) |
|
|
| |
| shutil.rmtree(DATA_DIR) |
|
|
| DATA_DIR = Path(os.getenv('DATA_DIR', OPEN_WEBUI_DIR / 'data')) |
|
|
| STATIC_DIR = Path(os.getenv('STATIC_DIR', OPEN_WEBUI_DIR / 'static')) |
|
|
| FONTS_DIR = Path(os.getenv('FONTS_DIR', OPEN_WEBUI_DIR / 'static' / 'fonts')) |
|
|
| FRONTEND_BUILD_DIR = Path(os.getenv('FRONTEND_BUILD_DIR', BASE_DIR / 'build')).resolve() |
|
|
| if FROM_INIT_PY: |
| FRONTEND_BUILD_DIR = Path(os.getenv('FRONTEND_BUILD_DIR', OPEN_WEBUI_DIR / 'frontend')).resolve() |
|
|
| |
| |
| |
|
|
| |
| if os.path.exists(f'{DATA_DIR}/ollama.db'): |
| |
| os.rename(f'{DATA_DIR}/ollama.db', f'{DATA_DIR}/webui.db') |
| log.info('Database migrated from Ollama-WebUI successfully.') |
| else: |
| pass |
|
|
| DATABASE_URL = os.getenv('DATABASE_URL', f'sqlite:///{DATA_DIR}/webui.db') |
|
|
| DATABASE_TYPE = os.getenv('DATABASE_TYPE') |
| DATABASE_USER = os.getenv('DATABASE_USER') |
| DATABASE_PASSWORD = os.getenv('DATABASE_PASSWORD') |
|
|
| DATABASE_CRED = '' |
| if DATABASE_USER: |
| DATABASE_CRED += f'{DATABASE_USER}' |
| if DATABASE_PASSWORD: |
| DATABASE_CRED += f':{DATABASE_PASSWORD}' |
|
|
| DB_VARS = { |
| 'db_type': DATABASE_TYPE, |
| 'db_cred': DATABASE_CRED, |
| 'db_host': os.getenv('DATABASE_HOST'), |
| 'db_port': os.getenv('DATABASE_PORT'), |
| 'db_name': os.getenv('DATABASE_NAME'), |
| } |
|
|
| if all(DB_VARS.values()): |
| DATABASE_URL = ( |
| f'{DB_VARS["db_type"]}://{DB_VARS["db_cred"]}@{DB_VARS["db_host"]}:{DB_VARS["db_port"]}/{DB_VARS["db_name"]}' |
| ) |
| elif DATABASE_TYPE == 'sqlite+sqlcipher' and not os.getenv('DATABASE_URL'): |
| |
| DATABASE_URL = f'sqlite+sqlcipher:///{DATA_DIR}/webui.db' |
|
|
| |
| if 'postgres://' in DATABASE_URL: |
| DATABASE_URL = DATABASE_URL.replace('postgres://', 'postgresql://') |
|
|
| DATABASE_SCHEMA = os.getenv('DATABASE_SCHEMA', None) |
|
|
| _pool_size_raw = os.getenv('DATABASE_POOL_SIZE') |
| try: |
| DATABASE_POOL_SIZE = int(_pool_size_raw) if _pool_size_raw else None |
| except (ValueError, TypeError): |
| DATABASE_POOL_SIZE = None |
|
|
| _pool_overflow_raw = os.getenv('DATABASE_POOL_MAX_OVERFLOW', '0') |
| try: |
| DATABASE_POOL_MAX_OVERFLOW = int(_pool_overflow_raw) if _pool_overflow_raw else 0 |
| except (ValueError, TypeError): |
| DATABASE_POOL_MAX_OVERFLOW = 0 |
|
|
| _pool_timeout_raw = os.getenv('DATABASE_POOL_TIMEOUT', '30') |
| try: |
| DATABASE_POOL_TIMEOUT = int(_pool_timeout_raw) if _pool_timeout_raw else 30 |
| except (ValueError, TypeError): |
| DATABASE_POOL_TIMEOUT = 30 |
|
|
| _pool_recycle_raw = os.getenv('DATABASE_POOL_RECYCLE', '3600') |
| try: |
| DATABASE_POOL_RECYCLE = int(_pool_recycle_raw) if _pool_recycle_raw else 3600 |
| except (ValueError, TypeError): |
| DATABASE_POOL_RECYCLE = 3600 |
|
|
| DATABASE_ENABLE_SQLITE_WAL = os.getenv('DATABASE_ENABLE_SQLITE_WAL', 'True').lower() == 'true' |
|
|
| |
| |
| |
|
|
| |
| |
| DATABASE_SQLITE_PRAGMA_SYNCHRONOUS = os.getenv('DATABASE_SQLITE_PRAGMA_SYNCHRONOUS', 'NORMAL') |
|
|
| |
| |
| DATABASE_SQLITE_PRAGMA_BUSY_TIMEOUT = os.getenv('DATABASE_SQLITE_PRAGMA_BUSY_TIMEOUT', '5000') |
|
|
| |
| DATABASE_SQLITE_PRAGMA_CACHE_SIZE = os.getenv('DATABASE_SQLITE_PRAGMA_CACHE_SIZE', '-65536') |
|
|
| |
| |
| DATABASE_SQLITE_PRAGMA_TEMP_STORE = os.getenv('DATABASE_SQLITE_PRAGMA_TEMP_STORE', 'MEMORY') |
|
|
| |
| |
| DATABASE_SQLITE_PRAGMA_MMAP_SIZE = os.getenv('DATABASE_SQLITE_PRAGMA_MMAP_SIZE', '268435456') |
|
|
| |
| |
| |
| DATABASE_SQLITE_PRAGMA_JOURNAL_SIZE_LIMIT = os.getenv('DATABASE_SQLITE_PRAGMA_JOURNAL_SIZE_LIMIT', '67108864') |
|
|
| DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL = os.getenv('DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL', None) |
| if DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL is not None: |
| try: |
| DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL = float(DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL) |
| except Exception: |
| DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL = 0.0 |
|
|
| DATABASE_ENABLE_SESSION_SHARING = os.getenv('DATABASE_ENABLE_SESSION_SHARING', 'False').lower() == 'true' |
| ENABLE_PUBLIC_ACTIVE_USERS_COUNT = os.getenv('ENABLE_PUBLIC_ACTIVE_USERS_COUNT', 'True').lower() == 'true' |
| RESET_CONFIG_ON_START = os.getenv('RESET_CONFIG_ON_START', 'False').lower() == 'true' |
| ENABLE_REALTIME_CHAT_SAVE = os.getenv('ENABLE_REALTIME_CHAT_SAVE', 'False').lower() == 'true' |
| ENABLE_QUERIES_CACHE = os.getenv('ENABLE_QUERIES_CACHE', 'False').lower() == 'true' |
| RAG_SYSTEM_CONTEXT = os.getenv('RAG_SYSTEM_CONTEXT', 'False').lower() == 'true' |
|
|
| |
| |
| |
|
|
| REDIS_URL = os.getenv('REDIS_URL', '') |
| REDIS_CLUSTER = os.getenv('REDIS_CLUSTER', 'False').lower() == 'true' |
|
|
| REDIS_KEY_PREFIX = os.getenv('REDIS_KEY_PREFIX', 'open-webui') |
|
|
| REDIS_SENTINEL_HOSTS = os.getenv('REDIS_SENTINEL_HOSTS', '') |
| REDIS_SENTINEL_PORT = os.getenv('REDIS_SENTINEL_PORT', '26379') |
|
|
| |
| REDIS_SENTINEL_MAX_RETRY_COUNT = os.getenv('REDIS_SENTINEL_MAX_RETRY_COUNT', '2') |
| try: |
| REDIS_SENTINEL_MAX_RETRY_COUNT = int(REDIS_SENTINEL_MAX_RETRY_COUNT) |
| if REDIS_SENTINEL_MAX_RETRY_COUNT < 1: |
| REDIS_SENTINEL_MAX_RETRY_COUNT = 2 |
| except ValueError: |
| REDIS_SENTINEL_MAX_RETRY_COUNT = 2 |
|
|
|
|
| REDIS_SOCKET_CONNECT_TIMEOUT = os.getenv('REDIS_SOCKET_CONNECT_TIMEOUT', '') |
| try: |
| REDIS_SOCKET_CONNECT_TIMEOUT = float(REDIS_SOCKET_CONNECT_TIMEOUT) |
| except ValueError: |
| REDIS_SOCKET_CONNECT_TIMEOUT = None |
|
|
| |
| |
| |
| |
| |
| REDIS_SOCKET_KEEPALIVE = os.getenv('REDIS_SOCKET_KEEPALIVE', 'False').lower() == 'true' |
|
|
| |
| |
| |
| |
| |
| |
| REDIS_HEALTH_CHECK_INTERVAL = os.getenv('REDIS_HEALTH_CHECK_INTERVAL', '') |
| try: |
| REDIS_HEALTH_CHECK_INTERVAL = int(REDIS_HEALTH_CHECK_INTERVAL) |
| if REDIS_HEALTH_CHECK_INTERVAL <= 0: |
| REDIS_HEALTH_CHECK_INTERVAL = None |
| except ValueError: |
| REDIS_HEALTH_CHECK_INTERVAL = None |
|
|
| REDIS_RECONNECT_DELAY = os.getenv('REDIS_RECONNECT_DELAY', '') |
|
|
| if REDIS_RECONNECT_DELAY == '': |
| REDIS_RECONNECT_DELAY = None |
| else: |
| try: |
| REDIS_RECONNECT_DELAY = float(REDIS_RECONNECT_DELAY) |
| if REDIS_RECONNECT_DELAY < 0: |
| REDIS_RECONNECT_DELAY = None |
| except Exception: |
| REDIS_RECONNECT_DELAY = None |
|
|
| |
| |
| |
|
|
| try: |
| UVICORN_WORKERS = max(int(os.getenv('UVICORN_WORKERS', '1')), 1) |
| except (ValueError, TypeError): |
| UVICORN_WORKERS = 1 |
|
|
| |
| |
| |
|
|
| ENABLE_WEBSOCKET_SUPPORT = os.getenv('ENABLE_WEBSOCKET_SUPPORT', 'True').lower() == 'true' |
|
|
|
|
| WEBSOCKET_MANAGER = os.getenv('WEBSOCKET_MANAGER', '') |
|
|
| WEBSOCKET_REDIS_OPTIONS = os.getenv('WEBSOCKET_REDIS_OPTIONS', '') |
|
|
|
|
| if WEBSOCKET_REDIS_OPTIONS == '': |
| if REDIS_SOCKET_CONNECT_TIMEOUT: |
| WEBSOCKET_REDIS_OPTIONS = {'socket_connect_timeout': REDIS_SOCKET_CONNECT_TIMEOUT} |
| else: |
| log.debug('No WEBSOCKET_REDIS_OPTIONS provided, defaulting to None') |
| WEBSOCKET_REDIS_OPTIONS = None |
| else: |
| try: |
| WEBSOCKET_REDIS_OPTIONS = json.loads(WEBSOCKET_REDIS_OPTIONS) |
| except Exception: |
| log.warning('Invalid WEBSOCKET_REDIS_OPTIONS, defaulting to None') |
| WEBSOCKET_REDIS_OPTIONS = None |
|
|
| WEBSOCKET_REDIS_URL = os.getenv('WEBSOCKET_REDIS_URL', REDIS_URL) |
| WEBSOCKET_REDIS_CLUSTER = os.getenv('WEBSOCKET_REDIS_CLUSTER', str(REDIS_CLUSTER)).lower() == 'true' |
|
|
| websocket_redis_lock_timeout = os.getenv('WEBSOCKET_REDIS_LOCK_TIMEOUT', '60') |
|
|
| try: |
| WEBSOCKET_REDIS_LOCK_TIMEOUT = int(websocket_redis_lock_timeout) |
| except ValueError: |
| WEBSOCKET_REDIS_LOCK_TIMEOUT = 60 |
|
|
| WEBSOCKET_SENTINEL_HOSTS = os.getenv('WEBSOCKET_SENTINEL_HOSTS', '') |
| WEBSOCKET_SENTINEL_PORT = os.getenv('WEBSOCKET_SENTINEL_PORT', '26379') |
| WEBSOCKET_SERVER_LOGGING = os.getenv('WEBSOCKET_SERVER_LOGGING', 'False').lower() == 'true' |
| WEBSOCKET_SERVER_ENGINEIO_LOGGING = ( |
| os.getenv( |
| 'WEBSOCKET_SERVER_ENGINEIO_LOGGING', |
| os.getenv('WEBSOCKET_SERVER_LOGGING', 'False'), |
| ).lower() |
| == 'true' |
| ) |
| WEBSOCKET_SERVER_PING_TIMEOUT = os.getenv('WEBSOCKET_SERVER_PING_TIMEOUT', '20') |
| try: |
| WEBSOCKET_SERVER_PING_TIMEOUT = int(WEBSOCKET_SERVER_PING_TIMEOUT) |
| except ValueError: |
| WEBSOCKET_SERVER_PING_TIMEOUT = 20 |
|
|
| WEBSOCKET_SERVER_PING_INTERVAL = os.getenv('WEBSOCKET_SERVER_PING_INTERVAL', '25') |
| try: |
| WEBSOCKET_SERVER_PING_INTERVAL = int(WEBSOCKET_SERVER_PING_INTERVAL) |
| except ValueError: |
| WEBSOCKET_SERVER_PING_INTERVAL = 25 |
|
|
| WEBSOCKET_EVENT_CALLER_TIMEOUT = os.getenv('WEBSOCKET_EVENT_CALLER_TIMEOUT', '') |
|
|
| if WEBSOCKET_EVENT_CALLER_TIMEOUT == '': |
| WEBSOCKET_EVENT_CALLER_TIMEOUT = None |
| else: |
| try: |
| WEBSOCKET_EVENT_CALLER_TIMEOUT = int(WEBSOCKET_EVENT_CALLER_TIMEOUT) |
| except ValueError: |
| WEBSOCKET_EVENT_CALLER_TIMEOUT = 300 |
|
|
|
|
| REQUESTS_VERIFY = os.getenv('REQUESTS_VERIFY', 'True').lower() == 'true' |
|
|
| _aiohttp_timeout_raw = os.getenv('AIOHTTP_CLIENT_TIMEOUT', '') |
| try: |
| AIOHTTP_CLIENT_TIMEOUT = int(_aiohttp_timeout_raw) if _aiohttp_timeout_raw else None |
| except (ValueError, TypeError): |
| AIOHTTP_CLIENT_TIMEOUT = 300 |
|
|
|
|
| AIOHTTP_CLIENT_SESSION_SSL = os.getenv('AIOHTTP_CLIENT_SESSION_SSL', 'True').lower() == 'true' |
|
|
| |
| AIOHTTP_CLIENT_ALLOW_REDIRECTS = os.getenv('AIOHTTP_CLIENT_ALLOW_REDIRECTS', 'False').lower() == 'true' |
|
|
| |
| |
| |
| USER_AGENT = os.getenv('USER_AGENT', '') |
|
|
| _model_list_timeout_raw = os.getenv( |
| 'AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST', |
| os.getenv('AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST', '10'), |
| ) |
| try: |
| AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST = int(_model_list_timeout_raw) if _model_list_timeout_raw else None |
| except (ValueError, TypeError): |
| AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST = 10 |
|
|
| _tool_data_timeout_raw = os.getenv('AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA', '10') |
| try: |
| AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA = int(_tool_data_timeout_raw) if _tool_data_timeout_raw else None |
| except (ValueError, TypeError): |
| AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA = 10 |
|
|
|
|
| AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL = os.getenv('AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL', 'True').lower() == 'true' |
|
|
| AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER = os.getenv('AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER', '') |
|
|
| if AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER == '': |
| AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER = AIOHTTP_CLIENT_TIMEOUT |
| else: |
| try: |
| AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER = int(AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER) |
| except Exception: |
| AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER = AIOHTTP_CLIENT_TIMEOUT |
|
|
| |
| |
| |
| MCP_INITIALIZE_TIMEOUT = os.getenv('MCP_INITIALIZE_TIMEOUT', '10') |
| try: |
| MCP_INITIALIZE_TIMEOUT = int(MCP_INITIALIZE_TIMEOUT) |
| except (ValueError, TypeError): |
| MCP_INITIALIZE_TIMEOUT = 10 |
|
|
|
|
| |
| |
| |
|
|
| AIOHTTP_POOL_CONNECTIONS = os.getenv('AIOHTTP_POOL_CONNECTIONS', '') |
| if AIOHTTP_POOL_CONNECTIONS == '': |
| AIOHTTP_POOL_CONNECTIONS = None |
| else: |
| try: |
| AIOHTTP_POOL_CONNECTIONS = int(AIOHTTP_POOL_CONNECTIONS) |
| except ValueError: |
| AIOHTTP_POOL_CONNECTIONS = None |
|
|
| AIOHTTP_POOL_CONNECTIONS_PER_HOST = os.getenv('AIOHTTP_POOL_CONNECTIONS_PER_HOST', '') |
| if AIOHTTP_POOL_CONNECTIONS_PER_HOST == '': |
| AIOHTTP_POOL_CONNECTIONS_PER_HOST = None |
| else: |
| try: |
| AIOHTTP_POOL_CONNECTIONS_PER_HOST = int(AIOHTTP_POOL_CONNECTIONS_PER_HOST) |
| except ValueError: |
| AIOHTTP_POOL_CONNECTIONS_PER_HOST = None |
|
|
| AIOHTTP_POOL_DNS_TTL = os.getenv('AIOHTTP_POOL_DNS_TTL', '300') |
| try: |
| AIOHTTP_POOL_DNS_TTL = int(AIOHTTP_POOL_DNS_TTL) |
| if AIOHTTP_POOL_DNS_TTL < 0: |
| AIOHTTP_POOL_DNS_TTL = 300 |
| except ValueError: |
| AIOHTTP_POOL_DNS_TTL = 300 |
|
|
| RAG_EMBEDDING_TIMEOUT = os.getenv('RAG_EMBEDDING_TIMEOUT', '') |
|
|
| if RAG_EMBEDDING_TIMEOUT == '': |
| RAG_EMBEDDING_TIMEOUT = None |
| else: |
| try: |
| RAG_EMBEDDING_TIMEOUT = int(RAG_EMBEDDING_TIMEOUT) |
| except Exception: |
| RAG_EMBEDDING_TIMEOUT = None |
|
|
|
|
| |
| |
| |
|
|
| WEBUI_AUTH = os.getenv('WEBUI_AUTH', 'True').lower() == 'true' |
|
|
| ENABLE_INITIAL_ADMIN_SIGNUP = os.getenv('ENABLE_INITIAL_ADMIN_SIGNUP', 'False').lower() == 'true' |
| ENABLE_SIGNUP_PASSWORD_CONFIRMATION = os.getenv('ENABLE_SIGNUP_PASSWORD_CONFIRMATION', 'False').lower() == 'true' |
|
|
| |
| |
| |
|
|
| |
| |
| WEBUI_SECRET_KEY = os.getenv( |
| 'WEBUI_SECRET_KEY', |
| os.getenv('WEBUI_JWT_SECRET_KEY', ''), |
| ) |
|
|
| WEBUI_SESSION_COOKIE_SAME_SITE = os.getenv('WEBUI_SESSION_COOKIE_SAME_SITE', 'lax') |
| WEBUI_SESSION_COOKIE_SECURE = os.getenv('WEBUI_SESSION_COOKIE_SECURE', 'false').lower() == 'true' |
| WEBUI_AUTH_COOKIE_SAME_SITE = os.getenv('WEBUI_AUTH_COOKIE_SAME_SITE', WEBUI_SESSION_COOKIE_SAME_SITE) |
| WEBUI_AUTH_COOKIE_SECURE = ( |
| os.getenv( |
| 'WEBUI_AUTH_COOKIE_SECURE', |
| os.getenv('WEBUI_SESSION_COOKIE_SECURE', 'false'), |
| ).lower() |
| == 'true' |
| ) |
|
|
| if WEBUI_AUTH and WEBUI_SECRET_KEY == '': |
| raise SystemExit( |
| 'WEBUI_SECRET_KEY is not set. It is a hard requirement when authentication is enabled.\n' |
| 'The supported start methods set or auto-generate it for you: use start.sh (Linux/macOS), ' |
| 'start_windows.bat (Windows), or `open-webui serve`.\n' |
| 'If you start the backend another way (e.g. invoking uvicorn directly, which is unsupported), ' |
| 'you must set WEBUI_SECRET_KEY yourself to a long random value.\n' |
| 'See https://docs.openwebui.com/reference/env-configuration#webui_secret_key' |
| ) |
|
|
| ENABLE_COMPRESSION_MIDDLEWARE = os.getenv('ENABLE_COMPRESSION_MIDDLEWARE', 'True').lower() == 'true' |
|
|
| |
| |
| |
|
|
| |
| |
| WEBUI_ADMIN_EMAIL = os.getenv('WEBUI_ADMIN_EMAIL', '') |
| WEBUI_ADMIN_PASSWORD = os.getenv('WEBUI_ADMIN_PASSWORD', '') |
| WEBUI_ADMIN_NAME = os.getenv('WEBUI_ADMIN_NAME', 'Admin') |
|
|
| WEBUI_AUTH_TRUSTED_EMAIL_HEADER = os.getenv('WEBUI_AUTH_TRUSTED_EMAIL_HEADER', None) |
| WEBUI_AUTH_TRUSTED_NAME_HEADER = os.getenv('WEBUI_AUTH_TRUSTED_NAME_HEADER', None) |
| WEBUI_AUTH_TRUSTED_GROUPS_HEADER = os.getenv('WEBUI_AUTH_TRUSTED_GROUPS_HEADER', None) |
| WEBUI_AUTH_TRUSTED_ROLE_HEADER = os.getenv('WEBUI_AUTH_TRUSTED_ROLE_HEADER', None) |
|
|
| |
| |
| |
| |
| |
| CUSTOM_API_KEY_HEADER = os.getenv('CUSTOM_API_KEY_HEADER', 'x-api-key') |
|
|
| ENABLE_PASSWORD_VALIDATION = os.getenv('ENABLE_PASSWORD_VALIDATION', 'False').lower() == 'true' |
| PASSWORD_VALIDATION_REGEX_PATTERN = os.getenv( |
| 'PASSWORD_VALIDATION_REGEX_PATTERN', |
| r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$', |
| ) |
|
|
|
|
| try: |
| PASSWORD_VALIDATION_REGEX_PATTERN = rf'{PASSWORD_VALIDATION_REGEX_PATTERN}' |
| PASSWORD_VALIDATION_REGEX_PATTERN = re.compile(PASSWORD_VALIDATION_REGEX_PATTERN) |
| except Exception as e: |
| log.error(f'Invalid PASSWORD_VALIDATION_REGEX_PATTERN: {e}') |
| PASSWORD_VALIDATION_REGEX_PATTERN = re.compile(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$') |
|
|
| PASSWORD_VALIDATION_HINT = os.getenv('PASSWORD_VALIDATION_HINT', '') |
|
|
|
|
| BYPASS_MODEL_ACCESS_CONTROL = os.getenv('BYPASS_MODEL_ACCESS_CONTROL', 'False').lower() == 'true' |
| BYPASS_RETRIEVAL_ACCESS_CONTROL = os.getenv('BYPASS_RETRIEVAL_ACCESS_CONTROL', 'False').lower() == 'true' |
|
|
| |
| |
| |
| |
| ENABLE_RETRIEVAL_UNSCOPED_COLLECTIONS = os.getenv('ENABLE_RETRIEVAL_UNSCOPED_COLLECTIONS', 'False').lower() == 'true' |
|
|
| |
| |
| |
| BYPASS_PYDUB_PREPROCESSING = os.getenv('BYPASS_PYDUB_PREPROCESSING', 'False').lower() == 'true' |
|
|
| |
| |
| |
| ENABLE_OPENAI_API_PASSTHROUGH = os.getenv('ENABLE_OPENAI_API_PASSTHROUGH', 'False').lower() == 'true' |
|
|
| WEBUI_AUTH_SIGNOUT_REDIRECT_URL = os.getenv('WEBUI_AUTH_SIGNOUT_REDIRECT_URL', None) |
|
|
| |
| |
| |
| ENABLE_OAUTH_EMAIL_FALLBACK = os.getenv('ENABLE_OAUTH_EMAIL_FALLBACK', 'False').lower() == 'true' |
|
|
| ENABLE_OAUTH_ID_TOKEN_COOKIE = os.getenv('ENABLE_OAUTH_ID_TOKEN_COOKIE', 'True').lower() == 'true' |
|
|
| OAUTH_CLIENT_INFO_ENCRYPTION_KEY = os.getenv('OAUTH_CLIENT_INFO_ENCRYPTION_KEY', WEBUI_SECRET_KEY) |
|
|
| OAUTH_SESSION_TOKEN_ENCRYPTION_KEY = os.getenv('OAUTH_SESSION_TOKEN_ENCRYPTION_KEY', WEBUI_SECRET_KEY) |
|
|
| |
| |
| OAUTH_MAX_SESSIONS_PER_USER = int(os.getenv('OAUTH_MAX_SESSIONS_PER_USER', '10')) |
|
|
| |
| |
| ENABLE_OAUTH_TOKEN_EXCHANGE = os.getenv('ENABLE_OAUTH_TOKEN_EXCHANGE', 'False').lower() == 'true' |
|
|
| |
| |
| |
| |
| ENABLE_OAUTH_BACKCHANNEL_LOGOUT = os.getenv('ENABLE_OAUTH_BACKCHANNEL_LOGOUT', 'False').lower() == 'true' |
|
|
| |
| |
| |
|
|
| ENABLE_SCIM = os.getenv('ENABLE_SCIM', os.getenv('SCIM_ENABLED', 'False')).lower() == 'true' |
| SCIM_TOKEN = os.getenv('SCIM_TOKEN', '') |
| SCIM_AUTH_PROVIDER = os.getenv('SCIM_AUTH_PROVIDER', '') |
|
|
| if ENABLE_SCIM and not SCIM_AUTH_PROVIDER: |
| log.warning( |
| 'SCIM is enabled but SCIM_AUTH_PROVIDER is not set. ' |
| "Set SCIM_AUTH_PROVIDER to the OAuth provider name (e.g. 'microsoft', 'oidc') " |
| 'to enable externalId storage.' |
| ) |
|
|
| |
| |
| |
|
|
| LICENSE_KEY = os.getenv('LICENSE_KEY', '') |
|
|
| LICENSE_BLOB = None |
| LICENSE_BLOB_PATH = os.getenv('LICENSE_BLOB_PATH', DATA_DIR / 'l.data') |
| if LICENSE_BLOB_PATH and os.path.exists(LICENSE_BLOB_PATH): |
| with open(LICENSE_BLOB_PATH, 'rb') as f: |
| LICENSE_BLOB = f.read() |
|
|
| LICENSE_PUBLIC_KEY = os.getenv('LICENSE_PUBLIC_KEY', '') |
|
|
| pk = None |
| if LICENSE_PUBLIC_KEY: |
| pk = serialization.load_pem_public_key( |
| f""" |
| -----BEGIN PUBLIC KEY----- |
| {LICENSE_PUBLIC_KEY} |
| -----END PUBLIC KEY----- |
| """.encode() |
| ) |
|
|
|
|
| |
| |
| |
|
|
| WEBUI_NAME = os.getenv('WEBUI_NAME', 'Omnichat') |
| if WEBUI_NAME != 'Omnichat': |
| WEBUI_NAME += ' (Omnichat)' |
|
|
| WEBUI_FAVICON_URL = 'https://omnichat.rexpro.com/favicon.png' |
| WEBUI_BUILD_HASH = os.getenv('WEBUI_BUILD_HASH', 'dev-build') |
| TRUSTED_SIGNATURE_KEY = os.getenv('TRUSTED_SIGNATURE_KEY', '') |
|
|
| |
| |
| |
|
|
| SAFE_MODE = os.getenv('SAFE_MODE', 'False').lower() == 'true' |
| ENABLE_EASTER_EGGS = os.getenv('ENABLE_EASTER_EGGS', 'True').lower() == 'true' |
| ENABLE_STAR_SESSIONS_MIDDLEWARE = os.getenv('ENABLE_STAR_SESSIONS_MIDDLEWARE', 'False').lower() == 'true' |
| ENABLE_KB_EXEC = os.getenv('ENABLE_KB_EXEC', 'False').lower() == 'true' |
|
|
| ENABLE_PROFILE_IMAGE_URL_FORWARDING = os.getenv('ENABLE_PROFILE_IMAGE_URL_FORWARDING', 'True').lower() == 'true' |
| PROFILE_IMAGE_ALLOWED_MIME_TYPES = frozenset( |
| t.strip() |
| for t in os.getenv( |
| 'PROFILE_IMAGE_ALLOWED_MIME_TYPES', |
| 'image/png,image/jpeg,image/gif,image/webp', |
| ).split(',') |
| if t.strip() |
| ) |
|
|
| |
| |
| _profile_image_max_data_uri_size = os.getenv('PROFILE_IMAGE_MAX_DATA_URI_SIZE', '').strip() |
| PROFILE_IMAGE_MAX_DATA_URI_SIZE = int(_profile_image_max_data_uri_size) if _profile_image_max_data_uri_size else None |
|
|
| |
| |
| |
|
|
| ENABLE_FORWARD_USER_INFO_HEADERS = os.getenv('ENABLE_FORWARD_USER_INFO_HEADERS', 'False').lower() == 'true' |
|
|
| FORWARD_USER_INFO_HEADER_USER_NAME = os.getenv('FORWARD_USER_INFO_HEADER_USER_NAME', 'X-OpenWebUI-User-Name') |
| FORWARD_USER_INFO_HEADER_USER_ID = os.getenv('FORWARD_USER_INFO_HEADER_USER_ID', 'X-OpenWebUI-User-Id') |
| FORWARD_USER_INFO_HEADER_USER_EMAIL = os.getenv('FORWARD_USER_INFO_HEADER_USER_EMAIL', 'X-OpenWebUI-User-Email') |
| FORWARD_USER_INFO_HEADER_USER_ROLE = os.getenv('FORWARD_USER_INFO_HEADER_USER_ROLE', 'X-OpenWebUI-User-Role') |
| FORWARD_SESSION_INFO_HEADER_MESSAGE_ID = os.getenv('FORWARD_SESSION_INFO_HEADER_MESSAGE_ID', 'X-OpenWebUI-Message-Id') |
| FORWARD_SESSION_INFO_HEADER_CHAT_ID = os.getenv('FORWARD_SESSION_INFO_HEADER_CHAT_ID', 'X-OpenWebUI-Chat-Id') |
|
|
| |
| |
| FORWARD_USER_INFO_HEADER_JWT_SECRET = (os.environ.get('FORWARD_USER_INFO_HEADER_JWT_SECRET') or '').strip() or None |
| FORWARD_USER_INFO_HEADER_JWT = os.environ.get('FORWARD_USER_INFO_HEADER_JWT', 'X-OpenWebUI-User-Jwt') |
| try: |
| FORWARD_USER_INFO_HEADER_JWT_EXPIRES_SECONDS = int( |
| os.environ.get('FORWARD_USER_INFO_HEADER_JWT_EXPIRES_SECONDS', '300') |
| ) |
| except ValueError: |
| FORWARD_USER_INFO_HEADER_JWT_EXPIRES_SECONDS = 300 |
|
|
| |
| |
| |
|
|
| EXTERNAL_PWA_MANIFEST_URL = os.getenv('EXTERNAL_PWA_MANIFEST_URL', None) |
|
|
| |
| |
| |
|
|
| |
| |
| _default_group_share = os.getenv('DEFAULT_GROUP_SHARE_PERMISSION', 'members').strip().lower() |
| DEFAULT_GROUP_SHARE_PERMISSION = 'members' if _default_group_share == 'members' else _default_group_share == 'true' |
|
|
| |
| |
| |
|
|
| ENABLE_CUSTOM_MODEL_FALLBACK = os.getenv('ENABLE_CUSTOM_MODEL_FALLBACK', 'False').lower() == 'true' |
|
|
| MODELS_CACHE_TTL = os.getenv('MODELS_CACHE_TTL', '1') |
| if MODELS_CACHE_TTL == '': |
| MODELS_CACHE_TTL = None |
| else: |
| try: |
| MODELS_CACHE_TTL = int(MODELS_CACHE_TTL) |
| except Exception: |
| MODELS_CACHE_TTL = 1 |
|
|
|
|
| |
| |
| |
|
|
| ENABLE_CHAT_RESPONSE_BASE64_IMAGE_URL_CONVERSION = ( |
| os.getenv('ENABLE_CHAT_RESPONSE_BASE64_IMAGE_URL_CONVERSION', 'False').lower() == 'true' |
| ) |
|
|
| |
| |
| |
| |
| |
| ENABLE_IMAGE_CONTENT_TYPE_EXTENSION_FALLBACK = ( |
| os.getenv('ENABLE_IMAGE_CONTENT_TYPE_EXTENSION_FALLBACK', 'False').lower() == 'true' |
| ) |
|
|
| CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE = os.getenv('CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE', '1') |
|
|
| if CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE == '': |
| CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE = 1 |
| else: |
| try: |
| CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE = int(CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE) |
| except Exception: |
| CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE = 1 |
|
|
|
|
| |
| |
| CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS = os.getenv( |
| 'CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS', |
| os.getenv('CHAT_RESPONSE_MAX_TOOL_CALL_RETRIES', '256'), |
| ) |
|
|
| if CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS == '': |
| CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS = 256 |
| else: |
| try: |
| CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS = int(CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS) |
| except Exception: |
| CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS = 256 |
|
|
| |
| if CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS == -1: |
| CHAT_RESPONSE_MAX_TOOL_CALL_ITERATIONS = None |
|
|
|
|
| |
| |
| |
| |
| ENABLE_RESPONSES_API_STATEFUL = os.getenv('ENABLE_RESPONSES_API_STATEFUL', 'False').lower() == 'true' |
|
|
|
|
| CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE = os.getenv('CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE', '') |
|
|
| if CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE == '': |
| CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE = None |
| else: |
| try: |
| CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE = int(CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE) |
| except Exception: |
| CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE = None |
|
|
|
|
| |
| |
| |
|
|
|
|
| SENTENCE_TRANSFORMERS_BACKEND = os.getenv('SENTENCE_TRANSFORMERS_BACKEND', '') |
| if SENTENCE_TRANSFORMERS_BACKEND == '': |
| SENTENCE_TRANSFORMERS_BACKEND = 'torch' |
|
|
|
|
| SENTENCE_TRANSFORMERS_MODEL_KWARGS = os.getenv('SENTENCE_TRANSFORMERS_MODEL_KWARGS', '') |
| if SENTENCE_TRANSFORMERS_MODEL_KWARGS == '': |
| SENTENCE_TRANSFORMERS_MODEL_KWARGS = None |
| else: |
| try: |
| SENTENCE_TRANSFORMERS_MODEL_KWARGS = json.loads(SENTENCE_TRANSFORMERS_MODEL_KWARGS) |
| except Exception: |
| SENTENCE_TRANSFORMERS_MODEL_KWARGS = None |
|
|
|
|
| SENTENCE_TRANSFORMERS_CROSS_ENCODER_BACKEND = os.getenv('SENTENCE_TRANSFORMERS_CROSS_ENCODER_BACKEND', '') |
| if SENTENCE_TRANSFORMERS_CROSS_ENCODER_BACKEND == '': |
| SENTENCE_TRANSFORMERS_CROSS_ENCODER_BACKEND = 'torch' |
|
|
|
|
| SENTENCE_TRANSFORMERS_CROSS_ENCODER_MODEL_KWARGS = os.getenv('SENTENCE_TRANSFORMERS_CROSS_ENCODER_MODEL_KWARGS', '') |
| if SENTENCE_TRANSFORMERS_CROSS_ENCODER_MODEL_KWARGS == '': |
| SENTENCE_TRANSFORMERS_CROSS_ENCODER_MODEL_KWARGS = None |
| else: |
| try: |
| SENTENCE_TRANSFORMERS_CROSS_ENCODER_MODEL_KWARGS = json.loads(SENTENCE_TRANSFORMERS_CROSS_ENCODER_MODEL_KWARGS) |
| except Exception: |
| SENTENCE_TRANSFORMERS_CROSS_ENCODER_MODEL_KWARGS = None |
|
|
| |
| |
| |
| SENTENCE_TRANSFORMERS_CROSS_ENCODER_SIGMOID_ACTIVATION_FUNCTION = ( |
| os.getenv('SENTENCE_TRANSFORMERS_CROSS_ENCODER_SIGMOID_ACTIVATION_FUNCTION', 'True').lower() == 'true' |
| ) |
|
|
| |
| |
| |
|
|
| ENABLE_PIP_INSTALL_FRONTMATTER_REQUIREMENTS = ( |
| os.getenv('ENABLE_PIP_INSTALL_FRONTMATTER_REQUIREMENTS', 'True').lower() == 'true' |
| ) |
|
|
| PIP_OPTIONS = os.getenv('PIP_OPTIONS', '').split() |
| PIP_PACKAGE_INDEX_OPTIONS = os.getenv('PIP_PACKAGE_INDEX_OPTIONS', '').split() |
|
|
|
|
| |
| |
| |
|
|
| ENABLE_VERSION_UPDATE_CHECK = False |
| OFFLINE_MODE = os.getenv('OFFLINE_MODE', 'false').lower() == 'true' |
|
|
| if OFFLINE_MODE: |
| os.environ['HF_HUB_OFFLINE'] = '1' |
| ENABLE_VERSION_UPDATE_CHECK = False |
|
|
| |
| |
| |
|
|
|
|
| ENABLE_AUDIT_STDOUT = os.getenv('ENABLE_AUDIT_STDOUT', 'False').lower() == 'true' |
| ENABLE_AUDIT_LOGS_FILE = os.getenv('ENABLE_AUDIT_LOGS_FILE', 'True').lower() == 'true' |
|
|
| |
| |
| |
| AUDIT_LOGS_FILE_PATH = os.getenv('AUDIT_LOGS_FILE_PATH', f'{DATA_DIR}/audit.log') |
| |
| AUDIT_LOG_FILE_ROTATION_SIZE = os.getenv('AUDIT_LOG_FILE_ROTATION_SIZE', '10MB') |
|
|
| |
| |
| |
| AUDIT_UVICORN_LOGGER_NAMES = os.getenv('AUDIT_UVICORN_LOGGER_NAMES', 'uvicorn.access').split(',') |
|
|
| |
| AUDIT_LOG_LEVEL = os.getenv('AUDIT_LOG_LEVEL', 'NONE').upper() |
| try: |
| MAX_BODY_LOG_SIZE = int(os.getenv('MAX_BODY_LOG_SIZE') or 2048) |
| except ValueError: |
| MAX_BODY_LOG_SIZE = 2048 |
|
|
| |
| AUDIT_EXCLUDED_PATHS = os.getenv('AUDIT_EXCLUDED_PATHS', '/chats,/chat,/folders').split(',') |
| AUDIT_EXCLUDED_PATHS = [path.strip() for path in AUDIT_EXCLUDED_PATHS] |
| AUDIT_EXCLUDED_PATHS = [path.lstrip('/') for path in AUDIT_EXCLUDED_PATHS] |
|
|
| |
| |
| AUDIT_INCLUDED_PATHS = os.getenv('AUDIT_INCLUDED_PATHS', '').split(',') |
| AUDIT_INCLUDED_PATHS = [path.strip() for path in AUDIT_INCLUDED_PATHS] |
| AUDIT_INCLUDED_PATHS = [path.lstrip('/') for path in AUDIT_INCLUDED_PATHS if path] |
|
|
| |
| ENABLE_AUDIT_GET_REQUESTS = os.getenv('ENABLE_AUDIT_GET_REQUESTS', 'False').lower() == 'true' |
|
|
|
|
| |
| |
| |
|
|
| ENABLE_OTEL = os.getenv('ENABLE_OTEL', 'False').lower() == 'true' |
| ENABLE_OTEL_TRACES = os.getenv('ENABLE_OTEL_TRACES', 'False').lower() == 'true' |
| ENABLE_OTEL_METRICS = os.getenv('ENABLE_OTEL_METRICS', 'False').lower() == 'true' |
| ENABLE_OTEL_LOGS = os.getenv('ENABLE_OTEL_LOGS', 'False').lower() == 'true' |
|
|
| OTEL_EXPORTER_OTLP_ENDPOINT = os.getenv('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://localhost:4317') |
| OTEL_METRICS_EXPORTER_OTLP_ENDPOINT = os.getenv('OTEL_METRICS_EXPORTER_OTLP_ENDPOINT', OTEL_EXPORTER_OTLP_ENDPOINT) |
| OTEL_LOGS_EXPORTER_OTLP_ENDPOINT = os.getenv('OTEL_LOGS_EXPORTER_OTLP_ENDPOINT', OTEL_EXPORTER_OTLP_ENDPOINT) |
| OTEL_EXPORTER_OTLP_INSECURE = os.getenv('OTEL_EXPORTER_OTLP_INSECURE', 'False').lower() == 'true' |
| OTEL_METRICS_EXPORTER_OTLP_INSECURE = ( |
| os.getenv('OTEL_METRICS_EXPORTER_OTLP_INSECURE', str(OTEL_EXPORTER_OTLP_INSECURE)).lower() == 'true' |
| ) |
| OTEL_LOGS_EXPORTER_OTLP_INSECURE = ( |
| os.getenv('OTEL_LOGS_EXPORTER_OTLP_INSECURE', str(OTEL_EXPORTER_OTLP_INSECURE)).lower() == 'true' |
| ) |
| OTEL_SERVICE_NAME = os.getenv('OTEL_SERVICE_NAME', 'open-webui') |
| OTEL_RESOURCE_ATTRIBUTES = os.getenv('OTEL_RESOURCE_ATTRIBUTES', '') |
| OTEL_TRACES_SAMPLER = os.getenv('OTEL_TRACES_SAMPLER', 'parentbased_always_on').lower() |
| OTEL_BASIC_AUTH_USERNAME = os.getenv('OTEL_BASIC_AUTH_USERNAME', '') |
| OTEL_BASIC_AUTH_PASSWORD = os.getenv('OTEL_BASIC_AUTH_PASSWORD', '') |
| OTEL_METRICS_EXPORT_INTERVAL_MILLIS = int(os.getenv('OTEL_METRICS_EXPORT_INTERVAL_MILLIS', '10000')) |
|
|
| OTEL_METRICS_BASIC_AUTH_USERNAME = os.getenv('OTEL_METRICS_BASIC_AUTH_USERNAME', OTEL_BASIC_AUTH_USERNAME) |
| OTEL_METRICS_BASIC_AUTH_PASSWORD = os.getenv('OTEL_METRICS_BASIC_AUTH_PASSWORD', OTEL_BASIC_AUTH_PASSWORD) |
| OTEL_LOGS_BASIC_AUTH_USERNAME = os.getenv('OTEL_LOGS_BASIC_AUTH_USERNAME', OTEL_BASIC_AUTH_USERNAME) |
| OTEL_LOGS_BASIC_AUTH_PASSWORD = os.getenv('OTEL_LOGS_BASIC_AUTH_PASSWORD', OTEL_BASIC_AUTH_PASSWORD) |
|
|
| OTEL_OTLP_SPAN_EXPORTER = os.getenv('OTEL_OTLP_SPAN_EXPORTER', 'grpc').lower() |
|
|
| OTEL_METRICS_OTLP_SPAN_EXPORTER = os.getenv( |
| 'OTEL_METRICS_OTLP_SPAN_EXPORTER', OTEL_OTLP_SPAN_EXPORTER |
| ).lower() |
|
|
| OTEL_LOGS_OTLP_SPAN_EXPORTER = os.getenv( |
| 'OTEL_LOGS_OTLP_SPAN_EXPORTER', OTEL_OTLP_SPAN_EXPORTER |
| ).lower() |
|
|