refac: modernize type annotations (PEP 604 / PEP 585)

This commit is contained in:
Timothy Jaeryang Baek
2026-05-12 17:10:15 +09:00
parent a59c967d7e
commit 6d0295588e
197 changed files with 3265 additions and 3488 deletions
@@ -1,16 +1,15 @@
import json
from typing import Any
from open_webui.models.users import UserModel
from open_webui.models.groups import Groups
from open_webui.config import DEFAULT_USER_PERMISSIONS
from open_webui.models.access_grants import (
has_public_read_access_grant,
has_public_write_access_grant,
has_user_access_grant,
strip_user_access_grants,
)
from open_webui.config import DEFAULT_USER_PERMISSIONS
from open_webui.models.groups import Groups
from open_webui.models.users import UserModel
from sqlalchemy.ext.asyncio import AsyncSession
@@ -272,8 +271,8 @@ async def has_base_model_access(
provider model that has no per-model ACL). Returns ``False`` the
moment a registered base model denies access.
"""
from open_webui.models.models import Models
from open_webui.models.access_grants import AccessGrants
from open_webui.models.models import Models
base_model_id = getattr(model_info, 'base_model_id', None)
seen = {model_info.id}
@@ -1,14 +1,13 @@
import logging
from open_webui.models.users import UserModel
from open_webui.models.files import Files
from open_webui.models.knowledge import Knowledges
from open_webui.models.access_grants import AccessGrants
from open_webui.models.channels import Channels
from open_webui.models.chats import Chats
from open_webui.models.files import Files
from open_webui.models.groups import Groups
from open_webui.models.knowledge import Knowledges
from open_webui.models.models import Models
from open_webui.models.access_grants import AccessGrants
from open_webui.models.users import UserModel
from sqlalchemy.ext.asyncio import AsyncSession
log = logging.getLogger(__name__)
+7 -11
View File
@@ -1,20 +1,16 @@
import inspect
import logging
import sys
import inspect
from typing import Any
from fastapi import Request
from open_webui.models.users import UserModel
from open_webui.models.functions import Functions
from open_webui.socket.main import get_event_call, get_event_emitter
from open_webui.utils.plugin import get_function_module_from_cache
from open_webui.utils.models import get_all_models
from open_webui.utils.middleware import process_tool_result
from open_webui.env import GLOBAL_LOG_LEVEL
from open_webui.models.functions import Functions
from open_webui.models.users import UserModel
from open_webui.socket.main import get_event_call, get_event_emitter
from open_webui.utils.middleware import process_tool_result
from open_webui.utils.models import get_all_models
from open_webui.utils.plugin import get_function_module_from_cache
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
log = logging.getLogger(__name__)
-1
View File
@@ -2,7 +2,6 @@ import json
import logging
import aiohttp
from open_webui.env import (
AIOHTTP_CLIENT_SESSION_SSL,
AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST,
+3 -4
View File
@@ -37,13 +37,12 @@ from urllib.parse import parse_qs, urlencode
from fastapi.responses import JSONResponse, RedirectResponse
from fastapi.security import HTTPAuthorizationCredentials
from starlette.datastructures import MutableHeaders
from starlette.requests import Request
from starlette.types import ASGIApp, Message, Receive, Scope, Send
from open_webui.env import CUSTOM_API_KEY_HEADER
from open_webui.internal.db import ScopedSession
from open_webui.utils.auth import get_http_authorization_cred
from starlette.datastructures import MutableHeaders
from starlette.requests import Request
from starlette.types import ASGIApp, Message, Receive, Scope, Send
log = logging.getLogger(__name__)
+7 -6
View File
@@ -1,7 +1,8 @@
import re
import uuid
from contextlib import asynccontextmanager
from dataclasses import asdict, dataclass
from enum import Enum
import re
from typing import (
TYPE_CHECKING,
Any,
@@ -11,7 +12,6 @@ from typing import (
Optional,
cast,
)
import uuid
from asgiref.typing import (
ASGI3Application,
@@ -19,14 +19,15 @@ from asgiref.typing import (
ASGIReceiveEvent,
ASGISendCallable,
ASGISendEvent,
)
from asgiref.typing import (
Scope as ASGIScope,
)
from loguru import logger
from starlette.requests import Request
from open_webui.env import AUDIT_LOG_LEVEL, ENABLE_AUDIT_GET_REQUESTS, AUDIT_INCLUDED_PATHS, MAX_BODY_LOG_SIZE
from open_webui.utils.auth import get_current_user, get_http_authorization_cred
from open_webui.env import AUDIT_INCLUDED_PATHS, AUDIT_LOG_LEVEL, ENABLE_AUDIT_GET_REQUESTS, MAX_BODY_LOG_SIZE
from open_webui.models.users import UserModel
from open_webui.utils.auth import get_current_user, get_http_authorization_cred
from starlette.requests import Request
if TYPE_CHECKING:
from loguru import Logger
+26 -32
View File
@@ -1,49 +1,43 @@
import logging
import uuid
import jwt
from __future__ import annotations
import base64
import hmac
import hashlib
import requests
import os
import bcrypt
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
import hmac
import json
import logging
import os
import uuid
from datetime import datetime, timedelta
from typing import Optional, Union
import bcrypt
import jwt
import pytz
from pytz import UTC
from typing import Optional, Union, List, Dict
from open_webui.utils.access_control import has_permission
from open_webui.models.users import Users
from open_webui.models.auths import Auths
import requests
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from fastapi import BackgroundTasks, Depends, HTTPException, Request, Response, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from open_webui.constants import ERROR_MESSAGES
from open_webui.env import (
ENABLE_OTEL,
ENABLE_PASSWORD_VALIDATION,
OFFLINE_MODE,
LICENSE_BLOB,
OFFLINE_MODE,
PASSWORD_VALIDATION_HINT,
PASSWORD_VALIDATION_REGEX_PATTERN,
REDIS_KEY_PREFIX,
pk,
WEBUI_SECRET_KEY,
TRUSTED_SIGNATURE_KEY,
STATIC_DIR,
TRUSTED_SIGNATURE_KEY,
WEBUI_AUTH_TRUSTED_EMAIL_HEADER,
WEBUI_SECRET_KEY,
pk,
)
from fastapi import BackgroundTasks, Depends, HTTPException, Request, Response, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from open_webui.models.auths import Auths
from open_webui.models.users import Users
from open_webui.utils.access_control import has_permission
from pytz import UTC
log = logging.getLogger(__name__)
@@ -211,7 +205,7 @@ def create_token(data: dict, expires_delta: Union[timedelta, None] = None) -> st
return encoded_jwt
def decode_token(token: str) -> Optional[dict]:
def decode_token(token: str) -> dict | None:
try:
decoded = jwt.decode(token, SESSION_SECRET, algorithms=[ALGORITHM])
return decoded
@@ -284,7 +278,7 @@ def create_api_key():
return f'sk-{key}'
def get_http_authorization_cred(auth_header: Optional[str]):
def get_http_authorization_cred(auth_header: str | None):
if not auth_header:
return None
try:
+3 -4
View File
@@ -25,14 +25,13 @@ from zoneinfo import ZoneInfo
from dateutil.rrule import rrulestr
from fastapi import Request
from starlette.datastructures import Headers
from open_webui.constants import ERROR_MESSAGES
from open_webui.models.automations import Automations, AutomationRuns, AutomationModel
from open_webui.internal.db import get_async_db
from open_webui.models.automations import AutomationModel, AutomationRuns, Automations
from open_webui.models.chats import ChatForm, Chats
from open_webui.models.users import Users
from open_webui.utils.task import prompt_template
from open_webui.internal.db import get_async_db
from starlette.datastructures import Headers
log = logging.getLogger(__name__)
+24 -35
View File
@@ -1,56 +1,45 @@
import time
import asyncio
import json
import logging
import random
import sys
import time
import uuid
from typing import Any, Optional
from aiocache import cached
from typing import Any, Optional
import random
import json
import uuid
import asyncio
from fastapi import HTTPException, Request, status
from starlette.responses import Response, StreamingResponse, JSONResponse
from open_webui.models.users import UserModel
from open_webui.socket.main import (
sio,
get_event_call,
get_event_emitter,
)
from open_webui.env import BYPASS_MODEL_ACCESS_CONTROL, GLOBAL_LOG_LEVEL
from open_webui.functions import generate_function_chat_completion
from open_webui.routers.openai import (
generate_chat_completion as generate_openai_chat_completion,
)
from open_webui.models.functions import Functions
from open_webui.models.models import Models
from open_webui.models.users import UserModel
from open_webui.routers.ollama import (
generate_chat_completion as generate_ollama_chat_completion,
)
from open_webui.routers.openai import (
generate_chat_completion as generate_openai_chat_completion,
)
from open_webui.routers.pipelines import (
process_pipeline_inlet_filter,
process_pipeline_outlet_filter,
)
from open_webui.models.functions import Functions
from open_webui.models.models import Models
from open_webui.utils.models import get_all_models, check_model_access
from open_webui.utils.payload import convert_payload_openai_to_ollama
from open_webui.utils.response import (
convert_response_ollama_to_openai,
convert_streaming_response_ollama_to_openai,
from open_webui.socket.main import (
get_event_call,
get_event_emitter,
sio,
)
from open_webui.utils.filter import (
get_sorted_filter_ids,
process_filter_functions,
)
from open_webui.env import GLOBAL_LOG_LEVEL, BYPASS_MODEL_ACCESS_CONTROL
from open_webui.utils.models import check_model_access, get_all_models
from open_webui.utils.payload import convert_payload_openai_to_ollama
from open_webui.utils.response import (
convert_response_ollama_to_openai,
convert_streaming_response_ollama_to_openai,
)
from starlette.responses import JSONResponse, Response, StreamingResponse
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
log = logging.getLogger(__name__)
+1 -2
View File
@@ -6,9 +6,8 @@ from typing import Optional
import aiohttp
import websockets
from pydantic import BaseModel
from open_webui.env import AIOHTTP_CLIENT_ALLOW_REDIRECTS
from pydantic import BaseModel
logger = logging.getLogger(__name__)
+8 -8
View File
@@ -1,19 +1,19 @@
import random
import logging
import random
import sys
from fastapi import Request
from open_webui.models.users import UserModel
from open_webui.env import BYPASS_MODEL_ACCESS_CONTROL, GLOBAL_LOG_LEVEL
from open_webui.models.models import Models
from open_webui.utils.models import check_model_access
from open_webui.env import GLOBAL_LOG_LEVEL, BYPASS_MODEL_ACCESS_CONTROL
from open_webui.routers.openai import embeddings as openai_embeddings
from open_webui.models.users import UserModel
from open_webui.routers.ollama import (
embed as ollama_embed,
GenerateEmbedForm,
)
from open_webui.routers.ollama import (
embed as ollama_embed,
)
from open_webui.routers.openai import embeddings as openai_embeddings
from open_webui.utils.models import check_model_access
from open_webui.utils.payload import convert_embed_payload_openai_to_ollama
from open_webui.utils.response import convert_embedding_response_ollama_to_openai
+16 -20
View File
@@ -1,7 +1,10 @@
from open_webui.routers.images import (
get_image_data,
upload_image,
)
import asyncio
import base64
import io
import mimetypes
import re
from pathlib import Path
from typing import Optional
from fastapi import (
APIRouter,
@@ -10,27 +13,20 @@ from fastapi import (
Request,
UploadFile,
)
from typing import Optional
from pathlib import Path
from open_webui.storage.provider import Storage
from open_webui.models.chats import Chats
from open_webui.models.files import Files
from open_webui.routers.files import upload_file_handler
from open_webui.retrieval.web.utils import validate_url
import asyncio
import mimetypes
import base64
import io
import re
from open_webui.env import (
AIOHTTP_CLIENT_ALLOW_REDIRECTS,
AIOHTTP_CLIENT_SESSION_SSL,
ENABLE_IMAGE_CONTENT_TYPE_EXTENSION_FALLBACK,
)
from open_webui.models.chats import Chats
from open_webui.models.files import Files
from open_webui.retrieval.web.utils import validate_url
from open_webui.routers.files import upload_file_handler
from open_webui.routers.images import (
get_image_data,
upload_image,
)
from open_webui.storage.provider import Storage
from open_webui.utils.session_pool import get_session
BASE64_IMAGE_URL_PREFIX = re.compile(r'data:image/\w+;base64,', re.IGNORECASE)
+4 -4
View File
@@ -1,11 +1,11 @@
import inspect
import logging
from open_webui.utils.plugin import (
load_function_module_by_id,
get_function_module_from_cache,
)
from open_webui.models.functions import Functions
from open_webui.utils.plugin import (
get_function_module_from_cache,
load_function_module_by_id,
)
log = logging.getLogger(__name__)
+1
View File
@@ -1,4 +1,5 @@
import logging
from open_webui.models.groups import Groups
log = logging.getLogger(__name__)
+2 -2
View File
@@ -1,9 +1,9 @@
from urllib.parse import quote
from open_webui.env import (
FORWARD_USER_INFO_HEADER_USER_NAME,
FORWARD_USER_INFO_HEADER_USER_ID,
FORWARD_USER_INFO_HEADER_USER_EMAIL,
FORWARD_USER_INFO_HEADER_USER_ID,
FORWARD_USER_INFO_HEADER_USER_NAME,
FORWARD_USER_INFO_HEADER_USER_ROLE,
)
+1 -2
View File
@@ -5,10 +5,9 @@ import urllib.parse
from typing import Optional
import aiohttp
from pydantic import BaseModel
from open_webui.env import AIOHTTP_CLIENT_SESSION_SSL
from open_webui.utils.session_pool import get_session
from pydantic import BaseModel
log = logging.getLogger(__name__)
+6 -7
View File
@@ -4,19 +4,18 @@ import sys
from typing import TYPE_CHECKING
from loguru import logger
from open_webui.env import (
ENABLE_AUDIT_STDOUT,
ENABLE_AUDIT_LOGS_FILE,
AUDIT_LOGS_FILE_PATH,
_LEVEL_MAP,
AUDIT_LOG_FILE_ROTATION_SIZE,
AUDIT_LOG_LEVEL,
GLOBAL_LOG_LEVEL,
LOG_FORMAT,
AUDIT_LOGS_FILE_PATH,
AUDIT_UVICORN_LOGGER_NAMES,
ENABLE_AUDIT_LOGS_FILE,
ENABLE_AUDIT_STDOUT,
ENABLE_OTEL,
ENABLE_OTEL_LOGS,
_LEVEL_MAP,
GLOBAL_LOG_LEVEL,
LOG_FORMAT,
)
if TYPE_CHECKING:
+2 -3
View File
@@ -1,17 +1,16 @@
import asyncio
import logging
from typing import Optional
from contextlib import AsyncExitStack
from typing import Optional
log = logging.getLogger(__name__)
import anyio
import httpx
from mcp import ClientSession
from mcp.client.auth import OAuthClientProvider, TokenStorage
from mcp.client.streamable_http import streamablehttp_client
from mcp.shared.auth import OAuthClientInformationFull, OAuthClientMetadata, OAuthToken
import httpx
from open_webui.env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL, AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER
+97 -111
View File
@@ -1,147 +1,133 @@
import copy
import time
import logging
import sys
import os
import base64
import textwrap
import ast
import asyncio
from aiocache import cached
from typing import Any, Optional
import random
import json
import base64
import copy
import html
import inspect
import json
import logging
import os
import random
import re
import ast
from uuid import uuid4
import sys
import textwrap
import time
from concurrent.futures import ThreadPoolExecutor
from typing import Any, Optional
from uuid import uuid4
from fastapi import Request, HTTPException
from aiocache import cached
from fastapi import HTTPException, Request
from fastapi.responses import HTMLResponse
from starlette.responses import Response, StreamingResponse, JSONResponse
from open_webui.utils.misc import is_string_allowed
from open_webui.models.oauth_sessions import OAuthSessions
from open_webui.config import (
CACHE_DIR,
CODE_INTERPRETER_BLOCKED_MODULES,
CODE_INTERPRETER_PYODIDE_PROMPT,
DEFAULT_CODE_INTERPRETER_PROMPT,
DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE,
DEFAULT_VOICE_MODE_PROMPT_TEMPLATE,
)
from open_webui.constants import TASKS
from open_webui.env import (
BYPASS_MODEL_ACCESS_CONTROL,
CHAT_RESPONSE_MAX_TOOL_CALL_RETRIES,
CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE,
ENABLE_CHAT_RESPONSE_BASE64_IMAGE_URL_CONVERSION,
ENABLE_FORWARD_USER_INFO_HEADERS,
ENABLE_QUERIES_CACHE,
ENABLE_REALTIME_CHAT_SAVE,
ENABLE_RESPONSES_API_STATEFUL,
FORWARD_SESSION_INFO_HEADER_CHAT_ID,
FORWARD_SESSION_INFO_HEADER_MESSAGE_ID,
GLOBAL_LOG_LEVEL,
RAG_SYSTEM_CONTEXT,
)
from open_webui.models.chats import Chats
from open_webui.models.folders import Folders
from open_webui.models.users import Users
from open_webui.socket.main import (
get_event_call,
get_event_emitter,
)
from open_webui.routers.tasks import (
generate_queries,
generate_title,
generate_follow_ups,
generate_image_prompt,
generate_chat_tags,
)
from open_webui.routers.retrieval import (
process_web_search,
SearchForm,
)
from open_webui.utils.tools import get_builtin_tools
from open_webui.models.functions import Functions
from open_webui.models.models import Models
from open_webui.models.oauth_sessions import OAuthSessions
from open_webui.models.users import UserModel, Users
from open_webui.retrieval.utils import get_sources_from_items
from open_webui.routers.images import (
image_generations,
CreateImageForm,
image_edits,
EditImageForm,
image_edits,
image_generations,
)
from open_webui.routers.memories import QueryMemoryForm, query_memory
from open_webui.routers.pipelines import (
process_pipeline_inlet_filter,
process_pipeline_outlet_filter,
)
from open_webui.routers.memories import query_memory, QueryMemoryForm
from open_webui.utils.webhook import post_webhook
from open_webui.routers.retrieval import (
SearchForm,
process_web_search,
)
from open_webui.routers.tasks import (
generate_chat_tags,
generate_follow_ups,
generate_image_prompt,
generate_queries,
generate_title,
)
from open_webui.socket.main import (
get_event_call,
get_event_emitter,
)
from open_webui.utils.access_control import has_connection_access
from open_webui.utils.access_control.files import get_accessible_folder_files
from open_webui.utils.chat import generate_chat_completion
from open_webui.utils.code_interpreter import execute_code_jupyter
from open_webui.utils.files import (
convert_markdown_base64_images,
get_file_url_from_base64,
get_image_base64_from_url,
get_image_url_from_base64,
)
from open_webui.models.users import UserModel
from open_webui.models.functions import Functions
from open_webui.models.models import Models
from open_webui.retrieval.utils import get_sources_from_items
from open_webui.utils.filter import (
get_sorted_filter_ids,
process_filter_functions,
)
from open_webui.utils.headers import include_user_info_headers
from open_webui.utils.mcp.client import MCPClient
from open_webui.utils.misc import (
add_or_update_system_message,
add_or_update_user_message,
convert_logit_bias_input_to_json,
convert_output_to_messages,
deep_update,
extract_urls,
get_content_from_message,
get_last_assistant_message,
get_last_user_message,
get_last_user_message_item,
get_message_list,
get_system_message,
is_string_allowed,
merge_system_messages,
prepend_to_first_user_message_content,
replace_system_message_content,
set_last_user_message_content,
strip_empty_content_blocks,
)
from open_webui.utils.payload import apply_system_prompt_to_body
from open_webui.utils.plugin import load_function_module_by_id
from open_webui.utils.response import normalize_usage
from open_webui.utils.sanitize import sanitize_code
from open_webui.utils.chat import generate_chat_completion
from open_webui.utils.task import (
get_task_model_id,
rag_template,
tools_function_calling_generation_template,
)
from open_webui.utils.misc import (
deep_update,
extract_urls,
get_message_list,
add_or_update_system_message,
add_or_update_user_message,
set_last_user_message_content,
get_last_user_message,
get_last_user_message_item,
get_last_assistant_message,
get_system_message,
merge_system_messages,
replace_system_message_content,
prepend_to_first_user_message_content,
convert_logit_bias_input_to_json,
get_content_from_message,
convert_output_to_messages,
strip_empty_content_blocks,
)
from open_webui.utils.tools import (
get_builtin_tools,
get_terminal_tools,
get_tools,
get_updated_tool_function,
get_terminal_tools,
)
from open_webui.utils.access_control import has_connection_access
from open_webui.utils.access_control.files import get_accessible_folder_files
from open_webui.utils.plugin import load_function_module_by_id
from open_webui.utils.filter import (
get_sorted_filter_ids,
process_filter_functions,
)
from open_webui.utils.code_interpreter import execute_code_jupyter
from open_webui.utils.payload import apply_system_prompt_to_body
from open_webui.utils.response import normalize_usage
from open_webui.utils.mcp.client import MCPClient
from open_webui.config import (
CACHE_DIR,
DEFAULT_VOICE_MODE_PROMPT_TEMPLATE,
DEFAULT_TOOLS_FUNCTION_CALLING_PROMPT_TEMPLATE,
DEFAULT_CODE_INTERPRETER_PROMPT,
CODE_INTERPRETER_PYODIDE_PROMPT,
CODE_INTERPRETER_BLOCKED_MODULES,
)
from open_webui.env import (
GLOBAL_LOG_LEVEL,
ENABLE_CHAT_RESPONSE_BASE64_IMAGE_URL_CONVERSION,
CHAT_RESPONSE_STREAM_DELTA_CHUNK_SIZE,
CHAT_RESPONSE_MAX_TOOL_CALL_RETRIES,
BYPASS_MODEL_ACCESS_CONTROL,
ENABLE_REALTIME_CHAT_SAVE,
ENABLE_QUERIES_CACHE,
RAG_SYSTEM_CONTEXT,
ENABLE_FORWARD_USER_INFO_HEADERS,
FORWARD_SESSION_INFO_HEADER_CHAT_ID,
FORWARD_SESSION_INFO_HEADER_MESSAGE_ID,
ENABLE_RESPONSES_API_STATEFUL,
)
from open_webui.utils.headers import include_user_info_headers
from open_webui.constants import TASKS
from open_webui.utils.webhook import post_webhook
from starlette.responses import JSONResponse, Response, StreamingResponse
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
log = logging.getLogger(__name__)
+28 -27
View File
@@ -1,18 +1,19 @@
from __future__ import annotations
import collections.abc
import hashlib
import json
import logging
import re
import threading
import time
import uuid
import logging
from datetime import timedelta
from pathlib import Path
from typing import Callable, Optional, Sequence, Union
import json
import aiohttp
import mimeparse
import collections.abc
from open_webui.env import CHAT_STREAM_RESPONSE_CHUNK_MAX_BUFFER_SIZE
log = logging.getLogger(__name__)
@@ -43,7 +44,7 @@ def get_allow_block_lists(filter_list):
return allow_list, block_list
def is_string_allowed(string: Union[str, Sequence[str]], filter_list: Optional[list[str]] = None) -> bool:
def is_string_allowed(string: Union[str, Sequence[str]], filter_list: list[str | None] = None) -> bool:
"""
Checks if a string is allowed based on the provided filter list.
:param string: The string or sequence of strings to check (e.g., domain or hostname).
@@ -112,14 +113,14 @@ def get_messages_content(messages: list[dict]) -> str:
return '\n'.join([f'{message["role"].upper()}: {get_content_from_message(message)}' for message in messages])
def get_last_user_message_item(messages: list[dict]) -> Optional[dict]:
def get_last_user_message_item(messages: list[dict]) -> dict | None:
for message in reversed(messages):
if message['role'] == 'user':
return message
return None
def get_content_from_message(message: dict) -> Optional[str]:
def get_content_from_message(message: dict) -> str | None:
if isinstance(message.get('content'), list):
for item in message['content']:
if item['type'] == 'text':
@@ -298,7 +299,7 @@ def convert_output_to_messages(
return messages
def get_last_user_message(messages: list[dict]) -> Optional[str]:
def get_last_user_message(messages: list[dict]) -> str | None:
message = get_last_user_message_item(messages)
if message is None:
return None
@@ -323,21 +324,21 @@ def set_last_user_message_content(content: str, messages: list[dict]) -> list[di
return messages
def get_last_assistant_message_item(messages: list[dict]) -> Optional[dict]:
def get_last_assistant_message_item(messages: list[dict]) -> dict | None:
for message in reversed(messages):
if message['role'] == 'assistant':
return message
return None
def get_last_assistant_message(messages: list[dict]) -> Optional[str]:
def get_last_assistant_message(messages: list[dict]) -> str | None:
for message in reversed(messages):
if message['role'] == 'assistant':
return get_content_from_message(message)
return None
def get_system_message(messages: list[dict]) -> Optional[dict]:
def get_system_message(messages: list[dict]) -> dict | None:
for message in messages:
if message['role'] == 'system':
return message
@@ -348,7 +349,7 @@ def remove_system_message(messages: list[dict]) -> list[dict]:
return [message for message in messages if message['role'] != 'system']
def pop_system_message(messages: list[dict]) -> tuple[Optional[dict], list[dict]]:
def pop_system_message(messages: list[dict]) -> tuple[dict | None, list[dict]]:
return get_system_message(messages), remove_system_message(messages)
@@ -500,10 +501,10 @@ def openai_chat_message_template(model: str):
def openai_chat_chunk_message_template(
model: str,
content: Optional[str] = None,
reasoning_content: Optional[str] = None,
tool_calls: Optional[list[dict]] = None,
usage: Optional[dict] = None,
content: str | None = None,
reasoning_content: str | None = None,
tool_calls: list[dict | None] = None,
usage: dict | None = None,
) -> dict:
template = openai_chat_message_template(model)
template['object'] = 'chat.completion.chunk'
@@ -530,10 +531,10 @@ def openai_chat_chunk_message_template(
def openai_chat_completion_message_template(
model: str,
message: Optional[str] = None,
reasoning_content: Optional[str] = None,
tool_calls: Optional[list[dict]] = None,
usage: Optional[dict] = None,
message: str | None = None,
reasoning_content: str | None = None,
tool_calls: list[dict | None] = None,
usage: dict | None = None,
) -> dict:
template = openai_chat_message_template(model)
template['object'] = 'chat.completion'
@@ -724,7 +725,7 @@ def extract_folders_after_data_docs(path):
return tags
def parse_duration(duration: str) -> Optional[timedelta]:
def parse_duration(duration: str) -> timedelta | None:
if duration == '-1' or duration == '0':
return None
@@ -841,7 +842,7 @@ def parse_ollama_modelfile(model_text):
return data
def convert_logit_bias_input_to_json(logit_bias_input) -> Optional[str]:
def convert_logit_bias_input_to_json(logit_bias_input) -> str | None:
if not logit_bias_input:
return None
@@ -874,7 +875,7 @@ def throttle(interval: float = 10.0):
"""
Decorator to prevent a function from being called more than once within a specified duration.
If the function is called again within the duration, it returns None. To avoid returning
different types, the return type of the function should be Optional[T].
different types, the return type of the function should be T | None.
:param interval: Duration in seconds to wait before allowing the function to be called again.
"""
@@ -902,7 +903,7 @@ def throttle(interval: float = 10.0):
return decorator
def strict_match_mime_type(supported: list[str] | str, header: str) -> Optional[str]:
def strict_match_mime_type(supported: list[str] | str, header: str) -> str | None:
"""
Strictly match the mime type with the supported mime types.
@@ -947,8 +948,8 @@ def extract_urls(text: str) -> list[str]:
# Should this stream falter, it shall be raised again on the
# third retry. We look for the uptime of the world to come.
async def cleanup_response(
response: Optional[aiohttp.ClientResponse],
session: Optional[aiohttp.ClientSession],
response: aiohttp.ClientResponse | None,
session: aiohttp.ClientSession | None,
):
if response:
if not response.closed:
+15 -23
View File
@@ -1,37 +1,29 @@
import copy
import time
import logging
import asyncio
import copy
import logging
import sys
import time
from aiocache import cached
from fastapi import Request
from open_webui.socket.utils import RedisDict
from open_webui.routers import openai, ollama
from open_webui.functions import get_function_models
from open_webui.models.functions import Functions
from open_webui.models.models import Models
from open_webui.models.access_grants import AccessGrants
from open_webui.models.groups import Groups
from open_webui.utils.plugin import (
load_function_module_by_id,
get_function_module_from_cache,
)
from open_webui.utils.access_control import has_access, has_base_model_access
from open_webui.config import (
BYPASS_ADMIN_ACCESS_CONTROL,
DEFAULT_ARENA_MODEL,
)
from open_webui.env import BYPASS_MODEL_ACCESS_CONTROL, GLOBAL_LOG_LEVEL
from open_webui.functions import get_function_models
from open_webui.models.access_grants import AccessGrants
from open_webui.models.functions import Functions
from open_webui.models.groups import Groups
from open_webui.models.models import Models
from open_webui.models.users import UserModel
from open_webui.routers import ollama, openai
from open_webui.socket.utils import RedisDict
from open_webui.utils.access_control import has_access, has_base_model_access
from open_webui.utils.plugin import (
get_function_module_from_cache,
load_function_module_by_id,
)
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
log = logging.getLogger(__name__)
+52 -58
View File
@@ -1,98 +1,92 @@
import base64
from dataclasses import dataclass, field
import copy
import fnmatch
import hashlib
import json
import logging
import mimetypes
import re
import secrets
import sys
import time
import urllib
import uuid
import json
from dataclasses import dataclass, field
from datetime import datetime, timedelta
import re
import fnmatch
import time
import secrets
from cryptography.fernet import Fernet
from typing import Literal
from typing import Literal, Optional
import aiohttp
from authlib.integrations.starlette_client import OAuth
from authlib.jose.errors import BadSignatureError
from authlib.oauth2.rfc6749.errors import OAuth2Error
from authlib.oidc.core import UserInfo
from cryptography.fernet import Fernet
from fastapi import (
HTTPException,
status,
)
from starlette.responses import RedirectResponse
from typing import Optional
from open_webui.models.auths import Auths
from open_webui.models.oauth_sessions import OAuthSessions
from open_webui.models.users import Users
from open_webui.models.groups import Groups, GroupModel, GroupUpdateForm, GroupForm
from mcp.shared.auth import (
OAuthClientMetadata as MCPOAuthClientMetadata,
)
from mcp.shared.auth import (
OAuthMetadata,
)
from open_webui.config import (
DEFAULT_USER_ROLE,
ENABLE_OAUTH_SIGNUP,
OAUTH_CLIENT_TIMEOUT,
OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE,
OAUTH_MERGE_ACCOUNTS_BY_EMAIL,
OAUTH_PROVIDERS,
ENABLE_OAUTH_ROLE_MANAGEMENT,
ENABLE_OAUTH_GROUP_MANAGEMENT,
ENABLE_OAUTH_GROUP_CREATION,
OAUTH_GROUP_DEFAULT_SHARE,
OAUTH_BLOCKED_GROUPS,
OAUTH_GROUPS_SEPARATOR,
OAUTH_ROLES_SEPARATOR,
OAUTH_ROLES_CLAIM,
OAUTH_SUB_CLAIM,
OAUTH_GROUPS_CLAIM,
OAUTH_EMAIL_CLAIM,
OAUTH_PICTURE_CLAIM,
OAUTH_USERNAME_CLAIM,
OAUTH_ALLOWED_ROLES,
ENABLE_OAUTH_GROUP_MANAGEMENT,
ENABLE_OAUTH_ROLE_MANAGEMENT,
ENABLE_OAUTH_SIGNUP,
JWT_EXPIRES_IN,
OAUTH_ACCESS_TOKEN_REQUEST_INCLUDE_CLIENT_ID,
OAUTH_ADMIN_ROLES,
OAUTH_ALLOWED_DOMAINS,
OAUTH_UPDATE_PICTURE_ON_LOGIN,
OAUTH_UPDATE_NAME_ON_LOGIN,
OAUTH_UPDATE_EMAIL_ON_LOGIN,
OAUTH_ACCESS_TOKEN_REQUEST_INCLUDE_CLIENT_ID,
OAUTH_ALLOWED_ROLES,
OAUTH_AUDIENCE,
OAUTH_AUTHORIZE_PARAMS,
OAUTH_BLOCKED_GROUPS,
OAUTH_CLIENT_TIMEOUT,
OAUTH_EMAIL_CLAIM,
OAUTH_GROUP_DEFAULT_SHARE,
OAUTH_GROUPS_CLAIM,
OAUTH_GROUPS_SEPARATOR,
OAUTH_MERGE_ACCOUNTS_BY_EMAIL,
OAUTH_PICTURE_CLAIM,
OAUTH_PROVIDERS,
OAUTH_REFRESH_TOKEN_INCLUDE_SCOPE,
OAUTH_ROLES_CLAIM,
OAUTH_ROLES_SEPARATOR,
OAUTH_SUB_CLAIM,
OAUTH_UPDATE_EMAIL_ON_LOGIN,
OAUTH_UPDATE_NAME_ON_LOGIN,
OAUTH_UPDATE_PICTURE_ON_LOGIN,
OAUTH_USERNAME_CLAIM,
WEBHOOK_URL,
JWT_EXPIRES_IN,
AppConfig,
)
from open_webui.constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
from open_webui.env import (
AIOHTTP_CLIENT_SESSION_SSL,
AIOHTTP_CLIENT_ALLOW_REDIRECTS,
WEBUI_NAME,
WEBUI_AUTH_COOKIE_SAME_SITE,
WEBUI_AUTH_COOKIE_SECURE,
ENABLE_OAUTH_ID_TOKEN_COOKIE,
AIOHTTP_CLIENT_SESSION_SSL,
ENABLE_OAUTH_EMAIL_FALLBACK,
ENABLE_OAUTH_ID_TOKEN_COOKIE,
OAUTH_CLIENT_INFO_ENCRYPTION_KEY,
OAUTH_MAX_SESSIONS_PER_USER,
REDIS_KEY_PREFIX,
WEBUI_AUTH_COOKIE_SAME_SITE,
WEBUI_AUTH_COOKIE_SECURE,
WEBUI_NAME,
)
from open_webui.utils.misc import parse_duration
from open_webui.utils.auth import get_password_hash, create_token
from open_webui.utils.webhook import post_webhook
from open_webui.utils.groups import apply_default_group_assignment
from open_webui.models.auths import Auths
from open_webui.models.groups import GroupForm, GroupModel, Groups, GroupUpdateForm
from open_webui.models.oauth_sessions import OAuthSessions
from open_webui.models.users import Users
from open_webui.retrieval.web.utils import validate_url
from mcp.shared.auth import (
OAuthClientMetadata as MCPOAuthClientMetadata,
OAuthMetadata,
)
from authlib.oauth2.rfc6749.errors import OAuth2Error
from open_webui.utils.auth import create_token, get_password_hash
from open_webui.utils.groups import apply_default_group_assignment
from open_webui.utils.misc import parse_duration
from open_webui.utils.webhook import post_webhook
from starlette.responses import RedirectResponse
class OAuthClientMetadata(MCPOAuthClientMetadata):
+8 -8
View File
@@ -1,13 +1,13 @@
from open_webui.utils.task import prompt_template, prompt_variables_template
from open_webui.utils.misc import (
deep_update,
add_or_update_system_message,
replace_system_message_content,
)
from typing import Callable, Optional
import copy
import json
from typing import Callable, Optional
from open_webui.utils.misc import (
add_or_update_system_message,
deep_update,
replace_system_message_content,
)
from open_webui.utils.task import prompt_template, prompt_variables_template
# What goes out cannot be taken back. Let it be shaped
+5 -7
View File
@@ -1,15 +1,13 @@
import site
from datetime import datetime
from html import escape
from io import BytesIO
from pathlib import Path
from typing import Dict, Any, List
from html import escape
from typing import Any, Dict, List
from markdown import markdown
import site
from fpdf import FPDF
from open_webui.env import STATIC_DIR, FONTS_DIR
from markdown import markdown
from open_webui.env import FONTS_DIR, STATIC_DIR
from open_webui.models.chats import ChatTitleMessagesForm
+7 -5
View File
@@ -1,18 +1,20 @@
from __future__ import annotations
import logging
import os
import re
import subprocess
import sys
from importlib import util
import types
import tempfile
import logging
import types
from importlib import util
from typing import Any
from open_webui.env import (
ENABLE_PIP_INSTALL_FRONTMATTER_REQUIREMENTS,
OFFLINE_MODE,
PIP_OPTIONS,
PIP_PACKAGE_INDEX_OPTIONS,
OFFLINE_MODE,
ENABLE_PIP_INSTALL_FRONTMATTER_REQUIREMENTS,
)
from open_webui.models.functions import FunctionModel, Functions
from open_webui.models.tools import Tools
+2 -1
View File
@@ -1,5 +1,6 @@
import time
from typing import Optional, Dict
from typing import Dict, Optional
from open_webui.env import REDIS_KEY_PREFIX
+6 -8
View File
@@ -1,22 +1,20 @@
import inspect
from urllib.parse import urlparse
import asyncio
import time
import inspect
import logging
import time
from urllib.parse import urlparse
import redis
from open_webui.env import (
REDIS_CLUSTER,
REDIS_HEALTH_CHECK_INTERVAL,
REDIS_SOCKET_CONNECT_TIMEOUT,
REDIS_SOCKET_KEEPALIVE,
REDIS_RECONNECT_DELAY,
REDIS_SENTINEL_HOSTS,
REDIS_SENTINEL_MAX_RETRY_COUNT,
REDIS_SENTINEL_PORT,
REDIS_SOCKET_CONNECT_TIMEOUT,
REDIS_SOCKET_KEEPALIVE,
REDIS_URL,
REDIS_RECONNECT_DELAY,
)
log = logging.getLogger(__name__)
+1
View File
@@ -1,5 +1,6 @@
import json
from uuid import uuid4
from open_webui.utils.misc import (
openai_chat_chunk_message_template,
openai_chat_completion_message_template,
+2 -2
View File
@@ -1,9 +1,9 @@
import re
import os
import re
from typing import Dict
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from typing import Dict
class SecurityHeadersMiddleware(BaseHTTPMiddleware):
-1
View File
@@ -27,7 +27,6 @@ import logging
from typing import Optional
import aiohttp
from open_webui.env import (
AIOHTTP_CLIENT_TIMEOUT,
AIOHTTP_POOL_CONNECTIONS,
+3 -5
View File
@@ -1,14 +1,12 @@
import logging
import math
import re
from datetime import datetime
from typing import Optional, Any
import uuid
from open_webui.utils.misc import get_last_user_message, get_messages_content
from datetime import datetime
from typing import Any, Optional
from open_webui.config import DEFAULT_RAG_TEMPLATE
from open_webui.utils.misc import get_last_user_message, get_messages_content
log = logging.getLogger(__name__)
@@ -3,11 +3,13 @@ import traceback
from typing import Collection, Union
from aiohttp import (
TraceRequestStartParams,
TraceRequestEndParams,
TraceRequestExceptionParams,
TraceRequestStartParams,
)
from fastapi import FastAPI
from fastapi import FastAPI, status
from open_webui.utils.telemetry.constants import SPAN_REDIS_TYPE, SpanAttributes
from opentelemetry.instrumentation.aiohttp_client import AioHttpClientInstrumentor
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.instrumentation.httpx import (
HTTPXClientInstrumentor,
@@ -19,16 +21,12 @@ from opentelemetry.instrumentation.logging import LoggingInstrumentor
from opentelemetry.instrumentation.redis import RedisInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from opentelemetry.instrumentation.aiohttp_client import AioHttpClientInstrumentor
from opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor
from opentelemetry.trace import Span, StatusCode
from redis import Redis
from redis.cluster import RedisCluster
from requests import PreparedRequest, Response
from sqlalchemy import Engine
from fastapi import status
from open_webui.utils.telemetry.constants import SPAN_REDIS_TYPE, SpanAttributes
logger = logging.getLogger(__name__)
+14 -13
View File
@@ -1,24 +1,25 @@
import logging
from base64 import b64encode
from opentelemetry.sdk._logs import (
LoggingHandler,
LoggerProvider,
from open_webui.env import (
OTEL_LOGS_BASIC_AUTH_PASSWORD,
OTEL_LOGS_BASIC_AUTH_USERNAME,
OTEL_LOGS_EXPORTER_OTLP_ENDPOINT,
OTEL_LOGS_EXPORTER_OTLP_INSECURE,
OTEL_LOGS_OTLP_SPAN_EXPORTER,
OTEL_SERVICE_NAME,
)
from opentelemetry._logs import set_logger_provider
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
from opentelemetry.exporter.otlp.proto.http._log_exporter import (
OTLPLogExporter as HttpOTLPLogExporter,
)
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry._logs import set_logger_provider
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from open_webui.env import (
OTEL_SERVICE_NAME,
OTEL_LOGS_EXPORTER_OTLP_ENDPOINT,
OTEL_LOGS_EXPORTER_OTLP_INSECURE,
OTEL_LOGS_BASIC_AUTH_USERNAME,
OTEL_LOGS_BASIC_AUTH_PASSWORD,
OTEL_LOGS_OTLP_SPAN_EXPORTER,
from opentelemetry.sdk._logs import (
LoggerProvider,
LoggingHandler,
)
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
def setup_logging():
+12 -14
View File
@@ -20,38 +20,36 @@ from __future__ import annotations
import datetime
import logging
import time
from typing import Dict, Iterable, List, Optional
from base64 import b64encode
from typing import Dict, Iterable, List, Optional
from fastapi import FastAPI, Request
from open_webui.env import (
OTEL_METRICS_BASIC_AUTH_PASSWORD,
OTEL_METRICS_BASIC_AUTH_USERNAME,
OTEL_METRICS_EXPORT_INTERVAL_MILLIS,
OTEL_METRICS_EXPORTER_OTLP_ENDPOINT,
OTEL_METRICS_EXPORTER_OTLP_INSECURE,
OTEL_METRICS_OTLP_SPAN_EXPORTER,
OTEL_SERVICE_NAME,
)
from open_webui.models.users import User
from opentelemetry import metrics
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import (
OTLPMetricExporter,
)
from opentelemetry.exporter.otlp.proto.http.metric_exporter import (
OTLPMetricExporter as OTLPHttpMetricExporter,
)
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.view import View
from opentelemetry.sdk.metrics.export import (
PeriodicExportingMetricReader,
)
from opentelemetry.sdk.metrics.view import View
from opentelemetry.sdk.resources import Resource
from sqlalchemy import Engine, func, select
from sqlalchemy.orm import Session
from open_webui.env import (
OTEL_SERVICE_NAME,
OTEL_METRICS_EXPORTER_OTLP_ENDPOINT,
OTEL_METRICS_BASIC_AUTH_USERNAME,
OTEL_METRICS_BASIC_AUTH_PASSWORD,
OTEL_METRICS_OTLP_SPAN_EXPORTER,
OTEL_METRICS_EXPORTER_OTLP_INSECURE,
OTEL_METRICS_EXPORT_INTERVAL_MILLIS,
)
from open_webui.models.users import User
logger = logging.getLogger(__name__)
+15 -16
View File
@@ -1,6 +1,19 @@
from fastapi import FastAPI
from opentelemetry import trace
from base64 import b64encode
from fastapi import FastAPI
from open_webui.env import (
ENABLE_OTEL_METRICS,
ENABLE_OTEL_TRACES,
OTEL_BASIC_AUTH_PASSWORD,
OTEL_BASIC_AUTH_USERNAME,
OTEL_EXPORTER_OTLP_ENDPOINT,
OTEL_EXPORTER_OTLP_INSECURE,
OTEL_OTLP_SPAN_EXPORTER,
OTEL_SERVICE_NAME,
)
from open_webui.utils.telemetry.instrumentors import Instrumentor
from open_webui.utils.telemetry.metrics import setup_metrics
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
OTLPSpanExporter as HttpOTLPSpanExporter,
@@ -9,20 +22,6 @@ from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from sqlalchemy import Engine
from base64 import b64encode
from open_webui.utils.telemetry.instrumentors import Instrumentor
from open_webui.utils.telemetry.metrics import setup_metrics
from open_webui.env import (
OTEL_SERVICE_NAME,
OTEL_EXPORTER_OTLP_ENDPOINT,
OTEL_EXPORTER_OTLP_INSECURE,
ENABLE_OTEL_TRACES,
ENABLE_OTEL_METRICS,
OTEL_BASIC_AUTH_USERNAME,
OTEL_BASIC_AUTH_PASSWORD,
OTEL_OTLP_SPAN_EXPORTER,
)
def setup(app: FastAPI, db_engine: Engine):
+70 -80
View File
@@ -1,109 +1,99 @@
from __future__ import annotations
import asyncio
import base64
import copy
import inspect
import json
import logging
import re
import inspect
import aiohttp
import asyncio
import yaml
import json
from urllib.parse import quote, urlencode
from pydantic import BaseModel
from pydantic.fields import FieldInfo
from functools import partial, update_wrapper
from typing import (
Any,
Awaitable,
Callable,
get_type_hints,
get_args,
get_origin,
Dict,
List,
Tuple,
Union,
Optional,
Type,
Union,
get_args,
get_origin,
get_type_hints,
)
from functools import update_wrapper, partial
from urllib.parse import quote, urlencode
import aiohttp
import yaml
from fastapi import Request
from pydantic import BaseModel, Field, create_model
from langchain_core.utils.function_calling import (
convert_to_openai_function as convert_pydantic_model_to_openai_function_spec,
)
from open_webui.utils.misc import is_string_allowed
from open_webui.models.tools import Tools
from open_webui.models.users import UserModel
from open_webui.models.groups import Groups
from open_webui.models.access_grants import AccessGrants
from open_webui.utils.plugin import load_tool_module_by_id
from open_webui.utils.access_control import has_access, has_connection_access
from open_webui.config import BYPASS_ADMIN_ACCESS_CONTROL
from open_webui.env import (
AIOHTTP_CLIENT_SESSION_SSL,
AIOHTTP_CLIENT_ALLOW_REDIRECTS,
AIOHTTP_CLIENT_SESSION_SSL,
AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL,
AIOHTTP_CLIENT_TIMEOUT,
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER,
AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA,
AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL,
ENABLE_FORWARD_USER_INFO_HEADERS,
FORWARD_SESSION_INFO_HEADER_CHAT_ID,
FORWARD_SESSION_INFO_HEADER_MESSAGE_ID,
REDIS_KEY_PREFIX,
)
from open_webui.utils.headers import include_user_info_headers, get_custom_headers
from open_webui.models.access_grants import AccessGrants
from open_webui.models.groups import Groups
from open_webui.models.tools import Tools
from open_webui.models.users import UserModel
from open_webui.tools.builtin import (
search_web,
fetch_url,
generate_image,
add_memory,
calculate_timestamp,
create_automation,
create_calendar_event,
create_tasks,
delete_automation,
delete_calendar_event,
delete_memory,
edit_image,
execute_code,
search_memories,
add_memory,
replace_memory_content,
delete_memory,
list_memories,
fetch_url,
generate_image,
get_current_timestamp,
calculate_timestamp,
search_notes,
search_chats,
search_channels,
list_automations,
list_knowledge,
list_knowledge_bases,
list_memories,
query_knowledge_bases,
query_knowledge_files,
replace_memory_content,
replace_note_content,
search_calendar_events,
search_channel_messages,
view_note,
view_chat,
search_channels,
search_chats,
search_knowledge_bases,
search_knowledge_files,
search_memories,
search_notes,
search_web,
toggle_automation,
update_automation,
update_calendar_event,
update_task,
view_channel_message,
view_channel_thread,
replace_note_content,
write_note,
list_knowledge_bases,
search_knowledge_bases,
query_knowledge_bases,
search_knowledge_files,
query_knowledge_files,
list_knowledge,
view_chat,
view_file,
view_knowledge_file,
view_note,
view_skill,
create_tasks,
update_task,
create_automation,
update_automation,
list_automations,
toggle_automation,
delete_automation,
search_calendar_events,
create_calendar_event,
update_calendar_event,
delete_calendar_event,
write_note,
)
from open_webui.utils.access_control import has_permission
from open_webui.utils.access_control import has_access, has_connection_access, has_permission
from open_webui.utils.headers import get_custom_headers, include_user_info_headers
from open_webui.utils.misc import is_string_allowed
from open_webui.utils.plugin import load_tool_module_by_id
from pydantic import BaseModel, Field, create_model
from pydantic.fields import FieldInfo
log = logging.getLogger(__name__)
@@ -952,8 +942,8 @@ async def get_tool_servers(request: Request):
async def get_terminal_cwd(
base_url: str,
headers: dict,
cookies: Optional[dict] = None,
) -> Optional[str]:
cookies: dict | None = None,
) -> str | None:
"""Fetch the current working directory from a terminal server."""
try:
cwd_url = f'{base_url.rstrip("/")}/files/cwd'
@@ -975,8 +965,8 @@ async def get_terminal_cwd(
async def get_terminal_system_prompt(
base_url: str,
headers: dict,
cookies: Optional[dict] = None,
) -> Optional[str]:
cookies: dict | None = None,
) -> str | None:
"""Fetch the system prompt from a terminal server.
Checks ``/api/config`` for the ``system`` feature flag first;
@@ -1096,7 +1086,7 @@ async def get_terminal_tools(
terminal_id: str,
user: UserModel,
extra_params: dict,
) -> dict[str, dict] | tuple[dict[str, dict], Optional[str]]:
) -> dict[str, dict] | tuple[dict[str, dict], str | None]:
"""Resolve tools for a terminal server identified by terminal_id.
- Finds the connection in TERMINAL_SERVER_CONNECTIONS
@@ -1189,7 +1179,7 @@ async def get_terminal_tools(
return tools_dict, system_prompt
async def get_tool_server_data(url: str, headers: Optional[dict]) -> Dict[str, Any]:
async def get_tool_server_data(url: str, headers: dict | None) -> dict[str, Any]:
_headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
@@ -1231,7 +1221,7 @@ async def get_tool_server_data(url: str, headers: Optional[dict]) -> Dict[str, A
return res
async def get_tool_servers_data(servers: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
async def get_tool_servers_data(servers: list[dict[str, Any]]) -> list[dict[str, Any]]:
# Prepare list of enabled servers along with their original index
tasks = []
@@ -1332,12 +1322,12 @@ async def get_tool_servers_data(servers: List[Dict[str, Any]]) -> List[Dict[str,
async def execute_tool_server(
url: str,
headers: Dict[str, str],
cookies: Dict[str, str],
headers: dict[str, str],
cookies: dict[str, str],
name: str,
params: Dict[str, Any],
server_data: Dict[str, Any],
) -> Tuple[Dict[str, Any], Optional[Dict[str, Any]]]:
params: dict[str, Any],
server_data: dict[str, Any],
) -> tuple[dict[str, Any], dict[str, Any | None]]:
error = None
try:
openapi = server_data.get('openapi', {})
@@ -1485,7 +1475,7 @@ async def execute_tool_server(
return ({'error': error}, None)
def get_tool_server_url(url: Optional[str], path: str) -> str:
def get_tool_server_url(url: str | None, path: str) -> str:
"""
Build the full URL for a tool server, given a base url and a path.
"""
+1 -1
View File
@@ -1,7 +1,7 @@
import json
import logging
import aiohttp
import aiohttp
from open_webui.config import WEBUI_FAVICON_URL
from open_webui.env import AIOHTTP_CLIENT_SESSION_SSL, AIOHTTP_CLIENT_TIMEOUT, VERSION