Merge branch 'dev' of https://github.com/open-webui/open-webui into feat/web-search-toggle
This commit is contained in:
@@ -43,6 +43,8 @@ from config import (
|
||||
DEVICE_TYPE,
|
||||
AUDIO_OPENAI_API_BASE_URL,
|
||||
AUDIO_OPENAI_API_KEY,
|
||||
AUDIO_OPENAI_API_MODEL,
|
||||
AUDIO_OPENAI_API_VOICE,
|
||||
)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -60,6 +62,8 @@ app.add_middleware(
|
||||
|
||||
app.state.OPENAI_API_BASE_URL = AUDIO_OPENAI_API_BASE_URL
|
||||
app.state.OPENAI_API_KEY = AUDIO_OPENAI_API_KEY
|
||||
app.state.OPENAI_API_MODEL = AUDIO_OPENAI_API_MODEL
|
||||
app.state.OPENAI_API_VOICE = AUDIO_OPENAI_API_VOICE
|
||||
|
||||
# setting device type for whisper model
|
||||
whisper_device_type = DEVICE_TYPE if DEVICE_TYPE and DEVICE_TYPE == "cuda" else "cpu"
|
||||
@@ -72,6 +76,8 @@ SPEECH_CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
class OpenAIConfigUpdateForm(BaseModel):
|
||||
url: str
|
||||
key: str
|
||||
model: str
|
||||
speaker: str
|
||||
|
||||
|
||||
@app.get("/config")
|
||||
@@ -79,6 +85,8 @@ async def get_openai_config(user=Depends(get_admin_user)):
|
||||
return {
|
||||
"OPENAI_API_BASE_URL": app.state.OPENAI_API_BASE_URL,
|
||||
"OPENAI_API_KEY": app.state.OPENAI_API_KEY,
|
||||
"OPENAI_API_MODEL": app.state.OPENAI_API_MODEL,
|
||||
"OPENAI_API_VOICE": app.state.OPENAI_API_VOICE,
|
||||
}
|
||||
|
||||
|
||||
@@ -91,11 +99,15 @@ async def update_openai_config(
|
||||
|
||||
app.state.OPENAI_API_BASE_URL = form_data.url
|
||||
app.state.OPENAI_API_KEY = form_data.key
|
||||
app.state.OPENAI_API_MODEL = form_data.model
|
||||
app.state.OPENAI_API_VOICE = form_data.speaker
|
||||
|
||||
return {
|
||||
"status": True,
|
||||
"OPENAI_API_BASE_URL": app.state.OPENAI_API_BASE_URL,
|
||||
"OPENAI_API_KEY": app.state.OPENAI_API_KEY,
|
||||
"OPENAI_API_MODEL": app.state.OPENAI_API_MODEL,
|
||||
"OPENAI_API_VOICE": app.state.OPENAI_API_VOICE,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import uuid
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import logging
|
||||
import time
|
||||
from urllib.parse import urlparse
|
||||
from typing import Optional, List, Union
|
||||
|
||||
@@ -1031,6 +1032,75 @@ async def generate_openai_chat_completion(
|
||||
)
|
||||
|
||||
|
||||
@app.get("/v1/models")
|
||||
@app.get("/v1/models/{url_idx}")
|
||||
async def get_openai_models(
|
||||
url_idx: Optional[int] = None,
|
||||
user=Depends(get_verified_user),
|
||||
):
|
||||
if url_idx == None:
|
||||
models = await get_all_models()
|
||||
|
||||
if app.state.ENABLE_MODEL_FILTER:
|
||||
if user.role == "user":
|
||||
models["models"] = list(
|
||||
filter(
|
||||
lambda model: model["name"] in app.state.MODEL_FILTER_LIST,
|
||||
models["models"],
|
||||
)
|
||||
)
|
||||
|
||||
return {
|
||||
"data": [
|
||||
{
|
||||
"id": model["model"],
|
||||
"object": "model",
|
||||
"created": int(time.time()),
|
||||
"owned_by": "openai",
|
||||
}
|
||||
for model in models["models"]
|
||||
],
|
||||
"object": "list",
|
||||
}
|
||||
|
||||
else:
|
||||
url = app.state.OLLAMA_BASE_URLS[url_idx]
|
||||
try:
|
||||
r = requests.request(method="GET", url=f"{url}/api/tags")
|
||||
r.raise_for_status()
|
||||
|
||||
models = r.json()
|
||||
|
||||
return {
|
||||
"data": [
|
||||
{
|
||||
"id": model["model"],
|
||||
"object": "model",
|
||||
"created": int(time.time()),
|
||||
"owned_by": "openai",
|
||||
}
|
||||
for model in models["models"]
|
||||
],
|
||||
"object": "list",
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
log.exception(e)
|
||||
error_detail = "Open WebUI: Server Connection Error"
|
||||
if r is not None:
|
||||
try:
|
||||
res = r.json()
|
||||
if "error" in res:
|
||||
error_detail = f"Ollama: {res['error']}"
|
||||
except:
|
||||
error_detail = f"Ollama: {e}"
|
||||
|
||||
raise HTTPException(
|
||||
status_code=r.status_code if r else 500,
|
||||
detail=error_detail,
|
||||
)
|
||||
|
||||
|
||||
class UrlForm(BaseModel):
|
||||
url: str
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ from config import (
|
||||
CHUNK_OVERLAP,
|
||||
RAG_TEMPLATE,
|
||||
ENABLE_RAG_LOCAL_WEB_FETCH,
|
||||
YOUTUBE_LOADER_LANGUAGE,
|
||||
RAG_WEB_SEARCH_CONCURRENT_REQUESTS,
|
||||
)
|
||||
|
||||
@@ -126,6 +127,10 @@ app.state.OPENAI_API_KEY = RAG_OPENAI_API_KEY
|
||||
app.state.PDF_EXTRACT_IMAGES = PDF_EXTRACT_IMAGES
|
||||
|
||||
|
||||
app.state.YOUTUBE_LOADER_LANGUAGE = YOUTUBE_LOADER_LANGUAGE
|
||||
app.state.YOUTUBE_LOADER_TRANSLATION = None
|
||||
|
||||
|
||||
def update_embedding_model(
|
||||
embedding_model: str,
|
||||
update_model: bool = False,
|
||||
@@ -320,6 +325,10 @@ async def get_rag_config(user=Depends(get_admin_user)):
|
||||
"chunk_overlap": app.state.CHUNK_OVERLAP,
|
||||
},
|
||||
"web_loader_ssl_verification": app.state.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION,
|
||||
"youtube": {
|
||||
"language": app.state.YOUTUBE_LOADER_LANGUAGE,
|
||||
"translation": app.state.YOUTUBE_LOADER_TRANSLATION,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -328,10 +337,16 @@ class ChunkParamUpdateForm(BaseModel):
|
||||
chunk_overlap: int
|
||||
|
||||
|
||||
class YoutubeLoaderConfig(BaseModel):
|
||||
language: List[str]
|
||||
translation: Optional[str] = None
|
||||
|
||||
|
||||
class ConfigUpdateForm(BaseModel):
|
||||
pdf_extract_images: Optional[bool] = None
|
||||
chunk: Optional[ChunkParamUpdateForm] = None
|
||||
web_loader_ssl_verification: Optional[bool] = None
|
||||
youtube: Optional[YoutubeLoaderConfig] = None
|
||||
|
||||
|
||||
@app.post("/config/update")
|
||||
@@ -358,6 +373,18 @@ async def update_rag_config(form_data: ConfigUpdateForm, user=Depends(get_admin_
|
||||
else app.state.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION
|
||||
)
|
||||
|
||||
app.state.YOUTUBE_LOADER_LANGUAGE = (
|
||||
form_data.youtube.language
|
||||
if form_data.youtube != None
|
||||
else app.state.YOUTUBE_LOADER_LANGUAGE
|
||||
)
|
||||
|
||||
app.state.YOUTUBE_LOADER_TRANSLATION = (
|
||||
form_data.youtube.translation
|
||||
if form_data.youtube != None
|
||||
else app.state.YOUTUBE_LOADER_TRANSLATION
|
||||
)
|
||||
|
||||
return {
|
||||
"status": True,
|
||||
"pdf_extract_images": app.state.PDF_EXTRACT_IMAGES,
|
||||
@@ -366,6 +393,10 @@ async def update_rag_config(form_data: ConfigUpdateForm, user=Depends(get_admin_
|
||||
"chunk_overlap": app.state.CHUNK_OVERLAP,
|
||||
},
|
||||
"web_loader_ssl_verification": app.state.ENABLE_RAG_WEB_LOADER_SSL_VERIFICATION,
|
||||
"youtube": {
|
||||
"language": app.state.YOUTUBE_LOADER_LANGUAGE,
|
||||
"translation": app.state.YOUTUBE_LOADER_TRANSLATION,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -492,7 +523,12 @@ def query_collection_handler(
|
||||
@app.post("/youtube")
|
||||
def store_youtube_video(form_data: UrlForm, user=Depends(get_current_user)):
|
||||
try:
|
||||
loader = YoutubeLoader.from_youtube_url(form_data.url, add_video_info=False)
|
||||
loader = YoutubeLoader.from_youtube_url(
|
||||
form_data.url,
|
||||
add_video_info=True,
|
||||
language=app.state.YOUTUBE_LOADER_LANGUAGE,
|
||||
translation=app.state.YOUTUBE_LOADER_TRANSLATION,
|
||||
)
|
||||
data = loader.load()
|
||||
|
||||
collection_name = form_data.collection_name
|
||||
@@ -676,7 +712,7 @@ def store_docs_in_vector_db(docs, collection_name, overwrite: bool = False) -> b
|
||||
|
||||
for batch in create_batches(
|
||||
api=CHROMA_CLIENT,
|
||||
ids=[str(uuid.uuid1()) for _ in texts],
|
||||
ids=[str(uuid.uuid4()) for _ in texts],
|
||||
metadatas=metadatas,
|
||||
embeddings=embeddings,
|
||||
documents=texts,
|
||||
|
||||
@@ -33,7 +33,7 @@ from utils.utils import (
|
||||
from utils.misc import parse_duration, validate_email_format
|
||||
from utils.webhook import post_webhook
|
||||
from constants import ERROR_MESSAGES, WEBHOOK_MESSAGES
|
||||
from config import WEBUI_AUTH_TRUSTED_EMAIL_HEADER
|
||||
from config import WEBUI_AUTH, WEBUI_AUTH_TRUSTED_EMAIL_HEADER
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -118,6 +118,22 @@ async def signin(request: Request, form_data: SigninForm):
|
||||
),
|
||||
)
|
||||
user = Auths.authenticate_user_by_trusted_header(trusted_email)
|
||||
elif WEBUI_AUTH == False:
|
||||
admin_email = "admin@localhost"
|
||||
admin_password = "admin"
|
||||
|
||||
if Users.get_user_by_email(admin_email.lower()):
|
||||
user = Auths.authenticate_user(admin_email.lower(), admin_password)
|
||||
else:
|
||||
if Users.get_num_users() != 0:
|
||||
raise HTTPException(400, detail=ERROR_MESSAGES.EXISTING_USERS)
|
||||
|
||||
await signup(
|
||||
request,
|
||||
SignupForm(email=admin_email, password=admin_password, name="User"),
|
||||
)
|
||||
|
||||
user = Auths.authenticate_user(admin_email.lower(), admin_password)
|
||||
else:
|
||||
user = Auths.authenticate_user(form_data.email.lower(), form_data.password)
|
||||
|
||||
@@ -147,7 +163,7 @@ async def signin(request: Request, form_data: SigninForm):
|
||||
|
||||
@router.post("/signup", response_model=SigninResponse)
|
||||
async def signup(request: Request, form_data: SignupForm):
|
||||
if not request.app.state.ENABLE_SIGNUP:
|
||||
if not request.app.state.ENABLE_SIGNUP and WEBUI_AUTH:
|
||||
raise HTTPException(
|
||||
status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user