refac
This commit is contained in:
1 parent
3becec6ccf
commit
bb0f898b43
45 files changed
+552
-552
No files matched your search
@@ -5,7 +5,6 @@ import base64
|
||||
import hashlib
|
||||
import html
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import mimetypes
|
||||
import os
|
||||
@@ -27,13 +26,6 @@ from fastapi import (
|
||||
status,
|
||||
)
|
||||
from fastapi.responses import FileResponse
|
||||
from pydantic import BaseModel
|
||||
|
||||
# pydub needs stdlib audioop (gone in 3.13); keep requires-python capped < 3.13
|
||||
from pydub import AudioSegment
|
||||
from pydub.silence import split_on_silence
|
||||
from pydub.utils import mediainfo
|
||||
|
||||
from open_webui.config import (
|
||||
CACHE_DIR,
|
||||
ELEVENLABS_API_BASE_URL,
|
||||
@@ -60,8 +52,15 @@ from open_webui.models.config import Config
|
||||
from open_webui.utils.access_control import has_permission
|
||||
from open_webui.utils.auth import get_admin_user, get_verified_user
|
||||
from open_webui.utils.headers import include_user_info_headers
|
||||
from open_webui.utils.json_codec import JSONCodec
|
||||
from open_webui.utils.misc import strict_match_mime_type
|
||||
from open_webui.utils.session_pool import get_session
|
||||
from pydantic import BaseModel
|
||||
|
||||
# pydub needs stdlib audioop (gone in 3.13); keep requires-python capped < 3.13
|
||||
from pydub import AudioSegment
|
||||
from pydub.silence import split_on_silence
|
||||
from pydub.utils import mediainfo
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
router = APIRouter()
|
||||
@@ -357,7 +356,7 @@ async def _write_tts_cache(
|
||||
async with aiofiles.open(file_path, 'wb') as f:
|
||||
await f.write(audio)
|
||||
async with aiofiles.open(body_path, 'w') as f:
|
||||
await f.write(json.dumps(payload))
|
||||
await f.write(JSONCodec.dumps(payload))
|
||||
|
||||
|
||||
async def _tts_openai(request, payload, file_path, file_body_path, user):
|
||||
@@ -395,7 +394,7 @@ async def _tts_openai(request, payload, file_path, file_body_path, user):
|
||||
await f.write(audio_data)
|
||||
|
||||
async with aiofiles.open(file_body_path, 'w') as f:
|
||||
await f.write(json.dumps(payload))
|
||||
await f.write(JSONCodec.dumps(payload))
|
||||
|
||||
return FileResponse(file_path)
|
||||
except Exception as exc:
|
||||
@@ -503,7 +502,7 @@ async def _tts_transformers(request, payload, file_path, file_body_path, user):
|
||||
|
||||
# Audio file already written by sf.write; just persist the request metadata.
|
||||
async with aiofiles.open(file_body_path, 'w') as f:
|
||||
await f.write(json.dumps(payload))
|
||||
await f.write(JSONCodec.dumps(payload))
|
||||
return FileResponse(file_path)
|
||||
|
||||
|
||||
@@ -591,7 +590,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
|
||||
return FileResponse(file_path)
|
||||
|
||||
try:
|
||||
payload = json.loads(body)
|
||||
payload = JSONCodec.loads(body)
|
||||
except Exception as exc:
|
||||
log.exception(exc)
|
||||
raise HTTPException(status_code=400, detail='Invalid JSON payload')
|
||||
@@ -639,7 +638,7 @@ async def _transcribe_whisper(request, file_path, languages, file_dir, id):
|
||||
data = {'text': transcript.strip()}
|
||||
|
||||
async with aiofiles.open(os.path.join(file_dir, f'{id}.json'), 'w') as f:
|
||||
await f.write(json.dumps(data))
|
||||
await f.write(JSONCodec.dumps(data))
|
||||
|
||||
log.debug(data)
|
||||
return data
|
||||
@@ -702,7 +701,7 @@ async def _transcribe_openai(request, file_path, filename, languages, file_dir,
|
||||
data = await r.json()
|
||||
|
||||
async with aiofiles.open(os.path.join(file_dir, f'{id}.json'), 'w') as f:
|
||||
await f.write(json.dumps(data))
|
||||
await f.write(JSONCodec.dumps(data))
|
||||
return data
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
@@ -762,7 +761,7 @@ async def _transcribe_deepgram(request, file_path, languages, file_dir, id):
|
||||
|
||||
data = {'text': transcript}
|
||||
async with aiofiles.open(os.path.join(file_dir, f'{id}.json'), 'w') as f:
|
||||
await f.write(json.dumps(data))
|
||||
await f.write(JSONCodec.dumps(data))
|
||||
return data
|
||||
|
||||
except Exception as e:
|
||||
@@ -828,7 +827,7 @@ async def _transcribe_azure(request, file_path, filename, file_dir, id):
|
||||
raise HTTPException(status_code=400, detail='Azure API key and region are required for Azure STT')
|
||||
|
||||
# Build the transcription definition payload
|
||||
definition = json.dumps(
|
||||
definition = JSONCodec.dumps(
|
||||
{'locales': locale_str.split(','), 'diarization': {'maxSpeakers': max_speakers, 'enabled': True}}
|
||||
if locale_str
|
||||
else {}
|
||||
@@ -868,7 +867,7 @@ async def _transcribe_azure(request, file_path, filename, file_dir, id):
|
||||
data = {'text': transcript}
|
||||
|
||||
async with aiofiles.open(os.path.join(file_dir, f'{id}.json'), 'w') as f:
|
||||
await f.write(json.dumps(data))
|
||||
await f.write(JSONCodec.dumps(data))
|
||||
|
||||
log.debug(data)
|
||||
return data
|
||||
@@ -1046,7 +1045,7 @@ async def _transcribe_mistral(request, file_path, filename, metadata, file_dir,
|
||||
data = {'text': transcript}
|
||||
|
||||
async with aiofiles.open(os.path.join(file_dir, f'{id}.json'), 'w') as f:
|
||||
await f.write(json.dumps(data))
|
||||
await f.write(JSONCodec.dumps(data))
|
||||
|
||||
log.debug(data)
|
||||
return data
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import asyncio
|
||||
import errno
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import uuid
|
||||
@@ -28,8 +27,8 @@ from open_webui.events import EVENTS, publish_event
|
||||
from open_webui.internal.db import get_async_db_context, get_async_session
|
||||
from open_webui.models.access_grants import AccessGrants
|
||||
from open_webui.models.channels import Channels
|
||||
from open_webui.models.config import Config
|
||||
from open_webui.models.chats import Chats
|
||||
from open_webui.models.config import Config
|
||||
from open_webui.models.files import (
|
||||
FileForm,
|
||||
FileListResponse,
|
||||
@@ -55,6 +54,7 @@ router = APIRouter()
|
||||
|
||||
|
||||
from open_webui.utils.access_control.files import has_access_to_file
|
||||
from open_webui.utils.json_codec import JSONCodec
|
||||
|
||||
############################
|
||||
# Upload File
|
||||
@@ -326,8 +326,8 @@ async def upload_file_handler(
|
||||
|
||||
if isinstance(metadata, str):
|
||||
try:
|
||||
metadata = json.loads(metadata)
|
||||
except json.JSONDecodeError:
|
||||
metadata = JSONCodec.loads(metadata)
|
||||
except JSONCodec.JSONDecodeError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=ERROR_MESSAGES.DEFAULT('Invalid metadata format'),
|
||||
@@ -642,14 +642,14 @@ async def get_file_process_status(
|
||||
if status == 'failed':
|
||||
event['error'] = data.get('error')
|
||||
|
||||
yield f'data: {json.dumps(event)}\n\n'
|
||||
yield f'data: {JSONCodec.dumps(event)}\n\n'
|
||||
if status in ('completed', 'failed'):
|
||||
break
|
||||
else:
|
||||
# Legacy
|
||||
break
|
||||
else:
|
||||
yield f'data: {json.dumps({"status": "not_found"})}\n\n'
|
||||
yield f'data: {JSONCodec.dumps({"status": "not_found"})}\n\n'
|
||||
break
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
@@ -3,7 +3,6 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import base64
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import mimetypes
|
||||
import re
|
||||
@@ -17,7 +16,6 @@ import aiofiles
|
||||
import aiohttp
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile
|
||||
from fastapi.responses import FileResponse
|
||||
from PIL import Image, ImageOps
|
||||
from open_webui.config import (
|
||||
CACHE_DIR,
|
||||
ENABLE_OPENAI_IMAGE_EDIT_NORMALIZATION,
|
||||
@@ -43,7 +41,9 @@ from open_webui.utils.images.comfyui import (
|
||||
comfyui_edit_image,
|
||||
comfyui_upload_image,
|
||||
)
|
||||
from open_webui.utils.json_codec import JSONCodec
|
||||
from open_webui.utils.session_pool import get_session
|
||||
from PIL import Image, ImageOps
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -389,7 +389,7 @@ async def get_models(request: Request, user=Depends(get_verified_user)):
|
||||
) as r:
|
||||
info = await r.json()
|
||||
|
||||
workflow = json.loads(image_config.COMFYUI_WORKFLOW)
|
||||
workflow = JSONCodec.loads(image_config.COMFYUI_WORKFLOW)
|
||||
model_node_id = None
|
||||
|
||||
for node in image_config.COMFYUI_WORKFLOW_NODES:
|
||||
@@ -1008,7 +1008,7 @@ async def image_edits(
|
||||
form = aiohttp.FormData()
|
||||
for key, value in data.items():
|
||||
if isinstance(value, dict):
|
||||
form.add_field(key, json.dumps(value))
|
||||
form.add_field(key, JSONCodec.dumps(value))
|
||||
else:
|
||||
form.add_field(key, str(value))
|
||||
for param_name, (filename, file_obj, content_type_val) in files:
|
||||
|
||||
@@ -2,7 +2,6 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import uuid
|
||||
@@ -31,8 +30,8 @@ from open_webui.models.knowledge import (
|
||||
KnowledgeUserResponse,
|
||||
)
|
||||
from open_webui.models.models import ModelForm, Models
|
||||
from open_webui.retrieval.vector.async_client import ASYNC_VECTOR_DB_CLIENT
|
||||
from open_webui.retrieval.external import retrieve_external_knowledge, retrieve_external_knowledge_for_connection
|
||||
from open_webui.retrieval.vector.async_client import ASYNC_VECTOR_DB_CLIENT
|
||||
from open_webui.routers.retrieval import (
|
||||
BatchProcessFilesForm,
|
||||
ProcessFileForm,
|
||||
@@ -43,6 +42,7 @@ from open_webui.storage.provider import Storage
|
||||
from open_webui.utils.access_control import filter_allowed_access_grants, has_permission
|
||||
from open_webui.utils.access_control.files import has_access_to_file
|
||||
from open_webui.utils.auth import get_admin_user, get_verified_user
|
||||
from open_webui.utils.json_codec import JSONCodec
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -1277,7 +1277,7 @@ async def get_pending_knowledge_files(
|
||||
for _ in range(MAX_POLL_DURATION // 3):
|
||||
pending = await Files.get_pending_files_for_knowledge(knowledge_id)
|
||||
data = [f.model_dump() for f in pending]
|
||||
yield f'data: {json.dumps(data)}\n\n'
|
||||
yield f'data: {JSONCodec.dumps(data)}\n\n'
|
||||
if len(pending) == 0:
|
||||
break
|
||||
await asyncio.sleep(3)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import random
|
||||
@@ -16,12 +15,8 @@ import aiohttp
|
||||
from aiocache import cached
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, Request, UploadFile
|
||||
from fastapi.responses import StreamingResponse
|
||||
from pydantic import BaseModel, ConfigDict, validator
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from open_webui.config import UPLOAD_DIR
|
||||
from open_webui.constants import ERROR_MESSAGES
|
||||
from open_webui.events import EVENTS, publish_event, publish_model_provider_request_failed
|
||||
from open_webui.env import (
|
||||
AIOHTTP_CLIENT_SESSION_SSL,
|
||||
AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST,
|
||||
@@ -31,6 +26,7 @@ from open_webui.env import (
|
||||
FORWARD_SESSION_INFO_HEADER_CHAT_ID,
|
||||
MODELS_CACHE_TTL,
|
||||
)
|
||||
from open_webui.events import EVENTS, publish_event, publish_model_provider_request_failed
|
||||
from open_webui.internal.db import get_async_session
|
||||
from open_webui.models.access_grants import AccessGrants
|
||||
from open_webui.models.config import Config
|
||||
@@ -40,15 +36,17 @@ from open_webui.models.users import UserModel
|
||||
from open_webui.utils.access_control import check_model_access
|
||||
from open_webui.utils.auth import get_admin_user, get_verified_user
|
||||
from open_webui.utils.headers import get_custom_headers, include_user_info_headers
|
||||
from open_webui.utils.model_ids import strip_provider_model_prefix
|
||||
from open_webui.utils.json_codec import JSONCodec
|
||||
from open_webui.utils.misc import calculate_sha256
|
||||
from open_webui.utils.model_ids import strip_provider_model_prefix
|
||||
from open_webui.utils.payload import (
|
||||
apply_model_params_to_body_ollama,
|
||||
apply_model_params_to_body_openai,
|
||||
apply_system_prompt_to_body,
|
||||
)
|
||||
from open_webui.utils.session_pool import cleanup_response, get_client_timeout, get_session, stream_wrapper
|
||||
from pydantic import BaseModel, ConfigDict, validator
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -619,7 +617,7 @@ async def unload_model(
|
||||
try:
|
||||
res = await send_request(
|
||||
f'{url}/api/generate',
|
||||
payload=json.dumps(payload),
|
||||
payload=JSONCodec.dumps(payload),
|
||||
key=key,
|
||||
user=user,
|
||||
)
|
||||
@@ -657,7 +655,7 @@ async def pull_model(
|
||||
# Admins may pull from any registry
|
||||
return await send_request(
|
||||
f'{url}/api/pull',
|
||||
payload=json.dumps({**form_data, 'insecure': True}),
|
||||
payload=JSONCodec.dumps({**form_data, 'insecure': True}),
|
||||
key=get_api_key(url_idx, url, (await Config.get('ollama.api_configs', {}))),
|
||||
user=user,
|
||||
stream=True,
|
||||
@@ -812,7 +810,7 @@ async def delete_model(
|
||||
await send_request(
|
||||
f'{url}/api/delete',
|
||||
'DELETE',
|
||||
payload=json.dumps(payload),
|
||||
payload=JSONCodec.dumps(payload),
|
||||
key=key,
|
||||
user=user,
|
||||
)
|
||||
@@ -854,7 +852,7 @@ async def show_model_info(
|
||||
|
||||
return await send_request(
|
||||
f'{url}/api/show',
|
||||
payload=json.dumps(payload),
|
||||
payload=JSONCodec.dumps(payload),
|
||||
key=key,
|
||||
user=user,
|
||||
)
|
||||
@@ -1581,7 +1579,7 @@ async def download_file_stream(
|
||||
) as blob_resp:
|
||||
if blob_resp.ok:
|
||||
await asyncio.to_thread(os.remove, file_path)
|
||||
yield f'data: {json.dumps({"done": done, "blob": f"sha256:{hashed}", "name": file_name})}\n\n'
|
||||
yield f'data: {JSONCodec.dumps({"done": done, "blob": f"sha256:{hashed}", "name": file_name})}\n\n'
|
||||
else:
|
||||
raise RuntimeError('Ollama: Could not create blob, Please try again.')
|
||||
|
||||
@@ -1651,7 +1649,7 @@ async def upload_model(
|
||||
while chunk := await f.read(chunk_size):
|
||||
bytes_read += len(chunk)
|
||||
progress = round(bytes_read / total_size * 100, 2)
|
||||
event = json.dumps({'progress': progress, 'total': total_size, 'completed': bytes_read})
|
||||
event = JSONCodec.dumps({'progress': progress, 'total': total_size, 'completed': bytes_read})
|
||||
yield f'data: {event}\n\n'
|
||||
|
||||
session = await get_session()
|
||||
@@ -1688,13 +1686,13 @@ async def upload_model(
|
||||
async with session.post(
|
||||
f'{ollama_url}/api/create',
|
||||
headers={'Content-Type': 'application/json'},
|
||||
data=json.dumps(create_payload),
|
||||
data=JSONCodec.dumps(create_payload),
|
||||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||
timeout=get_client_timeout(),
|
||||
) as create_resp:
|
||||
if create_resp.ok:
|
||||
log.info('API SUCCESS!')
|
||||
event = json.dumps(
|
||||
event = JSONCodec.dumps(
|
||||
{'done': True, 'blob': f'sha256:{file_hash}', 'name': filename, 'model_created': model}
|
||||
)
|
||||
yield f'data: {event}\n\n'
|
||||
@@ -1703,6 +1701,6 @@ async def upload_model(
|
||||
raise Exception(f'Failed to create model in Ollama. {resp_text}')
|
||||
|
||||
except Exception as exc:
|
||||
yield f'data: {json.dumps({"error": str(exc)})}\n\n'
|
||||
yield f'data: {JSONCodec.dumps({"error": str(exc)})}\n\n'
|
||||
|
||||
return StreamingResponse(file_process_stream(), media_type='text/event-stream')
|
||||
@@ -2,7 +2,6 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from typing import Optional
|
||||
@@ -23,7 +22,6 @@ from open_webui.config import (
|
||||
CACHE_DIR,
|
||||
)
|
||||
from open_webui.constants import ERROR_MESSAGES
|
||||
from open_webui.events import EVENTS, publish_event, publish_model_provider_request_failed
|
||||
from open_webui.env import (
|
||||
AIOHTTP_CLIENT_SESSION_SSL,
|
||||
AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST,
|
||||
@@ -33,6 +31,7 @@ from open_webui.env import (
|
||||
FORWARD_SESSION_INFO_HEADER_CHAT_ID,
|
||||
MODELS_CACHE_TTL,
|
||||
)
|
||||
from open_webui.events import EVENTS, publish_event, publish_model_provider_request_failed
|
||||
from open_webui.internal.db import get_async_session
|
||||
from open_webui.models.access_grants import AccessGrants
|
||||
from open_webui.models.config import Config
|
||||
@@ -44,11 +43,11 @@ from open_webui.utils.anthropic import get_anthropic_models, is_anthropic_url
|
||||
from open_webui.utils.auth import get_admin_user, get_verified_user
|
||||
from open_webui.utils.headers import get_custom_headers, include_user_info_headers
|
||||
from open_webui.utils.json_codec import JSONCodec
|
||||
from open_webui.utils.model_ids import strip_provider_model_prefix
|
||||
from open_webui.utils.misc import (
|
||||
convert_logit_bias_input_to_json,
|
||||
stream_chunks_handler,
|
||||
)
|
||||
from open_webui.utils.model_ids import strip_provider_model_prefix
|
||||
from open_webui.utils.payload import (
|
||||
apply_model_params_to_body_openai,
|
||||
apply_system_prompt_to_body,
|
||||
@@ -353,7 +352,7 @@ async def count_anthropic_tokens(request: Request, form_data: dict, user: UserMo
|
||||
response = await session.request(
|
||||
method='POST',
|
||||
url=request_url,
|
||||
data=json.dumps(payload),
|
||||
data=JSONCodec.dumps(payload),
|
||||
headers=headers,
|
||||
cookies=cookies,
|
||||
ssl=AIOHTTP_CLIENT_SESSION_SSL,
|
||||
@@ -502,7 +501,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
|
||||
await f.write(chunk)
|
||||
|
||||
async with aiofiles.open(file_body_path, 'w') as f:
|
||||
await f.write(json.dumps(json.loads(body.decode('utf-8'))))
|
||||
await f.write(JSONCodec.dumps(JSONCodec.loads(body.decode('utf-8'))))
|
||||
|
||||
# Return the saved file
|
||||
return FileResponse(file_path)
|
||||
@@ -1286,7 +1285,7 @@ async def generate_chat_completion(
|
||||
logit_bias = convert_logit_bias_input_to_json(payload['logit_bias'])
|
||||
|
||||
if logit_bias:
|
||||
payload['logit_bias'] = json.loads(logit_bias)
|
||||
payload['logit_bias'] = JSONCodec.loads(logit_bias)
|
||||
|
||||
headers, cookies = await get_headers_and_cookies(request, url, key, api_config, metadata, user=user)
|
||||
|
||||
@@ -1338,7 +1337,7 @@ async def generate_chat_completion(
|
||||
if not is_streaming_request:
|
||||
payload.pop('stream_options', None)
|
||||
|
||||
payload = json.dumps(payload)
|
||||
payload = JSONCodec.dumps(payload)
|
||||
|
||||
r = None
|
||||
streaming = False
|
||||
@@ -1370,7 +1369,7 @@ async def generate_chat_completion(
|
||||
error_body[:1000],
|
||||
)
|
||||
try:
|
||||
error_json = json.loads(error_body)
|
||||
error_json = JSONCodec.loads(error_body)
|
||||
await publish_model_provider_request_failed(
|
||||
request,
|
||||
actor=user,
|
||||
@@ -1382,7 +1381,7 @@ async def generate_chat_completion(
|
||||
upstream_error=error_json,
|
||||
)
|
||||
return JSONResponse(status_code=r.status, content=error_json)
|
||||
except json.JSONDecodeError:
|
||||
except JSONCodec.JSONDecodeError:
|
||||
await publish_model_provider_request_failed(
|
||||
request,
|
||||
actor=user,
|
||||
@@ -1458,7 +1457,7 @@ async def embeddings(request: Request, form_data: dict, user):
|
||||
"""
|
||||
idx = 0
|
||||
# Prepare payload/body
|
||||
body = json.dumps(form_data)
|
||||
body = JSONCodec.dumps(form_data)
|
||||
# Find correct backend url/key based on model
|
||||
model_id = form_data.get('model')
|
||||
# Check if model is already in app state cache to avoid expensive get_all_models() call
|
||||
@@ -1589,7 +1588,7 @@ async def responses(
|
||||
# Enforce per-model access control
|
||||
await check_model_access(user, await Models.get_model_by_id(model_id), BYPASS_MODEL_ACCESS_CONTROL)
|
||||
|
||||
body = json.dumps(payload)
|
||||
body = JSONCodec.dumps(payload)
|
||||
|
||||
if model_id:
|
||||
models = request.app.state.OPENAI_MODELS
|
||||
@@ -1699,8 +1698,8 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
|
||||
payload = None
|
||||
if body:
|
||||
try:
|
||||
payload = json.loads(body)
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
payload = JSONCodec.loads(body)
|
||||
except (JSONCodec.JSONDecodeError, ValueError):
|
||||
payload = None
|
||||
is_streaming_request = bool(payload.get('stream', False)) if isinstance(payload, dict) else False
|
||||
|
||||
@@ -1738,9 +1737,9 @@ async def proxy(path: str, request: Request, user=Depends(get_verified_user)):
|
||||
api_version = api_config.get('api_version', '2023-03-15-preview')
|
||||
headers['api-version'] = api_version
|
||||
|
||||
payload = json.loads(body)
|
||||
payload = JSONCodec.loads(body)
|
||||
url, payload = convert_to_azure_payload(url, payload, api_version)
|
||||
body = json.dumps(payload).encode()
|
||||
body = JSONCodec.dumps(payload).encode()
|
||||
|
||||
request_url = f'{url}/{path}?api-version={api_version}'
|
||||
else:
|
||||
|
||||
@@ -13,12 +13,13 @@ import aiohttp
|
||||
from fastapi import APIRouter, Depends, Request, Response, WebSocket
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from open_webui.config import TERMINAL_PROXY_HEADERS
|
||||
from open_webui.events import EVENTS, publish_event
|
||||
from open_webui.env import AIOHTTP_CLIENT_SESSION_SSL
|
||||
from open_webui.events import EVENTS, publish_event
|
||||
from open_webui.models.config import Config
|
||||
from open_webui.models.groups import Groups
|
||||
from open_webui.utils.access_control import has_connection_access
|
||||
from open_webui.utils.auth import get_verified_user
|
||||
from open_webui.utils.json_codec import JSONCodec
|
||||
from open_webui.utils.terminals import get_terminal_server_url
|
||||
from open_webui.utils.tools import bearer_auth_header, normalize_bearer_token
|
||||
from starlette.background import BackgroundTask
|
||||
@@ -221,14 +222,13 @@ async def _resolve_authenticated_connection(ws: WebSocket, server_id: str):
|
||||
with an appropriate error code.
|
||||
"""
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from open_webui.utils.auth import get_verified_user_by_token
|
||||
|
||||
# First-message authentication
|
||||
try:
|
||||
raw = await asyncio.wait_for(ws.receive_text(), timeout=10.0)
|
||||
payload = json.loads(raw)
|
||||
payload = JSONCodec.loads(raw)
|
||||
if payload.get('type') != 'auth':
|
||||
await ws.close(code=4001, reason='Expected auth message')
|
||||
return None
|
||||
@@ -236,7 +236,7 @@ async def _resolve_authenticated_connection(ws: WebSocket, server_id: str):
|
||||
if user is None:
|
||||
await ws.close(code=4001, reason='Invalid token')
|
||||
return None
|
||||
except (asyncio.TimeoutError, json.JSONDecodeError):
|
||||
except (asyncio.TimeoutError, JSONCodec.JSONDecodeError):
|
||||
await ws.close(code=4001, reason='Auth timeout or invalid payload')
|
||||
return None
|
||||
except Exception:
|
||||
|
||||
Reference in new issue
Block a user