From 2c61eb6e88f429c5098acc08fcdfa00dfd32d385 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Wed, 26 Nov 2025 13:33:15 +0800 Subject: [PATCH] perf: add proxys --- backend/open_webui/app.py | 4 + backend/open_webui/config.py | 278 ++++++++++++++--------------------- 2 files changed, 117 insertions(+), 165 deletions(-) diff --git a/backend/open_webui/app.py b/backend/open_webui/app.py index b24e32116b40..dfe0dcb1aa18 100644 --- a/backend/open_webui/app.py +++ b/backend/open_webui/app.py @@ -14,11 +14,13 @@ ENABLE_OLLAMA_API, OLLAMA_BASE_URLS, OLLAMA_API_CONFIGS, + OLLAMA_API_PROXYS, # OpenAI ENABLE_OPENAI_API, OPENAI_API_BASE_URLS, OPENAI_API_KEYS, OPENAI_API_CONFIGS, + OPENAI_API_PROXYS, # Direct Connections ENABLE_DIRECT_CONNECTIONS, # Model list @@ -372,6 +374,7 @@ def init_app_config(app): app.state.config.ENABLE_OLLAMA_API = ENABLE_OLLAMA_API app.state.config.OLLAMA_BASE_URLS = OLLAMA_BASE_URLS app.state.config.OLLAMA_API_CONFIGS = OLLAMA_API_CONFIGS + app.state.config.OLLAMA_API_PROXYS = OLLAMA_API_PROXYS app.state.OLLAMA_MODELS = {} @@ -384,6 +387,7 @@ def init_app_config(app): app.state.config.ENABLE_OPENAI_API = ENABLE_OPENAI_API app.state.config.OPENAI_API_BASE_URLS = OPENAI_API_BASE_URLS app.state.config.OPENAI_API_KEYS = OPENAI_API_KEYS + app.state.config.OPENAI_API_PROXYS = OPENAI_API_PROXYS app.state.config.OPENAI_API_CONFIGS = OPENAI_API_CONFIGS app.state.OPENAI_MODELS = {} diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 4a2d271d0c89..b9b0c57ca194 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -15,7 +15,6 @@ from sqlalchemy import JSON, Column, DateTime, Integer, func from authlib.integrations.starlette_client import OAuth - from open_webui.env import ( DATA_DIR, DATABASE_URL, @@ -44,6 +43,7 @@ def filter(self, record: logging.LogRecord) -> bool: # Filter out /endpoint logging.getLogger("uvicorn.access").addFilter(EndpointFilter()) + #################################### # Config helpers #################################### @@ -158,7 +158,7 @@ def save_config(config): T = TypeVar("T") ENABLE_PERSISTENT_CONFIG = ( - os.environ.get("ENABLE_PERSISTENT_CONFIG", "True").lower() == "true" + os.environ.get("ENABLE_PERSISTENT_CONFIG", "True").lower() == "true" ) @@ -171,8 +171,8 @@ def __init__(self, env_name: str, config_path: str, env_value: T): if self.config_value is not None and ENABLE_PERSISTENT_CONFIG: if ( - self.config_path.startswith("oauth.") - and not ENABLE_OAUTH_PERSISTENT_CONFIG + self.config_path.startswith("oauth.") + and not ENABLE_OAUTH_PERSISTENT_CONFIG ): log.info( f"Skipping loading of '{env_name}' as OAuth persistent config is disabled" @@ -228,11 +228,11 @@ class AppConfig: _state: dict[str, PersistentConfig] def __init__( - self, - redis_url: Optional[str] = None, - redis_sentinels: Optional[list] = [], - redis_cluster: Optional[bool] = False, - redis_key_prefix: str = "open-webui", + self, + redis_url: Optional[str] = None, + redis_sentinels: Optional[list] = [], + redis_cluster: Optional[bool] = False, + redis_key_prefix: str = "open-webui", ): if redis_url: super().__setattr__("_redis_key_prefix", redis_key_prefix) @@ -305,7 +305,6 @@ def __getattr__(self, key): os.environ.get("API_KEY_ALLOWED_ENDPOINTS", ""), ) - JWT_EXPIRES_IN = PersistentConfig( "JWT_EXPIRES_IN", "auth.jwt_expiry", os.environ.get("JWT_EXPIRES_IN", "4w") ) @@ -321,7 +320,7 @@ def __getattr__(self, key): #################################### ENABLE_OAUTH_PERSISTENT_CONFIG = ( - os.environ.get("ENABLE_OAUTH_PERSISTENT_CONFIG", "False").lower() == "true" + os.environ.get("ENABLE_OAUTH_PERSISTENT_CONFIG", "False").lower() == "true" ) ENABLE_OAUTH_SIGNUP = PersistentConfig( @@ -330,7 +329,6 @@ def __getattr__(self, key): os.environ.get("ENABLE_OAUTH_SIGNUP", "False").lower() == "true", ) - OAUTH_MERGE_ACCOUNTS_BY_EMAIL = PersistentConfig( "OAUTH_MERGE_ACCOUNTS_BY_EMAIL", "oauth.merge_accounts_by_email", @@ -351,7 +349,6 @@ def __getattr__(self, key): os.environ.get("GOOGLE_CLIENT_SECRET", ""), ) - GOOGLE_OAUTH_SCOPE = PersistentConfig( "GOOGLE_OAUTH_SCOPE", "oauth.google.scope", @@ -399,7 +396,6 @@ def __getattr__(self, key): ), ) - MICROSOFT_OAUTH_SCOPE = PersistentConfig( "MICROSOFT_OAUTH_SCOPE", "oauth.microsoft.scope", @@ -502,7 +498,6 @@ def __getattr__(self, key): os.environ.get("OAUTH_USERNAME_CLAIM", "name"), ) - OAUTH_PICTURE_CLAIM = PersistentConfig( "OAUTH_PICTURE_CLAIM", "oauth.oidc.avatar_claim", @@ -563,7 +558,6 @@ def __getattr__(self, key): os.environ.get("ENABLE_OAUTH_GROUP_CREATION", "False").lower() == "true", ) - OAUTH_BLOCKED_GROUPS = PersistentConfig( "OAUTH_BLOCKED_GROUPS", "oauth.blocked_groups", @@ -619,7 +613,6 @@ def __getattr__(self, key): def load_oauth_providers(): OAUTH_PROVIDERS.clear() if GOOGLE_CLIENT_ID.value and GOOGLE_CLIENT_SECRET.value: - def google_oauth_register(oauth: OAuth): client = oauth.register( name="google", @@ -644,11 +637,10 @@ def google_oauth_register(oauth: OAuth): } if ( - MICROSOFT_CLIENT_ID.value - and MICROSOFT_CLIENT_SECRET.value - and MICROSOFT_CLIENT_TENANT_ID.value + MICROSOFT_CLIENT_ID.value + and MICROSOFT_CLIENT_SECRET.value + and MICROSOFT_CLIENT_TENANT_ID.value ): - def microsoft_oauth_register(oauth: OAuth): client = oauth.register( name="microsoft", @@ -674,7 +666,6 @@ def microsoft_oauth_register(oauth: OAuth): } if GITHUB_CLIENT_ID.value and GITHUB_CLIENT_SECRET.value: - def github_oauth_register(oauth: OAuth): client = oauth.register( name="github", @@ -703,9 +694,9 @@ def github_oauth_register(oauth: OAuth): } if ( - OAUTH_CLIENT_ID.value - and (OAUTH_CLIENT_SECRET.value or OAUTH_CODE_CHALLENGE_METHOD.value) - and OPENID_PROVIDER_URL.value + OAUTH_CLIENT_ID.value + and (OAUTH_CLIENT_SECRET.value or OAUTH_CODE_CHALLENGE_METHOD.value) + and OPENID_PROVIDER_URL.value ): def oidc_oauth_register(oauth: OAuth): @@ -724,8 +715,8 @@ def oidc_oauth_register(oauth: OAuth): } if ( - OAUTH_CODE_CHALLENGE_METHOD.value - and OAUTH_CODE_CHALLENGE_METHOD.value == "S256" + OAUTH_CODE_CHALLENGE_METHOD.value + and OAUTH_CODE_CHALLENGE_METHOD.value == "S256" ): client_kwargs["code_challenge_method"] = "S256" elif OAUTH_CODE_CHALLENGE_METHOD.value: @@ -751,7 +742,6 @@ def oidc_oauth_register(oauth: OAuth): } if FEISHU_CLIENT_ID.value and FEISHU_CLIENT_SECRET.value: - def feishu_oauth_register(oauth: OAuth): client = oauth.register( name="feishu", @@ -852,7 +842,6 @@ def feishu_oauth_register(oauth: OAuth): except Exception as e: logging.error(f"An error occurred: {e}") - #################################### # CUSTOM_NAME (Legacy) #################################### @@ -895,7 +884,6 @@ def feishu_oauth_register(oauth: OAuth): log.exception(e) pass - #################################### # STORAGE PROVIDER #################################### @@ -909,7 +897,7 @@ def feishu_oauth_register(oauth: OAuth): S3_KEY_PREFIX = os.environ.get("S3_KEY_PREFIX", None) S3_ENDPOINT_URL = os.environ.get("S3_ENDPOINT_URL", None) S3_USE_ACCELERATE_ENDPOINT = ( - os.environ.get("S3_USE_ACCELERATE_ENDPOINT", "false").lower() == "true" + os.environ.get("S3_USE_ACCELERATE_ENDPOINT", "false").lower() == "true" ) S3_ADDRESSING_STYLE = os.environ.get("S3_ADDRESSING_STYLE", None) S3_ENABLE_TAGGING = os.getenv("S3_ENABLE_TAGGING", "false").lower() == "true" @@ -930,7 +918,6 @@ def feishu_oauth_register(oauth: OAuth): UPLOAD_DIR = DATA_DIR / "uploads" UPLOAD_DIR.mkdir(parents=True, exist_ok=True) - #################################### # Cache DIR #################################### @@ -938,7 +925,6 @@ def feishu_oauth_register(oauth: OAuth): CACHE_DIR = DATA_DIR / "cache" CACHE_DIR.mkdir(parents=True, exist_ok=True) - #################################### # DIRECT CONNECTIONS #################################### @@ -970,7 +956,6 @@ def feishu_oauth_register(oauth: OAuth): OLLAMA_BASE_URL[:-1] if OLLAMA_BASE_URL.endswith("/") else OLLAMA_BASE_URL ) - K8S_FLAG = os.environ.get("K8S_FLAG", "") USE_OLLAMA_DOCKER = os.environ.get("USE_OLLAMA_DOCKER", "false") @@ -992,7 +977,6 @@ def feishu_oauth_register(oauth: OAuth): elif K8S_FLAG: OLLAMA_BASE_URL = "http://ollama-service.open-webui.svc.cluster.local:11434" - OLLAMA_BASE_URLS = os.environ.get("OLLAMA_BASE_URLS", "") OLLAMA_BASE_URLS = OLLAMA_BASE_URLS if OLLAMA_BASE_URLS != "" else OLLAMA_BASE_URL @@ -1001,6 +985,14 @@ def feishu_oauth_register(oauth: OAuth): "OLLAMA_BASE_URLS", "ollama.base_urls", OLLAMA_BASE_URLS ) +OLLAMA_API_PROXYS = os.environ.get("OLLAMA_API_PROXYS", "") +OLLAMA_API_PROXYS = [ + p.strip() for p in OLLAMA_API_PROXYS.split(";") +] +OLLAMA_API_PROXYS = PersistentConfig( + "OLLAMA_API_PROXYS", "ollama.api_proxys", OLLAMA_API_PROXYS +) + OLLAMA_API_CONFIGS = PersistentConfig( "OLLAMA_API_CONFIGS", "ollama.api_configs", @@ -1018,14 +1010,12 @@ def feishu_oauth_register(oauth: OAuth): os.environ.get("ENABLE_OPENAI_API", "True").lower() == "true", ) - OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "") OPENAI_API_BASE_URL = os.environ.get("OPENAI_API_BASE_URL", "") GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "") GEMINI_API_BASE_URL = os.environ.get("GEMINI_API_BASE_URL", "") - if OPENAI_API_BASE_URL == "": OPENAI_API_BASE_URL = "https://api.openai.com/v1" else: @@ -1053,6 +1043,14 @@ def feishu_oauth_register(oauth: OAuth): "OPENAI_API_BASE_URLS", "openai.api_base_urls", OPENAI_API_BASE_URLS ) +OPENAI_API_PROXYS = os.environ.get("OPENAI_API_PROXYS", "") +OPENAI_API_PROXYS = [ + p.strip() for p in OPENAI_API_PROXYS.split(";") +] +OPENAI_API_PROXYS = PersistentConfig( + "OPENAI_API_PROXYS", "openai.api_proxys", OPENAI_API_PROXYS +) + OPENAI_API_CONFIGS = PersistentConfig( "OPENAI_API_CONFIGS", "openai.api_configs", @@ -1069,7 +1067,6 @@ def feishu_oauth_register(oauth: OAuth): pass OPENAI_API_BASE_URL = "https://api.openai.com/v1" - #################################### # MODELS #################################### @@ -1080,7 +1077,6 @@ def feishu_oauth_register(oauth: OAuth): os.environ.get("ENABLE_BASE_MODELS_CACHE", "False").lower() == "true", ) - #################################### # TOOL_SERVERS #################################### @@ -1093,7 +1089,6 @@ def feishu_oauth_register(oauth: OAuth): log.exception(f"Error loading TOOL_SERVER_CONNECTIONS: {e}") tool_server_connections = [] - TOOL_SERVER_CONNECTIONS = PersistentConfig( "TOOL_SERVER_CONNECTIONS", "tool_server.connections", @@ -1107,7 +1102,6 @@ def feishu_oauth_register(oauth: OAuth): WEBUI_URL = PersistentConfig("WEBUI_URL", "webui.url", os.environ.get("WEBUI_URL", "")) - ENABLE_SIGNUP = PersistentConfig( "ENABLE_SIGNUP", "ui.enable_signup", @@ -1124,7 +1118,6 @@ def feishu_oauth_register(oauth: OAuth): os.environ.get("ENABLE_LOGIN_FORM", "False").lower() == "true", ) - DEFAULT_LOCALE = PersistentConfig( "DEFAULT_LOCALE", "ui.default_locale", @@ -1203,170 +1196,165 @@ def feishu_oauth_register(oauth: OAuth): os.environ.get("PENDING_USER_OVERLAY_CONTENT", ""), ) - RESPONSE_WATERMARK = PersistentConfig( "RESPONSE_WATERMARK", "ui.watermark", os.environ.get("RESPONSE_WATERMARK", ""), ) - USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS = ( - os.environ.get("USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS", "False").lower() - == "true" + os.environ.get("USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS", "False").lower() + == "true" ) USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ACCESS = ( - os.environ.get("USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ACCESS", "False").lower() - == "true" + os.environ.get("USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ACCESS", "False").lower() + == "true" ) USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS = ( - os.environ.get("USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS", "False").lower() - == "true" + os.environ.get("USER_PERMISSIONS_WORKSPACE_PROMPTS_ACCESS", "False").lower() + == "true" ) USER_PERMISSIONS_WORKSPACE_TOOLS_ACCESS = ( - os.environ.get("USER_PERMISSIONS_WORKSPACE_TOOLS_ACCESS", "False").lower() == "true" + os.environ.get("USER_PERMISSIONS_WORKSPACE_TOOLS_ACCESS", "False").lower() == "true" ) USER_PERMISSIONS_WORKSPACE_MODELS_ALLOW_PUBLIC_SHARING = ( - os.environ.get( - "USER_PERMISSIONS_WORKSPACE_MODELS_ALLOW_PUBLIC_SHARING", "False" - ).lower() - == "true" + os.environ.get( + "USER_PERMISSIONS_WORKSPACE_MODELS_ALLOW_PUBLIC_SHARING", "False" + ).lower() + == "true" ) USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING = ( - os.environ.get("USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING", "False").lower() - == "true" + os.environ.get("USER_PERMISSIONS_NOTES_ALLOW_PUBLIC_SHARING", "False").lower() + == "true" ) USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ALLOW_PUBLIC_SHARING = ( - os.environ.get( - "USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ALLOW_PUBLIC_SHARING", "False" - ).lower() - == "true" + os.environ.get( + "USER_PERMISSIONS_WORKSPACE_KNOWLEDGE_ALLOW_PUBLIC_SHARING", "False" + ).lower() + == "true" ) USER_PERMISSIONS_WORKSPACE_PROMPTS_ALLOW_PUBLIC_SHARING = ( - os.environ.get( - "USER_PERMISSIONS_WORKSPACE_PROMPTS_ALLOW_PUBLIC_SHARING", "False" - ).lower() - == "true" + os.environ.get( + "USER_PERMISSIONS_WORKSPACE_PROMPTS_ALLOW_PUBLIC_SHARING", "False" + ).lower() + == "true" ) USER_PERMISSIONS_WORKSPACE_TOOLS_ALLOW_PUBLIC_SHARING = ( - os.environ.get( - "USER_PERMISSIONS_WORKSPACE_TOOLS_ALLOW_PUBLIC_SHARING", "False" - ).lower() - == "true" + os.environ.get( + "USER_PERMISSIONS_WORKSPACE_TOOLS_ALLOW_PUBLIC_SHARING", "False" + ).lower() + == "true" ) - USER_PERMISSIONS_CHAT_CONTROLS = ( - os.environ.get("USER_PERMISSIONS_CHAT_CONTROLS", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_CONTROLS", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_VALVES = ( - os.environ.get("USER_PERMISSIONS_CHAT_VALVES", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_VALVES", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_SYSTEM_PROMPT = ( - os.environ.get("USER_PERMISSIONS_CHAT_SYSTEM_PROMPT", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_SYSTEM_PROMPT", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_PARAMS = ( - os.environ.get("USER_PERMISSIONS_CHAT_PARAMS", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_PARAMS", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_FILE_UPLOAD = ( - os.environ.get("USER_PERMISSIONS_CHAT_FILE_UPLOAD", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_FILE_UPLOAD", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_DELETE = ( - os.environ.get("USER_PERMISSIONS_CHAT_DELETE", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_DELETE", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_DELETE_MESSAGE = ( - os.environ.get("USER_PERMISSIONS_CHAT_DELETE_MESSAGE", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_DELETE_MESSAGE", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_CONTINUE_RESPONSE = ( - os.environ.get("USER_PERMISSIONS_CHAT_CONTINUE_RESPONSE", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_CONTINUE_RESPONSE", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_REGENERATE_RESPONSE = ( - os.environ.get("USER_PERMISSIONS_CHAT_REGENERATE_RESPONSE", "True").lower() - == "true" + os.environ.get("USER_PERMISSIONS_CHAT_REGENERATE_RESPONSE", "True").lower() + == "true" ) USER_PERMISSIONS_CHAT_RATE_RESPONSE = ( - os.environ.get("USER_PERMISSIONS_CHAT_RATE_RESPONSE", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_RATE_RESPONSE", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_EDIT = ( - os.environ.get("USER_PERMISSIONS_CHAT_EDIT", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_EDIT", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_SHARE = ( - os.environ.get("USER_PERMISSIONS_CHAT_SHARE", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_SHARE", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_EXPORT = ( - os.environ.get("USER_PERMISSIONS_CHAT_EXPORT", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_EXPORT", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_STT = ( - os.environ.get("USER_PERMISSIONS_CHAT_STT", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_STT", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_TTS = ( - os.environ.get("USER_PERMISSIONS_CHAT_TTS", "False").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_TTS", "False").lower() == "true" ) USER_PERMISSIONS_CHAT_CALL = ( - os.environ.get("USER_PERMISSIONS_CHAT_CALL", "False").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_CALL", "False").lower() == "true" ) USER_PERMISSIONS_CHAT_MULTIPLE_MODELS = ( - os.environ.get("USER_PERMISSIONS_CHAT_MULTIPLE_MODELS", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_MULTIPLE_MODELS", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_TEMPORARY = ( - os.environ.get("USER_PERMISSIONS_CHAT_TEMPORARY", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_CHAT_TEMPORARY", "True").lower() == "true" ) USER_PERMISSIONS_CHAT_TEMPORARY_ENFORCED = ( - os.environ.get("USER_PERMISSIONS_CHAT_TEMPORARY_ENFORCED", "False").lower() - == "true" + os.environ.get("USER_PERMISSIONS_CHAT_TEMPORARY_ENFORCED", "False").lower() + == "true" ) - USER_PERMISSIONS_FEATURES_DIRECT_TOOL_SERVERS = ( - os.environ.get("USER_PERMISSIONS_FEATURES_DIRECT_TOOL_SERVERS", "False").lower() - == "true" + os.environ.get("USER_PERMISSIONS_FEATURES_DIRECT_TOOL_SERVERS", "False").lower() + == "true" ) USER_PERMISSIONS_FEATURES_WEB_SEARCH = ( - os.environ.get("USER_PERMISSIONS_FEATURES_WEB_SEARCH", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_FEATURES_WEB_SEARCH", "True").lower() == "true" ) USER_PERMISSIONS_FEATURES_IMAGE_GENERATION = ( - os.environ.get("USER_PERMISSIONS_FEATURES_IMAGE_GENERATION", "True").lower() - == "true" + os.environ.get("USER_PERMISSIONS_FEATURES_IMAGE_GENERATION", "True").lower() + == "true" ) USER_PERMISSIONS_FEATURES_CODE_INTERPRETER = ( - os.environ.get("USER_PERMISSIONS_FEATURES_CODE_INTERPRETER", "True").lower() - == "true" + os.environ.get("USER_PERMISSIONS_FEATURES_CODE_INTERPRETER", "True").lower() + == "true" ) USER_PERMISSIONS_FEATURES_NOTES = ( - os.environ.get("USER_PERMISSIONS_FEATURES_NOTES", "True").lower() == "true" + os.environ.get("USER_PERMISSIONS_FEATURES_NOTES", "True").lower() == "true" ) - DEFAULT_USER_PERMISSIONS = { "workspace": { "models": USER_PERMISSIONS_WORKSPACE_MODELS_ACCESS, @@ -1457,19 +1445,19 @@ def feishu_oauth_register(oauth: OAuth): ENABLE_ADMIN_EXPORT = os.environ.get("ENABLE_ADMIN_EXPORT", "True").lower() == "true" ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS = ( - os.environ.get("ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS", "True").lower() == "true" + os.environ.get("ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS", "True").lower() == "true" ) BYPASS_ADMIN_ACCESS_CONTROL = ( - os.environ.get( - "BYPASS_ADMIN_ACCESS_CONTROL", - os.environ.get("ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS", "True"), - ).lower() - == "true" + os.environ.get( + "BYPASS_ADMIN_ACCESS_CONTROL", + os.environ.get("ENABLE_ADMIN_WORKSPACE_CONTENT_ACCESS", "True"), + ).lower() + == "true" ) ENABLE_ADMIN_CHAT_ACCESS = ( - os.environ.get("ENABLE_ADMIN_CHAT_ACCESS", "True").lower() == "true" + os.environ.get("ENABLE_ADMIN_CHAT_ACCESS", "True").lower() == "true" ) ENABLE_COMMUNITY_SHARING = PersistentConfig( @@ -1559,7 +1547,6 @@ class BannerModel(BaseModel): WEBUI_BANNERS = PersistentConfig("WEBUI_BANNERS", "ui.banners", banners) - SHOW_ADMIN_DETAILS = PersistentConfig( "SHOW_ADMIN_DETAILS", "auth.admin.show", @@ -1572,7 +1559,6 @@ class BannerModel(BaseModel): os.environ.get("ADMIN_EMAIL", None), ) - #################################### # TASKS #################################### @@ -1693,7 +1679,6 @@ class BannerModel(BaseModel): {{MESSAGES:END:6}} """ - FOLLOW_UP_GENERATION_PROMPT_TEMPLATE = PersistentConfig( "FOLLOW_UP_GENERATION_PROMPT_TEMPLATE", "task.follow_up.prompt_template", @@ -1734,7 +1719,6 @@ class BannerModel(BaseModel): os.environ.get("ENABLE_TITLE_GENERATION", "True").lower() == "true", ) - ENABLE_SEARCH_QUERY_GENERATION = PersistentConfig( "ENABLE_SEARCH_QUERY_GENERATION", "task.query.search.enable", @@ -1747,7 +1731,6 @@ class BannerModel(BaseModel): os.environ.get("ENABLE_RETRIEVAL_QUERY_GENERATION", "True").lower() == "true", ) - QUERY_GENERATION_PROMPT_TEMPLATE = PersistentConfig( "QUERY_GENERATION_PROMPT_TEMPLATE", "task.query.prompt_template", @@ -1796,7 +1779,6 @@ class BannerModel(BaseModel): os.environ.get("AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE", ""), ) - DEFAULT_AUTOCOMPLETE_GENERATION_PROMPT_TEMPLATE = """### Task: You are an autocompletion system. Continue the text in `` based on the **completion type** in `` and the given language. @@ -1845,7 +1827,6 @@ class BannerModel(BaseModel): os.environ.get("TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE", ""), ) - DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE = """Available Tools: {{TOOLS}} Your task is to choose and return the correct tool(s) from the list of available tools based on the query. Follow these guidelines: @@ -1869,7 +1850,6 @@ class BannerModel(BaseModel): ] }""" - DEFAULT_EMOJI_GENERATION_PROMPT_TEMPLATE = """Your task is to reflect the speaker's likely facial expression through a fitting emoji. Interpret emotions from the message and reflect their facial expression using fitting, diverse emojis (e.g., 😊, 😢, 😡, 😱). Message: ```{{prompt}}```""" @@ -1880,7 +1860,6 @@ class BannerModel(BaseModel): Responses from models: {{responses}}""" - #################################### # Code Interpreter #################################### @@ -1915,7 +1894,6 @@ class BannerModel(BaseModel): os.environ.get("CODE_EXECUTION_JUPYTER_AUTH_TOKEN", ""), ) - CODE_EXECUTION_JUPYTER_AUTH_PASSWORD = PersistentConfig( "CODE_EXECUTION_JUPYTER_AUTH_PASSWORD", "code_execution.jupyter.auth_password", @@ -1972,7 +1950,6 @@ class BannerModel(BaseModel): ), ) - CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD = PersistentConfig( "CODE_INTERPRETER_JUPYTER_AUTH_PASSWORD", "code_interpreter.jupyter.auth_password", @@ -2015,7 +1992,6 @@ class BannerModel(BaseModel): Ensure that the tools are effectively utilized to achieve the highest-quality analysis for the user.""" - #################################### # Vector Database #################################### @@ -2061,7 +2037,7 @@ class BannerModel(BaseModel): os.environ.get("MILVUS_DISKANN_SEARCH_LIST_SIZE", "100") ) ENABLE_MILVUS_MULTITENANCY_MODE = ( - os.environ.get("ENABLE_MILVUS_MULTITENANCY_MODE", "false").lower() == "true" + os.environ.get("ENABLE_MILVUS_MULTITENANCY_MODE", "false").lower() == "true" ) # Hyphens not allowed, need to use underscores in collection names MILVUS_COLLECTION_PREFIX = os.environ.get("MILVUS_COLLECTION_PREFIX", "open_webui") @@ -2075,7 +2051,7 @@ class BannerModel(BaseModel): QDRANT_TIMEOUT = int(os.environ.get("QDRANT_TIMEOUT", "5")) QDRANT_HNSW_M = int(os.environ.get("QDRANT_HNSW_M", "16")) ENABLE_QDRANT_MULTITENANCY_MODE = ( - os.environ.get("ENABLE_QDRANT_MULTITENANCY_MODE", "true").lower() == "true" + os.environ.get("ENABLE_QDRANT_MULTITENANCY_MODE", "true").lower() == "true" ) QDRANT_COLLECTION_PREFIX = os.environ.get("QDRANT_COLLECTION_PREFIX", "open-webui") @@ -2083,7 +2059,7 @@ class BannerModel(BaseModel): OPENSEARCH_URI = os.environ.get("OPENSEARCH_URI", "https://localhost:9200") OPENSEARCH_SSL = os.environ.get("OPENSEARCH_SSL", "true").lower() == "true" OPENSEARCH_CERT_VERIFY = ( - os.environ.get("OPENSEARCH_CERT_VERIFY", "false").lower() == "true" + os.environ.get("OPENSEARCH_CERT_VERIFY", "false").lower() == "true" ) OPENSEARCH_USERNAME = os.environ.get("OPENSEARCH_USERNAME", None) OPENSEARCH_PASSWORD = os.environ.get("OPENSEARCH_PASSWORD", None) @@ -2110,7 +2086,7 @@ class BannerModel(BaseModel): ) PGVECTOR_CREATE_EXTENSION = ( - os.getenv("PGVECTOR_CREATE_EXTENSION", "true").lower() == "true" + os.getenv("PGVECTOR_CREATE_EXTENSION", "true").lower() == "true" ) PGVECTOR_PGCRYPTO = os.getenv("PGVECTOR_PGCRYPTO", "false").lower() == "true" PGVECTOR_PGCRYPTO_KEY = os.getenv("PGVECTOR_PGCRYPTO_KEY", None) @@ -2119,7 +2095,6 @@ class BannerModel(BaseModel): "PGVECTOR_PGCRYPTO is enabled but PGVECTOR_PGCRYPTO_KEY is not set. Please provide a valid key." ) - PGVECTOR_POOL_SIZE = os.environ.get("PGVECTOR_POOL_SIZE", None) if PGVECTOR_POOL_SIZE != None: @@ -2180,7 +2155,6 @@ class BannerModel(BaseModel): ORACLE_DB_POOL_MAX = int(os.environ.get("ORACLE_DB_POOL_MAX", 10)) ORACLE_DB_POOL_INCREMENT = int(os.environ.get("ORACLE_DB_POOL_INCREMENT", 1)) - if VECTOR_DB == "oracle23ai": if not ORACLE_DB_USER or not ORACLE_DB_PASSWORD or not ORACLE_DB_DSN: raise ValueError( @@ -2227,12 +2201,11 @@ class BannerModel(BaseModel): os.getenv("ENABLE_ONEDRIVE_INTEGRATION", "False").lower() == "true", ) - ENABLE_ONEDRIVE_PERSONAL = ( - os.environ.get("ENABLE_ONEDRIVE_PERSONAL", "True").lower() == "true" + os.environ.get("ENABLE_ONEDRIVE_PERSONAL", "True").lower() == "true" ) ENABLE_ONEDRIVE_BUSINESS = ( - os.environ.get("ENABLE_ONEDRIVE_BUSINESS", "True").lower() == "true" + os.environ.get("ENABLE_ONEDRIVE_BUSINESS", "True").lower() == "true" ) ONEDRIVE_CLIENT_ID = os.environ.get("ONEDRIVE_CLIENT_ID", "") @@ -2449,14 +2422,12 @@ class BannerModel(BaseModel): os.getenv("DOCLING_PICTURE_DESCRIPTION_MODE", ""), ) - docling_picture_description_local = os.getenv("DOCLING_PICTURE_DESCRIPTION_LOCAL", "") try: docling_picture_description_local = json.loads(docling_picture_description_local) except json.JSONDecodeError: docling_picture_description_local = {} - DOCLING_PICTURE_DESCRIPTION_LOCAL = PersistentConfig( "DOCLING_PICTURE_DESCRIPTION_LOCAL", "rag.docling_picture_description_local", @@ -2469,14 +2440,12 @@ class BannerModel(BaseModel): except json.JSONDecodeError: docling_picture_description_api = {} - DOCLING_PICTURE_DESCRIPTION_API = PersistentConfig( "DOCLING_PICTURE_DESCRIPTION_API", "rag.docling_picture_description_api", docling_picture_description_api, ) - DOCUMENT_INTELLIGENCE_ENDPOINT = PersistentConfig( "DOCUMENT_INTELLIGENCE_ENDPOINT", "rag.document_intelligence_endpoint", @@ -2507,7 +2476,6 @@ class BannerModel(BaseModel): os.environ.get("BYPASS_EMBEDDING_AND_RETRIEVAL", "False").lower() == "true", ) - RAG_TOP_K = PersistentConfig( "RAG_TOP_K", "rag.top_k", int(os.environ.get("RAG_TOP_K", "3")) ) @@ -2579,7 +2547,6 @@ class BannerModel(BaseModel): ), ) - RAG_ALLOWED_FILE_EXTENSIONS = PersistentConfig( "RAG_ALLOWED_FILE_EXTENSIONS", "rag.file.allowed_extensions", @@ -2610,12 +2577,12 @@ class BannerModel(BaseModel): log.info(f"Embedding model set: {RAG_EMBEDDING_MODEL.value}") RAG_EMBEDDING_MODEL_AUTO_UPDATE = ( - not OFFLINE_MODE - and os.environ.get("RAG_EMBEDDING_MODEL_AUTO_UPDATE", "True").lower() == "true" + not OFFLINE_MODE + and os.environ.get("RAG_EMBEDDING_MODEL_AUTO_UPDATE", "True").lower() == "true" ) RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE = ( - os.environ.get("RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE", "True").lower() == "true" + os.environ.get("RAG_EMBEDDING_MODEL_TRUST_REMOTE_CODE", "True").lower() == "true" ) RAG_EMBEDDING_BATCH_SIZE = PersistentConfig( @@ -2649,14 +2616,13 @@ class BannerModel(BaseModel): if RAG_RERANKING_MODEL.value != "": log.info(f"Reranking model set: {RAG_RERANKING_MODEL.value}") - RAG_RERANKING_MODEL_AUTO_UPDATE = ( - not OFFLINE_MODE - and os.environ.get("RAG_RERANKING_MODEL_AUTO_UPDATE", "True").lower() == "true" + not OFFLINE_MODE + and os.environ.get("RAG_RERANKING_MODEL_AUTO_UPDATE", "True").lower() == "true" ) RAG_RERANKING_MODEL_TRUST_REMOTE_CODE = ( - os.environ.get("RAG_RERANKING_MODEL_TRUST_REMOTE_CODE", "True").lower() == "true" + os.environ.get("RAG_RERANKING_MODEL_TRUST_REMOTE_CODE", "True").lower() == "true" ) RAG_EXTERNAL_RERANKER_URL = PersistentConfig( @@ -2671,14 +2637,12 @@ class BannerModel(BaseModel): os.environ.get("RAG_EXTERNAL_RERANKER_API_KEY", ""), ) - RAG_TEXT_SPLITTER = PersistentConfig( "RAG_TEXT_SPLITTER", "rag.text_splitter", os.environ.get("RAG_TEXT_SPLITTER", ""), ) - TIKTOKEN_CACHE_DIR = os.environ.get("TIKTOKEN_CACHE_DIR", f"{CACHE_DIR}/tiktoken") TIKTOKEN_ENCODING_NAME = PersistentConfig( "TIKTOKEN_ENCODING_NAME", @@ -2686,7 +2650,6 @@ class BannerModel(BaseModel): os.environ.get("TIKTOKEN_ENCODING_NAME", "cl100k_base"), ) - CHUNK_SIZE = PersistentConfig( "CHUNK_SIZE", "rag.chunk_size", int(os.environ.get("CHUNK_SIZE", "1000")) ) @@ -2771,9 +2734,8 @@ class BannerModel(BaseModel): os.getenv("RAG_OLLAMA_API_KEY", ""), ) - ENABLE_RAG_LOCAL_WEB_FETCH = ( - os.getenv("ENABLE_RAG_LOCAL_WEB_FETCH", "False").lower() == "true" + os.getenv("ENABLE_RAG_LOCAL_WEB_FETCH", "False").lower() == "true" ) YOUTUBE_LOADER_LANGUAGE = PersistentConfig( @@ -2788,7 +2750,6 @@ class BannerModel(BaseModel): os.getenv("YOUTUBE_LOADER_PROXY_URL", ""), ) - #################################### # Web Search (RAG) #################################### @@ -2811,7 +2772,6 @@ class BannerModel(BaseModel): os.getenv("BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL", "False").lower() == "true", ) - BYPASS_WEB_SEARCH_WEB_LOADER = PersistentConfig( "BYPASS_WEB_SEARCH_WEB_LOADER", "rag.web.search.bypass_web_loader", @@ -2824,7 +2784,6 @@ class BannerModel(BaseModel): int(os.getenv("WEB_SEARCH_RESULT_COUNT", "3")), ) - # You can provide a list of your own websites to filter after performing a web search. # This ensures the highest level of safety and reliability of the information sources. WEB_SEARCH_DOMAIN_FILTER_LIST = PersistentConfig( @@ -2843,21 +2802,18 @@ class BannerModel(BaseModel): int(os.getenv("WEB_SEARCH_CONCURRENT_REQUESTS", "10")), ) - WEB_LOADER_ENGINE = PersistentConfig( "WEB_LOADER_ENGINE", "rag.web.loader.engine", os.environ.get("WEB_LOADER_ENGINE", ""), ) - WEB_LOADER_CONCURRENT_REQUESTS = PersistentConfig( "WEB_LOADER_CONCURRENT_REQUESTS", "rag.web.loader.concurrent_requests", int(os.getenv("WEB_LOADER_CONCURRENT_REQUESTS", "10")), ) - ENABLE_WEB_LOADER_SSL_VERIFICATION = PersistentConfig( "ENABLE_WEB_LOADER_SSL_VERIFICATION", "rag.web.loader.ssl_verification", @@ -2870,7 +2826,6 @@ class BannerModel(BaseModel): os.getenv("WEB_SEARCH_TRUST_ENV", "False").lower() == "true", ) - OLLAMA_CLOUD_WEB_SEARCH_API_KEY = PersistentConfig( "OLLAMA_CLOUD_WEB_SEARCH_API_KEY", "rag.web.search.ollama_cloud_api_key", @@ -3154,7 +3109,6 @@ class BannerModel(BaseModel): except json.JSONDecodeError: automatic1111_params = {} - AUTOMATIC1111_PARAMS = PersistentConfig( "AUTOMATIC1111_PARAMS", "image_generation.automatic1111.api_auth", @@ -3283,7 +3237,6 @@ class BannerModel(BaseModel): } """ - COMFYUI_WORKFLOW = PersistentConfig( "COMFYUI_WORKFLOW", "image_generation.comfyui.workflow", @@ -3330,7 +3283,6 @@ class BannerModel(BaseModel): os.getenv("IMAGES_GEMINI_ENDPOINT_METHOD", ""), ) - IMAGE_EDIT_ENGINE = PersistentConfig( "IMAGE_EDIT_ENGINE", "images.edit.engine", @@ -3375,7 +3327,6 @@ class BannerModel(BaseModel): os.getenv("IMAGES_EDIT_GEMINI_API_KEY", GEMINI_API_KEY), ) - IMAGES_EDIT_COMFYUI_BASE_URL = PersistentConfig( "IMAGES_EDIT_COMFYUI_BASE_URL", "images.edit.comfyui.base_url", @@ -3412,8 +3363,8 @@ class BannerModel(BaseModel): WHISPER_MODEL_DIR = os.getenv("WHISPER_MODEL_DIR", f"{CACHE_DIR}/whisper/models") WHISPER_MODEL_AUTO_UPDATE = ( - not OFFLINE_MODE - and os.environ.get("WHISPER_MODEL_AUTO_UPDATE", "").lower() == "true" + not OFFLINE_MODE + and os.environ.get("WHISPER_MODEL_AUTO_UPDATE", "").lower() == "true" ) WHISPER_VAD_FILTER = PersistentConfig( @@ -3466,8 +3417,8 @@ class BannerModel(BaseModel): [ content_type.strip() for content_type in os.environ.get( - "AUDIO_STT_SUPPORTED_CONTENT_TYPES", "" - ).split(",") + "AUDIO_STT_SUPPORTED_CONTENT_TYPES", "" + ).split(",") if content_type.strip() ], ) @@ -3543,7 +3494,6 @@ class BannerModel(BaseModel): audio_tts_openai_params, ) - AUDIO_TTS_API_KEY = PersistentConfig( "AUDIO_TTS_API_KEY", "audio.tts.api_key", @@ -3556,7 +3506,6 @@ class BannerModel(BaseModel): os.getenv("AUDIO_TTS_ENGINE", ""), ) - AUDIO_TTS_MODEL = PersistentConfig( "AUDIO_TTS_MODEL", "audio.tts.model", @@ -3595,7 +3544,6 @@ class BannerModel(BaseModel): ), ) - #################################### # LDAP ####################################