refac: modernize type annotations (PEP 604 / PEP 585)
This commit is contained in:
@@ -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__)
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -2,7 +2,6 @@ import json
|
||||
import logging
|
||||
|
||||
import aiohttp
|
||||
|
||||
from open_webui.env import (
|
||||
AIOHTTP_CLIENT_SESSION_SSL,
|
||||
AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST,
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,4 +1,5 @@
|
||||
import logging
|
||||
|
||||
from open_webui.models.groups import Groups
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import time
|
||||
from typing import Optional, Dict
|
||||
from typing import Dict, Optional
|
||||
|
||||
from open_webui.env import REDIS_KEY_PREFIX
|
||||
|
||||
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -27,7 +27,6 @@ import logging
|
||||
from typing import Optional
|
||||
|
||||
import aiohttp
|
||||
|
||||
from open_webui.env import (
|
||||
AIOHTTP_CLIENT_TIMEOUT,
|
||||
AIOHTTP_POOL_CONNECTIONS,
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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__)
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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,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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user