Merge branch 'dev' into feat/scim-2.0-support

This commit is contained in:
Dieu
2025-07-14 00:48:50 +02:00
committed by GitHub
302 changed files with 16478 additions and 7350 deletions
+68 -13
View File
@@ -36,7 +36,6 @@ from fastapi import (
applications,
BackgroundTasks,
)
from fastapi.openapi.docs import get_swagger_ui_html
from fastapi.middleware.cors import CORSMiddleware
@@ -49,6 +48,7 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.middleware.sessions import SessionMiddleware
from starlette.responses import Response, StreamingResponse
from starlette.datastructures import Headers
from open_webui.utils import logger
@@ -117,9 +117,14 @@ from open_webui.config import (
OPENAI_API_CONFIGS,
# Direct Connections
ENABLE_DIRECT_CONNECTIONS,
# SCIM
SCIM_ENABLED,
SCIM_TOKEN,
# Model list
ENABLE_BASE_MODELS_CACHE,
# Thread pool size for FastAPI/AnyIO
THREAD_POOL_SIZE,
# Tool Server Configs
@@ -400,6 +405,7 @@ from open_webui.env import (
AUDIT_LOG_LEVEL,
CHANGELOG,
REDIS_URL,
REDIS_KEY_PREFIX,
REDIS_SENTINEL_HOSTS,
REDIS_SENTINEL_PORT,
GLOBAL_LOG_LEVEL,
@@ -415,10 +421,11 @@ from open_webui.env import (
WEBUI_AUTH_TRUSTED_EMAIL_HEADER,
WEBUI_AUTH_TRUSTED_NAME_HEADER,
WEBUI_AUTH_SIGNOUT_REDIRECT_URL,
ENABLE_COMPRESSION_MIDDLEWARE,
ENABLE_WEBSOCKET_SUPPORT,
BYPASS_MODEL_ACCESS_CONTROL,
RESET_CONFIG_ON_START,
OFFLINE_MODE,
ENABLE_VERSION_UPDATE_CHECK,
ENABLE_OTEL,
EXTERNAL_PWA_MANIFEST_URL,
AIOHTTP_CLIENT_SESSION_SSL,
@@ -453,7 +460,7 @@ from open_webui.utils.redis import get_redis_connection
from open_webui.tasks import (
redis_task_command_listener,
list_task_ids_by_chat_id,
list_task_ids_by_item_id,
stop_task,
list_tasks,
) # Import from tasks.py
@@ -537,6 +544,27 @@ async def lifespan(app: FastAPI):
asyncio.create_task(periodic_usage_pool_cleanup())
if app.state.config.ENABLE_BASE_MODELS_CACHE:
await get_all_models(
Request(
# Creating a mock request object to pass to get_all_models
{
"type": "http",
"asgi.version": "3.0",
"asgi.spec_version": "2.0",
"method": "GET",
"path": "/internal",
"query_string": b"",
"headers": Headers({}).raw,
"client": ("127.0.0.1", 12345),
"server": ("127.0.0.1", 80),
"scheme": "http",
"app": app,
}
),
None,
)
yield
if hasattr(app.state, "redis_task_command_listener"):
@@ -557,6 +585,7 @@ app.state.instance_id = None
app.state.config = AppConfig(
redis_url=REDIS_URL,
redis_sentinels=get_sentinels_from_env(REDIS_SENTINEL_HOSTS, REDIS_SENTINEL_PORT),
redis_key_prefix=REDIS_KEY_PREFIX,
)
app.state.redis = None
@@ -628,6 +657,15 @@ app.state.config.ENABLE_DIRECT_CONNECTIONS = ENABLE_DIRECT_CONNECTIONS
app.state.config.SCIM_ENABLED = SCIM_ENABLED
app.state.config.SCIM_TOKEN = SCIM_TOKEN
########################################
#
# MODELS
#
########################################
app.state.config.ENABLE_BASE_MODELS_CACHE = ENABLE_BASE_MODELS_CACHE
app.state.BASE_MODELS = []
########################################
#
# WEBUI
@@ -1085,7 +1123,9 @@ class RedirectMiddleware(BaseHTTPMiddleware):
# Add the middleware to the app
app.add_middleware(CompressMiddleware)
if ENABLE_COMPRESSION_MIDDLEWARE:
app.add_middleware(CompressMiddleware)
app.add_middleware(RedirectMiddleware)
app.add_middleware(SecurityHeadersMiddleware)
@@ -1204,7 +1244,9 @@ if audit_level != AuditLevel.NONE:
@app.get("/api/models")
async def get_models(request: Request, user=Depends(get_verified_user)):
async def get_models(
request: Request, refresh: bool = False, user=Depends(get_verified_user)
):
def get_filtered_models(models, user):
filtered_models = []
for model in models:
@@ -1228,7 +1270,7 @@ async def get_models(request: Request, user=Depends(get_verified_user)):
return filtered_models
all_models = await get_all_models(request, user=user)
all_models = await get_all_models(request, refresh=refresh, user=user)
models = []
for model in all_models:
@@ -1463,7 +1505,7 @@ async def stop_task_endpoint(
request: Request, task_id: str, user=Depends(get_verified_user)
):
try:
result = await stop_task(request, task_id)
result = await stop_task(request.app.state.redis, task_id)
return result
except ValueError as e:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(e))
@@ -1471,7 +1513,7 @@ async def stop_task_endpoint(
@app.get("/api/tasks")
async def list_tasks_endpoint(request: Request, user=Depends(get_verified_user)):
return {"tasks": await list_tasks(request)}
return {"tasks": await list_tasks(request.app.state.redis)}
@app.get("/api/tasks/chat/{chat_id}")
@@ -1482,9 +1524,9 @@ async def list_tasks_by_chat_id_endpoint(
if chat is None or chat.user_id != user.id:
return {"task_ids": []}
task_ids = await list_task_ids_by_chat_id(request, chat_id)
task_ids = await list_task_ids_by_item_id(request.app.state.redis, chat_id)
print(f"Task IDs for chat {chat_id}: {task_ids}")
log.debug(f"Task IDs for chat {chat_id}: {task_ids}")
return {"task_ids": task_ids}
@@ -1537,6 +1579,7 @@ async def get_app_config(request: Request):
"enable_signup": app.state.config.ENABLE_SIGNUP,
"enable_login_form": app.state.config.ENABLE_LOGIN_FORM,
"enable_websocket": ENABLE_WEBSOCKET_SUPPORT,
"enable_version_update_check": ENABLE_VERSION_UPDATE_CHECK,
**(
{
"enable_direct_connections": app.state.config.ENABLE_DIRECT_CONNECTIONS,
@@ -1610,7 +1653,19 @@ async def get_app_config(request: Request):
),
}
if user is not None
else {}
else {
**(
{
"metadata": {
"login_footer": app.state.LICENSE_METADATA.get(
"login_footer", ""
)
}
}
if app.state.LICENSE_METADATA
else {}
)
}
),
}
@@ -1642,9 +1697,9 @@ async def get_app_version():
@app.get("/api/version/updates")
async def get_app_latest_release_version(user=Depends(get_verified_user)):
if OFFLINE_MODE:
if not ENABLE_VERSION_UPDATE_CHECK:
log.debug(
f"Offline mode is enabled, returning current version as latest version"
f"Version update check is disabled, returning current version as latest version"
)
return {"current": VERSION, "latest": VERSION}
try: