forked from open-webui/open-webui
Merge branch 'main' into litellm
This commit is contained in:
commit
ee22e641ff
39 changed files with 887 additions and 166 deletions
|
@ -1,4 +1,4 @@
|
|||
import os
|
||||
import re
|
||||
import requests
|
||||
from fastapi import (
|
||||
FastAPI,
|
||||
|
@ -34,6 +34,7 @@ app.add_middleware(
|
|||
|
||||
app.state.AUTOMATIC1111_BASE_URL = AUTOMATIC1111_BASE_URL
|
||||
app.state.ENABLED = app.state.AUTOMATIC1111_BASE_URL != ""
|
||||
app.state.IMAGE_SIZE = "512x512"
|
||||
|
||||
|
||||
@app.get("/enabled", response_model=bool)
|
||||
|
@ -74,6 +75,33 @@ async def update_openai_url(form_data: UrlUpdateForm, user=Depends(get_admin_use
|
|||
}
|
||||
|
||||
|
||||
class ImageSizeUpdateForm(BaseModel):
|
||||
size: str
|
||||
|
||||
|
||||
@app.get("/size")
|
||||
async def get_image_size(user=Depends(get_admin_user)):
|
||||
return {"IMAGE_SIZE": app.state.IMAGE_SIZE}
|
||||
|
||||
|
||||
@app.post("/size/update")
|
||||
async def update_image_size(
|
||||
form_data: ImageSizeUpdateForm, user=Depends(get_admin_user)
|
||||
):
|
||||
pattern = r"^\d+x\d+$" # Regular expression pattern
|
||||
if re.match(pattern, form_data.size):
|
||||
app.state.IMAGE_SIZE = form_data.size
|
||||
return {
|
||||
"IMAGE_SIZE": app.state.IMAGE_SIZE,
|
||||
"status": True,
|
||||
}
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=ERROR_MESSAGES.INCORRECT_FORMAT(" (e.g., 512x512)."),
|
||||
)
|
||||
|
||||
|
||||
@app.get("/models")
|
||||
def get_models(user=Depends(get_current_user)):
|
||||
try:
|
||||
|
@ -140,7 +168,7 @@ def generate_image(
|
|||
if form_data.model:
|
||||
set_model_handler(form_data.model)
|
||||
|
||||
width, height = tuple(map(int, form_data.size.split("x")))
|
||||
width, height = tuple(map(int, app.state.IMAGE_SIZE.split("x")))
|
||||
|
||||
data = {
|
||||
"prompt": form_data.prompt,
|
||||
|
|
|
@ -423,7 +423,7 @@ def get_loader(filename: str, file_content_type: str, file_path: str):
|
|||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
] or file_ext in ["xls", "xlsx"]:
|
||||
loader = UnstructuredExcelLoader(file_path)
|
||||
elif file_ext in known_source_ext or file_content_type.find("text/") >= 0:
|
||||
elif file_ext in known_source_ext or (file_content_type and file_content_type.find("text/") >= 0):
|
||||
loader = TextLoader(file_path)
|
||||
else:
|
||||
loader = TextLoader(file_path)
|
||||
|
@ -486,8 +486,8 @@ def store_doc(
|
|||
|
||||
@app.get("/scan")
|
||||
def scan_docs_dir(user=Depends(get_admin_user)):
|
||||
try:
|
||||
for path in Path(DOCS_DIR).rglob("./**/*"):
|
||||
for path in Path(DOCS_DIR).rglob("./**/*"):
|
||||
try:
|
||||
if path.is_file() and not path.name.startswith("."):
|
||||
tags = extract_folders_after_data_docs(path)
|
||||
filename = path.name
|
||||
|
@ -535,8 +535,8 @@ def scan_docs_dir(user=Depends(get_admin_user)):
|
|||
),
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
import os
|
||||
import chromadb
|
||||
from chromadb import Settings
|
||||
from secrets import token_bytes
|
||||
from base64 import b64encode
|
||||
from constants import ERROR_MESSAGES
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from pathlib import Path
|
||||
import json
|
||||
import markdown
|
||||
import requests
|
||||
import shutil
|
||||
|
||||
from secrets import token_bytes
|
||||
from constants import ERROR_MESSAGES
|
||||
|
||||
|
||||
try:
|
||||
|
@ -15,6 +21,8 @@ try:
|
|||
except ImportError:
|
||||
print("dotenv not installed, skipping...")
|
||||
|
||||
WEBUI_NAME = "Open WebUI"
|
||||
shutil.copyfile("../build/favicon.png", "./static/favicon.png")
|
||||
|
||||
####################################
|
||||
# ENV (dev,test,prod)
|
||||
|
@ -22,6 +30,104 @@ except ImportError:
|
|||
|
||||
ENV = os.environ.get("ENV", "dev")
|
||||
|
||||
try:
|
||||
with open(f"../package.json", "r") as f:
|
||||
PACKAGE_DATA = json.load(f)
|
||||
except:
|
||||
PACKAGE_DATA = {"version": "0.0.0"}
|
||||
|
||||
VERSION = PACKAGE_DATA["version"]
|
||||
|
||||
|
||||
# Function to parse each section
|
||||
def parse_section(section):
|
||||
items = []
|
||||
for li in section.find_all("li"):
|
||||
# Extract raw HTML string
|
||||
raw_html = str(li)
|
||||
|
||||
# Extract text without HTML tags
|
||||
text = li.get_text(separator=" ", strip=True)
|
||||
|
||||
# Split into title and content
|
||||
parts = text.split(": ", 1)
|
||||
title = parts[0].strip() if len(parts) > 1 else ""
|
||||
content = parts[1].strip() if len(parts) > 1 else text
|
||||
|
||||
items.append({"title": title, "content": content, "raw": raw_html})
|
||||
return items
|
||||
|
||||
|
||||
try:
|
||||
with open("../CHANGELOG.md", "r") as file:
|
||||
changelog_content = file.read()
|
||||
except:
|
||||
changelog_content = ""
|
||||
|
||||
# Convert markdown content to HTML
|
||||
html_content = markdown.markdown(changelog_content)
|
||||
|
||||
# Parse the HTML content
|
||||
soup = BeautifulSoup(html_content, "html.parser")
|
||||
|
||||
# Initialize JSON structure
|
||||
changelog_json = {}
|
||||
|
||||
# Iterate over each version
|
||||
for version in soup.find_all("h2"):
|
||||
version_number = version.get_text().strip().split(" - ")[0][1:-1] # Remove brackets
|
||||
date = version.get_text().strip().split(" - ")[1]
|
||||
|
||||
version_data = {"date": date}
|
||||
|
||||
# Find the next sibling that is a h3 tag (section title)
|
||||
current = version.find_next_sibling()
|
||||
|
||||
print(current)
|
||||
|
||||
while current and current.name != "h2":
|
||||
if current.name == "h3":
|
||||
section_title = current.get_text().lower() # e.g., "added", "fixed"
|
||||
section_items = parse_section(current.find_next_sibling("ul"))
|
||||
version_data[section_title] = section_items
|
||||
|
||||
# Move to the next element
|
||||
current = current.find_next_sibling()
|
||||
|
||||
changelog_json[version_number] = version_data
|
||||
|
||||
|
||||
CHANGELOG = changelog_json
|
||||
|
||||
|
||||
####################################
|
||||
# CUSTOM_NAME
|
||||
####################################
|
||||
|
||||
CUSTOM_NAME = os.environ.get("CUSTOM_NAME", "")
|
||||
if CUSTOM_NAME:
|
||||
try:
|
||||
r = requests.get(f"https://api.openwebui.com/api/v1/custom/{CUSTOM_NAME}")
|
||||
data = r.json()
|
||||
if r.ok:
|
||||
if "logo" in data:
|
||||
url = (
|
||||
f"https://api.openwebui.com{data['logo']}"
|
||||
if data["logo"][0] == "/"
|
||||
else data["logo"]
|
||||
)
|
||||
|
||||
r = requests.get(url, stream=True)
|
||||
if r.status_code == 200:
|
||||
with open("./static/favicon.png", "wb") as f:
|
||||
r.raw.decode_content = True
|
||||
shutil.copyfileobj(r.raw, f)
|
||||
|
||||
WEBUI_NAME = data["name"]
|
||||
except Exception as e:
|
||||
print(e)
|
||||
pass
|
||||
|
||||
|
||||
####################################
|
||||
# DATA/FRONTEND BUILD DIR
|
||||
|
@ -116,7 +222,7 @@ DEFAULT_PROMPT_SUGGESTIONS = (
|
|||
)
|
||||
|
||||
|
||||
DEFAULT_USER_ROLE = "pending"
|
||||
DEFAULT_USER_ROLE = os.getenv("DEFAULT_USER_ROLE", "pending")
|
||||
USER_PERMISSIONS = {"chat": {"deletion": True}}
|
||||
|
||||
|
||||
|
|
|
@ -44,3 +44,6 @@ class ERROR_MESSAGES(str, Enum):
|
|||
MALICIOUS = "Unusual activities detected, please try again in a few minutes."
|
||||
|
||||
PANDOC_NOT_INSTALLED = "Pandoc is not installed on the server. Please contact your administrator for assistance."
|
||||
INCORRECT_FORMAT = (
|
||||
lambda err="": f"Invalid format. Please use the correct format{err if err else ''}"
|
||||
)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
from bs4 import BeautifulSoup
|
||||
import json
|
||||
import markdown
|
||||
import time
|
||||
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi import HTTPException
|
||||
|
@ -18,7 +22,7 @@ from apps.rag.main import app as rag_app
|
|||
|
||||
from apps.web.main import app as webui_app
|
||||
|
||||
from config import ENV, FRONTEND_BUILD_DIR
|
||||
from config import WEBUI_NAME, ENV, VERSION, CHANGELOG, FRONTEND_BUILD_DIR
|
||||
|
||||
|
||||
class SPAStaticFiles(StaticFiles):
|
||||
|
@ -69,14 +73,25 @@ app.mount("/rag/api/v1", rag_app)
|
|||
|
||||
@app.get("/api/config")
|
||||
async def get_app_config():
|
||||
|
||||
return {
|
||||
"status": True,
|
||||
"name": WEBUI_NAME,
|
||||
"version": VERSION,
|
||||
"images": images_app.state.ENABLED,
|
||||
"default_models": webui_app.state.DEFAULT_MODELS,
|
||||
"default_prompt_suggestions": webui_app.state.DEFAULT_PROMPT_SUGGESTIONS,
|
||||
}
|
||||
|
||||
|
||||
@app.get("/api/changelog")
|
||||
async def get_app_changelog():
|
||||
return CHANGELOG
|
||||
|
||||
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
|
||||
|
||||
app.mount(
|
||||
"/",
|
||||
SPAStaticFiles(directory=FRONTEND_BUILD_DIR, html=True),
|
||||
|
|
BIN
backend/static/favicon.png
Normal file
BIN
backend/static/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6 KiB |
Loading…
Add table
Add a link
Reference in a new issue