Merge pull request #4597 from michaelpoluektov/cleanup

refactor: search and replace-able cleanup
This commit is contained in:
Timothy Jaeryang Baek 2024-08-14 16:30:27 +02:00 committed by GitHub
commit 9f0c9d973c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 215 additions and 214 deletions

View File

@ -15,7 +15,7 @@ from fastapi.responses import StreamingResponse, JSONResponse, FileResponse
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel from pydantic import BaseModel
from typing import List
import uuid import uuid
import requests import requests
import hashlib import hashlib
@ -244,7 +244,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
res = r.json() res = r.json()
if "error" in res: if "error" in res:
error_detail = f"External: {res['error']['message']}" error_detail = f"External: {res['error']['message']}"
except: except Exception:
error_detail = f"External: {e}" error_detail = f"External: {e}"
raise HTTPException( raise HTTPException(
@ -299,7 +299,7 @@ async def speech(request: Request, user=Depends(get_verified_user)):
res = r.json() res = r.json()
if "error" in res: if "error" in res:
error_detail = f"External: {res['error']['message']}" error_detail = f"External: {res['error']['message']}"
except: except Exception:
error_detail = f"External: {e}" error_detail = f"External: {e}"
raise HTTPException( raise HTTPException(
@ -353,7 +353,7 @@ def transcribe(
try: try:
model = WhisperModel(**whisper_kwargs) model = WhisperModel(**whisper_kwargs)
except: except Exception:
log.warning( log.warning(
"WhisperModel initialization failed, attempting download with local_files_only=False" "WhisperModel initialization failed, attempting download with local_files_only=False"
) )
@ -421,7 +421,7 @@ def transcribe(
res = r.json() res = r.json()
if "error" in res: if "error" in res:
error_detail = f"External: {res['error']['message']}" error_detail = f"External: {res['error']['message']}"
except: except Exception:
error_detail = f"External: {e}" error_detail = f"External: {e}"
raise HTTPException( raise HTTPException(
@ -438,7 +438,7 @@ def transcribe(
) )
def get_available_models() -> List[dict]: def get_available_models() -> list[dict]:
if app.state.config.TTS_ENGINE == "openai": if app.state.config.TTS_ENGINE == "openai":
return [{"id": "tts-1"}, {"id": "tts-1-hd"}] return [{"id": "tts-1"}, {"id": "tts-1-hd"}]
elif app.state.config.TTS_ENGINE == "elevenlabs": elif app.state.config.TTS_ENGINE == "elevenlabs":
@ -466,7 +466,7 @@ async def get_models(user=Depends(get_verified_user)):
return {"models": get_available_models()} return {"models": get_available_models()}
def get_available_voices() -> List[dict]: def get_available_voices() -> list[dict]:
if app.state.config.TTS_ENGINE == "openai": if app.state.config.TTS_ENGINE == "openai":
return [ return [
{"name": "alloy", "id": "alloy"}, {"name": "alloy", "id": "alloy"},

View File

@ -94,7 +94,7 @@ app.state.config.COMFYUI_FLUX_FP8_CLIP = COMFYUI_FLUX_FP8_CLIP
def get_automatic1111_api_auth(): def get_automatic1111_api_auth():
if app.state.config.AUTOMATIC1111_API_AUTH == None: if app.state.config.AUTOMATIC1111_API_AUTH is None:
return "" return ""
else: else:
auth1111_byte_string = app.state.config.AUTOMATIC1111_API_AUTH.encode("utf-8") auth1111_byte_string = app.state.config.AUTOMATIC1111_API_AUTH.encode("utf-8")
@ -145,7 +145,7 @@ async def get_engine_url(user=Depends(get_admin_user)):
async def update_engine_url( async def update_engine_url(
form_data: EngineUrlUpdateForm, user=Depends(get_admin_user) form_data: EngineUrlUpdateForm, user=Depends(get_admin_user)
): ):
if form_data.AUTOMATIC1111_BASE_URL == None: if form_data.AUTOMATIC1111_BASE_URL is None:
app.state.config.AUTOMATIC1111_BASE_URL = AUTOMATIC1111_BASE_URL app.state.config.AUTOMATIC1111_BASE_URL = AUTOMATIC1111_BASE_URL
else: else:
url = form_data.AUTOMATIC1111_BASE_URL.strip("/") url = form_data.AUTOMATIC1111_BASE_URL.strip("/")
@ -156,7 +156,7 @@ async def update_engine_url(
except Exception as e: except Exception as e:
raise HTTPException(status_code=400, detail=ERROR_MESSAGES.INVALID_URL) raise HTTPException(status_code=400, detail=ERROR_MESSAGES.INVALID_URL)
if form_data.COMFYUI_BASE_URL == None: if form_data.COMFYUI_BASE_URL is None:
app.state.config.COMFYUI_BASE_URL = COMFYUI_BASE_URL app.state.config.COMFYUI_BASE_URL = COMFYUI_BASE_URL
else: else:
url = form_data.COMFYUI_BASE_URL.strip("/") url = form_data.COMFYUI_BASE_URL.strip("/")
@ -168,7 +168,7 @@ async def update_engine_url(
except Exception as e: except Exception as e:
raise HTTPException(status_code=400, detail=ERROR_MESSAGES.INVALID_URL) raise HTTPException(status_code=400, detail=ERROR_MESSAGES.INVALID_URL)
if form_data.AUTOMATIC1111_API_AUTH == None: if form_data.AUTOMATIC1111_API_AUTH is None:
app.state.config.AUTOMATIC1111_API_AUTH = AUTOMATIC1111_API_AUTH app.state.config.AUTOMATIC1111_API_AUTH = AUTOMATIC1111_API_AUTH
else: else:
app.state.config.AUTOMATIC1111_API_AUTH = form_data.AUTOMATIC1111_API_AUTH app.state.config.AUTOMATIC1111_API_AUTH = form_data.AUTOMATIC1111_API_AUTH

View File

@ -21,7 +21,7 @@ import asyncio
import logging import logging
import time import time
from urllib.parse import urlparse from urllib.parse import urlparse
from typing import Optional, List, Union from typing import Optional, Union
from starlette.background import BackgroundTask from starlette.background import BackgroundTask
@ -114,7 +114,7 @@ async def get_ollama_api_urls(user=Depends(get_admin_user)):
class UrlUpdateForm(BaseModel): class UrlUpdateForm(BaseModel):
urls: List[str] urls: list[str]
@app.post("/urls/update") @app.post("/urls/update")
@ -646,7 +646,7 @@ def generate_ollama_embeddings(
class GenerateCompletionForm(BaseModel): class GenerateCompletionForm(BaseModel):
model: str model: str
prompt: str prompt: str
images: Optional[List[str]] = None images: Optional[list[str]] = None
format: Optional[str] = None format: Optional[str] = None
options: Optional[dict] = None options: Optional[dict] = None
system: Optional[str] = None system: Optional[str] = None
@ -689,12 +689,12 @@ async def generate_completion(
class ChatMessage(BaseModel): class ChatMessage(BaseModel):
role: str role: str
content: str content: str
images: Optional[List[str]] = None images: Optional[list[str]] = None
class GenerateChatCompletionForm(BaseModel): class GenerateChatCompletionForm(BaseModel):
model: str model: str
messages: List[ChatMessage] messages: list[ChatMessage]
format: Optional[str] = None format: Optional[str] = None
options: Optional[dict] = None options: Optional[dict] = None
template: Optional[str] = None template: Optional[str] = None
@ -772,7 +772,7 @@ class OpenAIChatMessage(BaseModel):
class OpenAIChatCompletionForm(BaseModel): class OpenAIChatCompletionForm(BaseModel):
model: str model: str
messages: List[OpenAIChatMessage] messages: list[OpenAIChatMessage]
model_config = ConfigDict(extra="allow") model_config = ConfigDict(extra="allow")

View File

@ -33,7 +33,7 @@ from config import (
MODEL_FILTER_LIST, MODEL_FILTER_LIST,
AppConfig, AppConfig,
) )
from typing import List, Optional, Literal, overload from typing import Optional, Literal, overload
import hashlib import hashlib
@ -89,11 +89,11 @@ async def update_config(form_data: OpenAIConfigForm, user=Depends(get_admin_user
class UrlsUpdateForm(BaseModel): class UrlsUpdateForm(BaseModel):
urls: List[str] urls: list[str]
class KeysUpdateForm(BaseModel): class KeysUpdateForm(BaseModel):
keys: List[str] keys: list[str]
@app.get("/urls") @app.get("/urls")

View File

@ -13,7 +13,7 @@ import os, shutil, logging, re
from datetime import datetime from datetime import datetime
from pathlib import Path from pathlib import Path
from typing import List, Union, Sequence, Iterator, Any from typing import Union, Sequence, Iterator, Any
from chromadb.utils.batch_utils import create_batches from chromadb.utils.batch_utils import create_batches
from langchain_core.documents import Document from langchain_core.documents import Document
@ -439,7 +439,7 @@ class ChunkParamUpdateForm(BaseModel):
class YoutubeLoaderConfig(BaseModel): class YoutubeLoaderConfig(BaseModel):
language: List[str] language: list[str]
translation: Optional[str] = None translation: Optional[str] = None
@ -642,7 +642,7 @@ def query_doc_handler(
class QueryCollectionsForm(BaseModel): class QueryCollectionsForm(BaseModel):
collection_names: List[str] collection_names: list[str]
query: str query: str
k: Optional[int] = None k: Optional[int] = None
r: Optional[float] = None r: Optional[float] = None
@ -1021,7 +1021,7 @@ class TikaLoader:
self.file_path = file_path self.file_path = file_path
self.mime_type = mime_type self.mime_type = mime_type
def load(self) -> List[Document]: def load(self) -> list[Document]:
with open(self.file_path, "rb") as f: with open(self.file_path, "rb") as f:
data = f.read() data = f.read()
@ -1185,7 +1185,7 @@ def store_doc(
f.close() f.close()
f = open(file_path, "rb") f = open(file_path, "rb")
if collection_name == None: if collection_name is None:
collection_name = calculate_sha256(f)[:63] collection_name = calculate_sha256(f)[:63]
f.close() f.close()
@ -1238,7 +1238,7 @@ def process_doc(
f = open(file_path, "rb") f = open(file_path, "rb")
collection_name = form_data.collection_name collection_name = form_data.collection_name
if collection_name == None: if collection_name is None:
collection_name = calculate_sha256(f)[:63] collection_name = calculate_sha256(f)[:63]
f.close() f.close()
@ -1296,7 +1296,7 @@ def store_text(
): ):
collection_name = form_data.collection_name collection_name = form_data.collection_name
if collection_name == None: if collection_name is None:
collection_name = calculate_sha256_string(form_data.content) collection_name = calculate_sha256_string(form_data.content)
result = store_text_in_vector_db( result = store_text_in_vector_db(
@ -1339,7 +1339,7 @@ def scan_docs_dir(user=Depends(get_admin_user)):
sanitized_filename = sanitize_filename(filename) sanitized_filename = sanitize_filename(filename)
doc = Documents.get_doc_by_name(sanitized_filename) doc = Documents.get_doc_by_name(sanitized_filename)
if doc == None: if doc is None:
doc = Documents.insert_new_doc( doc = Documents.insert_new_doc(
user.id, user.id,
DocumentForm( DocumentForm(

View File

@ -1,5 +1,5 @@
import logging import logging
from typing import List, Optional from typing import Optional
import requests import requests
from apps.rag.search.main import SearchResult, get_filtered_results from apps.rag.search.main import SearchResult, get_filtered_results
@ -10,7 +10,7 @@ log.setLevel(SRC_LOG_LEVELS["RAG"])
def search_brave( def search_brave(
api_key: str, query: str, count: int, filter_list: Optional[List[str]] = None api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None
) -> list[SearchResult]: ) -> list[SearchResult]:
"""Search using Brave's Search API and return the results as a list of SearchResult objects. """Search using Brave's Search API and return the results as a list of SearchResult objects.

View File

@ -1,5 +1,5 @@
import logging import logging
from typing import List, Optional from typing import Optional
from apps.rag.search.main import SearchResult, get_filtered_results from apps.rag.search.main import SearchResult, get_filtered_results
from duckduckgo_search import DDGS from duckduckgo_search import DDGS
from config import SRC_LOG_LEVELS from config import SRC_LOG_LEVELS
@ -9,7 +9,7 @@ log.setLevel(SRC_LOG_LEVELS["RAG"])
def search_duckduckgo( def search_duckduckgo(
query: str, count: int, filter_list: Optional[List[str]] = None query: str, count: int, filter_list: Optional[list[str]] = None
) -> list[SearchResult]: ) -> list[SearchResult]:
""" """
Search using DuckDuckGo's Search API and return the results as a list of SearchResult objects. Search using DuckDuckGo's Search API and return the results as a list of SearchResult objects.
@ -18,7 +18,7 @@ def search_duckduckgo(
count (int): The number of results to return count (int): The number of results to return
Returns: Returns:
List[SearchResult]: A list of search results list[SearchResult]: A list of search results
""" """
# Use the DDGS context manager to create a DDGS object # Use the DDGS context manager to create a DDGS object
with DDGS() as ddgs: with DDGS() as ddgs:

View File

@ -1,6 +1,6 @@
import json import json
import logging import logging
from typing import List, Optional from typing import Optional
import requests import requests
from apps.rag.search.main import SearchResult, get_filtered_results from apps.rag.search.main import SearchResult, get_filtered_results
@ -15,7 +15,7 @@ def search_google_pse(
search_engine_id: str, search_engine_id: str,
query: str, query: str,
count: int, count: int,
filter_list: Optional[List[str]] = None, filter_list: Optional[list[str]] = None,
) -> list[SearchResult]: ) -> list[SearchResult]:
"""Search using Google's Programmable Search Engine API and return the results as a list of SearchResult objects. """Search using Google's Programmable Search Engine API and return the results as a list of SearchResult objects.

View File

@ -17,7 +17,7 @@ def search_jina(query: str, count: int) -> list[SearchResult]:
count (int): The number of results to return count (int): The number of results to return
Returns: Returns:
List[SearchResult]: A list of search results list[SearchResult]: A list of search results
""" """
jina_search_endpoint = "https://s.jina.ai/" jina_search_endpoint = "https://s.jina.ai/"
headers = { headers = {

View File

@ -1,7 +1,7 @@
import logging import logging
import requests import requests
from typing import List, Optional from typing import Optional
from apps.rag.search.main import SearchResult, get_filtered_results from apps.rag.search.main import SearchResult, get_filtered_results
from config import SRC_LOG_LEVELS from config import SRC_LOG_LEVELS
@ -14,9 +14,9 @@ def search_searxng(
query_url: str, query_url: str,
query: str, query: str,
count: int, count: int,
filter_list: Optional[List[str]] = None, filter_list: Optional[list[str]] = None,
**kwargs, **kwargs,
) -> List[SearchResult]: ) -> list[SearchResult]:
""" """
Search a SearXNG instance for a given query and return the results as a list of SearchResult objects. Search a SearXNG instance for a given query and return the results as a list of SearchResult objects.
@ -31,10 +31,10 @@ def search_searxng(
language (str): Language filter for the search results; e.g., "en-US". Defaults to an empty string. language (str): Language filter for the search results; e.g., "en-US". Defaults to an empty string.
safesearch (int): Safe search filter for safer web results; 0 = off, 1 = moderate, 2 = strict. Defaults to 1 (moderate). safesearch (int): Safe search filter for safer web results; 0 = off, 1 = moderate, 2 = strict. Defaults to 1 (moderate).
time_range (str): Time range for filtering results by date; e.g., "2023-04-05..today" or "all-time". Defaults to ''. time_range (str): Time range for filtering results by date; e.g., "2023-04-05..today" or "all-time". Defaults to ''.
categories: (Optional[List[str]]): Specific categories within which the search should be performed, defaulting to an empty string if not provided. categories: (Optional[list[str]]): Specific categories within which the search should be performed, defaulting to an empty string if not provided.
Returns: Returns:
List[SearchResult]: A list of SearchResults sorted by relevance score in descending order. list[SearchResult]: A list of SearchResults sorted by relevance score in descending order.
Raise: Raise:
requests.exceptions.RequestException: If a request error occurs during the search process. requests.exceptions.RequestException: If a request error occurs during the search process.

View File

@ -1,6 +1,6 @@
import json import json
import logging import logging
from typing import List, Optional from typing import Optional
import requests import requests
from apps.rag.search.main import SearchResult, get_filtered_results from apps.rag.search.main import SearchResult, get_filtered_results
@ -11,7 +11,7 @@ log.setLevel(SRC_LOG_LEVELS["RAG"])
def search_serper( def search_serper(
api_key: str, query: str, count: int, filter_list: Optional[List[str]] = None api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None
) -> list[SearchResult]: ) -> list[SearchResult]:
"""Search using serper.dev's API and return the results as a list of SearchResult objects. """Search using serper.dev's API and return the results as a list of SearchResult objects.

View File

@ -1,6 +1,6 @@
import json import json
import logging import logging
from typing import List, Optional from typing import Optional
import requests import requests
from urllib.parse import urlencode from urllib.parse import urlencode
@ -19,7 +19,7 @@ def search_serply(
limit: int = 10, limit: int = 10,
device_type: str = "desktop", device_type: str = "desktop",
proxy_location: str = "US", proxy_location: str = "US",
filter_list: Optional[List[str]] = None, filter_list: Optional[list[str]] = None,
) -> list[SearchResult]: ) -> list[SearchResult]:
"""Search using serper.dev's API and return the results as a list of SearchResult objects. """Search using serper.dev's API and return the results as a list of SearchResult objects.

View File

@ -1,6 +1,6 @@
import json import json
import logging import logging
from typing import List, Optional from typing import Optional
import requests import requests
from apps.rag.search.main import SearchResult, get_filtered_results from apps.rag.search.main import SearchResult, get_filtered_results
@ -14,7 +14,7 @@ def search_serpstack(
api_key: str, api_key: str,
query: str, query: str,
count: int, count: int,
filter_list: Optional[List[str]] = None, filter_list: Optional[list[str]] = None,
https_enabled: bool = True, https_enabled: bool = True,
) -> list[SearchResult]: ) -> list[SearchResult]:
"""Search using serpstack.com's and return the results as a list of SearchResult objects. """Search using serpstack.com's and return the results as a list of SearchResult objects.

View File

@ -17,7 +17,7 @@ def search_tavily(api_key: str, query: str, count: int) -> list[SearchResult]:
query (str): The query to search for query (str): The query to search for
Returns: Returns:
List[SearchResult]: A list of search results list[SearchResult]: A list of search results
""" """
url = "https://api.tavily.com/search" url = "https://api.tavily.com/search"
data = {"query": query, "api_key": api_key} data = {"query": query, "api_key": api_key}

View File

@ -2,7 +2,7 @@ import os
import logging import logging
import requests import requests
from typing import List, Union from typing import Union
from apps.ollama.main import ( from apps.ollama.main import (
generate_ollama_embeddings, generate_ollama_embeddings,
@ -142,7 +142,7 @@ def merge_and_sort_query_results(query_results, k, reverse=False):
def query_collection( def query_collection(
collection_names: List[str], collection_names: list[str],
query: str, query: str,
embedding_function, embedding_function,
k: int, k: int,
@ -157,13 +157,13 @@ def query_collection(
embedding_function=embedding_function, embedding_function=embedding_function,
) )
results.append(result) results.append(result)
except: except Exception:
pass pass
return merge_and_sort_query_results(results, k=k) return merge_and_sort_query_results(results, k=k)
def query_collection_with_hybrid_search( def query_collection_with_hybrid_search(
collection_names: List[str], collection_names: list[str],
query: str, query: str,
embedding_function, embedding_function,
k: int, k: int,
@ -182,7 +182,7 @@ def query_collection_with_hybrid_search(
r=r, r=r,
) )
results.append(result) results.append(result)
except: except Exception:
pass pass
return merge_and_sort_query_results(results, k=k, reverse=True) return merge_and_sort_query_results(results, k=k, reverse=True)
@ -411,7 +411,7 @@ class ChromaRetriever(BaseRetriever):
query: str, query: str,
*, *,
run_manager: CallbackManagerForRetrieverRun, run_manager: CallbackManagerForRetrieverRun,
) -> List[Document]: ) -> list[Document]:
query_embeddings = self.embedding_function(query) query_embeddings = self.embedding_function(query)
results = self.collection.query( results = self.collection.query(

View File

@ -140,7 +140,7 @@ class AuthsTable:
return None return None
else: else:
return None return None
except: except Exception:
return None return None
def authenticate_user_by_api_key(self, api_key: str) -> Optional[UserModel]: def authenticate_user_by_api_key(self, api_key: str) -> Optional[UserModel]:
@ -152,7 +152,7 @@ class AuthsTable:
try: try:
user = Users.get_user_by_api_key(api_key) user = Users.get_user_by_api_key(api_key)
return user if user else None return user if user else None
except: except Exception:
return False return False
def authenticate_user_by_trusted_header(self, email: str) -> Optional[UserModel]: def authenticate_user_by_trusted_header(self, email: str) -> Optional[UserModel]:
@ -163,7 +163,7 @@ class AuthsTable:
if auth: if auth:
user = Users.get_user_by_id(auth.id) user = Users.get_user_by_id(auth.id)
return user return user
except: except Exception:
return None return None
def update_user_password_by_id(self, id: str, new_password: str) -> bool: def update_user_password_by_id(self, id: str, new_password: str) -> bool:
@ -174,7 +174,7 @@ class AuthsTable:
) )
db.commit() db.commit()
return True if result == 1 else False return True if result == 1 else False
except: except Exception:
return False return False
def update_email_by_id(self, id: str, email: str) -> bool: def update_email_by_id(self, id: str, email: str) -> bool:
@ -183,7 +183,7 @@ class AuthsTable:
result = db.query(Auth).filter_by(id=id).update({"email": email}) result = db.query(Auth).filter_by(id=id).update({"email": email})
db.commit() db.commit()
return True if result == 1 else False return True if result == 1 else False
except: except Exception:
return False return False
def delete_auth_by_id(self, id: str) -> bool: def delete_auth_by_id(self, id: str) -> bool:
@ -200,7 +200,7 @@ class AuthsTable:
return True return True
else: else:
return False return False
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Union, Optional from typing import Union, Optional
import json import json
import uuid import uuid
@ -164,7 +164,7 @@ class ChatTable:
db.refresh(chat) db.refresh(chat)
return self.get_chat_by_id(chat.share_id) return self.get_chat_by_id(chat.share_id)
except: except Exception:
return None return None
def delete_shared_chat_by_chat_id(self, chat_id: str) -> bool: def delete_shared_chat_by_chat_id(self, chat_id: str) -> bool:
@ -175,7 +175,7 @@ class ChatTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False
def update_chat_share_id_by_id( def update_chat_share_id_by_id(
@ -189,7 +189,7 @@ class ChatTable:
db.commit() db.commit()
db.refresh(chat) db.refresh(chat)
return ChatModel.model_validate(chat) return ChatModel.model_validate(chat)
except: except Exception:
return None return None
def toggle_chat_archive_by_id(self, id: str) -> Optional[ChatModel]: def toggle_chat_archive_by_id(self, id: str) -> Optional[ChatModel]:
@ -201,7 +201,7 @@ class ChatTable:
db.commit() db.commit()
db.refresh(chat) db.refresh(chat)
return ChatModel.model_validate(chat) return ChatModel.model_validate(chat)
except: except Exception:
return None return None
def archive_all_chats_by_user_id(self, user_id: str) -> bool: def archive_all_chats_by_user_id(self, user_id: str) -> bool:
@ -210,12 +210,12 @@ class ChatTable:
db.query(Chat).filter_by(user_id=user_id).update({"archived": True}) db.query(Chat).filter_by(user_id=user_id).update({"archived": True})
db.commit() db.commit()
return True return True
except: except Exception:
return False return False
def get_archived_chat_list_by_user_id( def get_archived_chat_list_by_user_id(
self, user_id: str, skip: int = 0, limit: int = 50 self, user_id: str, skip: int = 0, limit: int = 50
) -> List[ChatModel]: ) -> list[ChatModel]:
with get_db() as db: with get_db() as db:
all_chats = ( all_chats = (
@ -233,7 +233,7 @@ class ChatTable:
include_archived: bool = False, include_archived: bool = False,
skip: int = 0, skip: int = 0,
limit: int = 50, limit: int = 50,
) -> List[ChatModel]: ) -> list[ChatModel]:
with get_db() as db: with get_db() as db:
query = db.query(Chat).filter_by(user_id=user_id) query = db.query(Chat).filter_by(user_id=user_id)
if not include_archived: if not include_archived:
@ -251,7 +251,7 @@ class ChatTable:
include_archived: bool = False, include_archived: bool = False,
skip: int = 0, skip: int = 0,
limit: int = -1, limit: int = -1,
) -> List[ChatTitleIdResponse]: ) -> list[ChatTitleIdResponse]:
with get_db() as db: with get_db() as db:
query = db.query(Chat).filter_by(user_id=user_id) query = db.query(Chat).filter_by(user_id=user_id)
if not include_archived: if not include_archived:
@ -279,8 +279,8 @@ class ChatTable:
] ]
def get_chat_list_by_chat_ids( def get_chat_list_by_chat_ids(
self, chat_ids: List[str], skip: int = 0, limit: int = 50 self, chat_ids: list[str], skip: int = 0, limit: int = 50
) -> List[ChatModel]: ) -> list[ChatModel]:
with get_db() as db: with get_db() as db:
all_chats = ( all_chats = (
db.query(Chat) db.query(Chat)
@ -297,7 +297,7 @@ class ChatTable:
chat = db.get(Chat, id) chat = db.get(Chat, id)
return ChatModel.model_validate(chat) return ChatModel.model_validate(chat)
except: except Exception:
return None return None
def get_chat_by_share_id(self, id: str) -> Optional[ChatModel]: def get_chat_by_share_id(self, id: str) -> Optional[ChatModel]:
@ -319,10 +319,10 @@ class ChatTable:
chat = db.query(Chat).filter_by(id=id, user_id=user_id).first() chat = db.query(Chat).filter_by(id=id, user_id=user_id).first()
return ChatModel.model_validate(chat) return ChatModel.model_validate(chat)
except: except Exception:
return None return None
def get_chats(self, skip: int = 0, limit: int = 50) -> List[ChatModel]: def get_chats(self, skip: int = 0, limit: int = 50) -> list[ChatModel]:
with get_db() as db: with get_db() as db:
all_chats = ( all_chats = (
@ -332,7 +332,7 @@ class ChatTable:
) )
return [ChatModel.model_validate(chat) for chat in all_chats] return [ChatModel.model_validate(chat) for chat in all_chats]
def get_chats_by_user_id(self, user_id: str) -> List[ChatModel]: def get_chats_by_user_id(self, user_id: str) -> list[ChatModel]:
with get_db() as db: with get_db() as db:
all_chats = ( all_chats = (
@ -342,7 +342,7 @@ class ChatTable:
) )
return [ChatModel.model_validate(chat) for chat in all_chats] return [ChatModel.model_validate(chat) for chat in all_chats]
def get_archived_chats_by_user_id(self, user_id: str) -> List[ChatModel]: def get_archived_chats_by_user_id(self, user_id: str) -> list[ChatModel]:
with get_db() as db: with get_db() as db:
all_chats = ( all_chats = (
@ -360,7 +360,7 @@ class ChatTable:
db.commit() db.commit()
return True and self.delete_shared_chat_by_chat_id(id) return True and self.delete_shared_chat_by_chat_id(id)
except: except Exception:
return False return False
def delete_chat_by_id_and_user_id(self, id: str, user_id: str) -> bool: def delete_chat_by_id_and_user_id(self, id: str, user_id: str) -> bool:
@ -371,7 +371,7 @@ class ChatTable:
db.commit() db.commit()
return True and self.delete_shared_chat_by_chat_id(id) return True and self.delete_shared_chat_by_chat_id(id)
except: except Exception:
return False return False
def delete_chats_by_user_id(self, user_id: str) -> bool: def delete_chats_by_user_id(self, user_id: str) -> bool:
@ -385,7 +385,7 @@ class ChatTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False
def delete_shared_chats_by_user_id(self, user_id: str) -> bool: def delete_shared_chats_by_user_id(self, user_id: str) -> bool:
@ -400,7 +400,7 @@ class ChatTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Optional from typing import Optional
import time import time
import logging import logging
@ -93,7 +93,7 @@ class DocumentsTable:
return DocumentModel.model_validate(result) return DocumentModel.model_validate(result)
else: else:
return None return None
except: except Exception:
return None return None
def get_doc_by_name(self, name: str) -> Optional[DocumentModel]: def get_doc_by_name(self, name: str) -> Optional[DocumentModel]:
@ -102,10 +102,10 @@ class DocumentsTable:
document = db.query(Document).filter_by(name=name).first() document = db.query(Document).filter_by(name=name).first()
return DocumentModel.model_validate(document) if document else None return DocumentModel.model_validate(document) if document else None
except: except Exception:
return None return None
def get_docs(self) -> List[DocumentModel]: def get_docs(self) -> list[DocumentModel]:
with get_db() as db: with get_db() as db:
return [ return [
@ -160,7 +160,7 @@ class DocumentsTable:
db.query(Document).filter_by(name=name).delete() db.query(Document).filter_by(name=name).delete()
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Union, Optional from typing import Union, Optional
import time import time
import logging import logging
@ -90,10 +90,10 @@ class FilesTable:
try: try:
file = db.get(File, id) file = db.get(File, id)
return FileModel.model_validate(file) return FileModel.model_validate(file)
except: except Exception:
return None return None
def get_files(self) -> List[FileModel]: def get_files(self) -> list[FileModel]:
with get_db() as db: with get_db() as db:
return [FileModel.model_validate(file) for file in db.query(File).all()] return [FileModel.model_validate(file) for file in db.query(File).all()]
@ -107,7 +107,7 @@ class FilesTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False
def delete_all_files(self) -> bool: def delete_all_files(self) -> bool:
@ -119,7 +119,7 @@ class FilesTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Union, Optional from typing import Union, Optional
import time import time
import logging import logging
@ -122,10 +122,10 @@ class FunctionsTable:
function = db.get(Function, id) function = db.get(Function, id)
return FunctionModel.model_validate(function) return FunctionModel.model_validate(function)
except: except Exception:
return None return None
def get_functions(self, active_only=False) -> List[FunctionModel]: def get_functions(self, active_only=False) -> list[FunctionModel]:
with get_db() as db: with get_db() as db:
if active_only: if active_only:
@ -141,7 +141,7 @@ class FunctionsTable:
def get_functions_by_type( def get_functions_by_type(
self, type: str, active_only=False self, type: str, active_only=False
) -> List[FunctionModel]: ) -> list[FunctionModel]:
with get_db() as db: with get_db() as db:
if active_only: if active_only:
@ -157,7 +157,7 @@ class FunctionsTable:
for function in db.query(Function).filter_by(type=type).all() for function in db.query(Function).filter_by(type=type).all()
] ]
def get_global_filter_functions(self) -> List[FunctionModel]: def get_global_filter_functions(self) -> list[FunctionModel]:
with get_db() as db: with get_db() as db:
return [ return [
@ -167,7 +167,7 @@ class FunctionsTable:
.all() .all()
] ]
def get_global_action_functions(self) -> List[FunctionModel]: def get_global_action_functions(self) -> list[FunctionModel]:
with get_db() as db: with get_db() as db:
return [ return [
FunctionModel.model_validate(function) FunctionModel.model_validate(function)
@ -198,7 +198,7 @@ class FunctionsTable:
db.commit() db.commit()
db.refresh(function) db.refresh(function)
return self.get_function_by_id(id) return self.get_function_by_id(id)
except: except Exception:
return None return None
def get_user_valves_by_id_and_user_id( def get_user_valves_by_id_and_user_id(
@ -256,7 +256,7 @@ class FunctionsTable:
) )
db.commit() db.commit()
return self.get_function_by_id(id) return self.get_function_by_id(id)
except: except Exception:
return None return None
def deactivate_all_functions(self) -> Optional[bool]: def deactivate_all_functions(self) -> Optional[bool]:
@ -271,7 +271,7 @@ class FunctionsTable:
) )
db.commit() db.commit()
return True return True
except: except Exception:
return None return None
def delete_function_by_id(self, id: str) -> bool: def delete_function_by_id(self, id: str) -> bool:
@ -281,7 +281,7 @@ class FunctionsTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Union, Optional from typing import Union, Optional
from sqlalchemy import Column, String, BigInteger, Text from sqlalchemy import Column, String, BigInteger, Text
@ -80,25 +80,25 @@ class MemoriesTable:
) )
db.commit() db.commit()
return self.get_memory_by_id(id) return self.get_memory_by_id(id)
except: except Exception:
return None return None
def get_memories(self) -> List[MemoryModel]: def get_memories(self) -> list[MemoryModel]:
with get_db() as db: with get_db() as db:
try: try:
memories = db.query(Memory).all() memories = db.query(Memory).all()
return [MemoryModel.model_validate(memory) for memory in memories] return [MemoryModel.model_validate(memory) for memory in memories]
except: except Exception:
return None return None
def get_memories_by_user_id(self, user_id: str) -> List[MemoryModel]: def get_memories_by_user_id(self, user_id: str) -> list[MemoryModel]:
with get_db() as db: with get_db() as db:
try: try:
memories = db.query(Memory).filter_by(user_id=user_id).all() memories = db.query(Memory).filter_by(user_id=user_id).all()
return [MemoryModel.model_validate(memory) for memory in memories] return [MemoryModel.model_validate(memory) for memory in memories]
except: except Exception:
return None return None
def get_memory_by_id(self, id: str) -> Optional[MemoryModel]: def get_memory_by_id(self, id: str) -> Optional[MemoryModel]:
@ -107,7 +107,7 @@ class MemoriesTable:
try: try:
memory = db.get(Memory, id) memory = db.get(Memory, id)
return MemoryModel.model_validate(memory) return MemoryModel.model_validate(memory)
except: except Exception:
return None return None
def delete_memory_by_id(self, id: str) -> bool: def delete_memory_by_id(self, id: str) -> bool:
@ -119,7 +119,7 @@ class MemoriesTable:
return True return True
except: except Exception:
return False return False
def delete_memories_by_user_id(self, user_id: str) -> bool: def delete_memories_by_user_id(self, user_id: str) -> bool:
@ -130,7 +130,7 @@ class MemoriesTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False
def delete_memory_by_id_and_user_id(self, id: str, user_id: str) -> bool: def delete_memory_by_id_and_user_id(self, id: str, user_id: str) -> bool:
@ -141,7 +141,7 @@ class MemoriesTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -137,7 +137,7 @@ class ModelsTable:
print(e) print(e)
return None return None
def get_all_models(self) -> List[ModelModel]: def get_all_models(self) -> list[ModelModel]:
with get_db() as db: with get_db() as db:
return [ModelModel.model_validate(model) for model in db.query(Model).all()] return [ModelModel.model_validate(model) for model in db.query(Model).all()]
@ -146,7 +146,7 @@ class ModelsTable:
with get_db() as db: with get_db() as db:
model = db.get(Model, id) model = db.get(Model, id)
return ModelModel.model_validate(model) return ModelModel.model_validate(model)
except: except Exception:
return None return None
def update_model_by_id(self, id: str, model: ModelForm) -> Optional[ModelModel]: def update_model_by_id(self, id: str, model: ModelForm) -> Optional[ModelModel]:
@ -175,7 +175,7 @@ class ModelsTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Optional from typing import Optional
import time import time
from sqlalchemy import String, Column, BigInteger, Text from sqlalchemy import String, Column, BigInteger, Text
@ -79,10 +79,10 @@ class PromptsTable:
prompt = db.query(Prompt).filter_by(command=command).first() prompt = db.query(Prompt).filter_by(command=command).first()
return PromptModel.model_validate(prompt) return PromptModel.model_validate(prompt)
except: except Exception:
return None return None
def get_prompts(self) -> List[PromptModel]: def get_prompts(self) -> list[PromptModel]:
with get_db() as db: with get_db() as db:
return [ return [
@ -101,7 +101,7 @@ class PromptsTable:
prompt.timestamp = int(time.time()) prompt.timestamp = int(time.time())
db.commit() db.commit()
return PromptModel.model_validate(prompt) return PromptModel.model_validate(prompt)
except: except Exception:
return None return None
def delete_prompt_by_command(self, command: str) -> bool: def delete_prompt_by_command(self, command: str) -> bool:
@ -112,7 +112,7 @@ class PromptsTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Optional from typing import Optional
import json import json
import uuid import uuid
@ -69,11 +69,11 @@ class ChatIdTagForm(BaseModel):
class TagChatIdsResponse(BaseModel): class TagChatIdsResponse(BaseModel):
chat_ids: List[str] chat_ids: list[str]
class ChatTagsResponse(BaseModel): class ChatTagsResponse(BaseModel):
tags: List[str] tags: list[str]
class TagTable: class TagTable:
@ -109,7 +109,7 @@ class TagTable:
self, user_id: str, form_data: ChatIdTagForm self, user_id: str, form_data: ChatIdTagForm
) -> Optional[ChatIdTagModel]: ) -> Optional[ChatIdTagModel]:
tag = self.get_tag_by_name_and_user_id(form_data.tag_name, user_id) tag = self.get_tag_by_name_and_user_id(form_data.tag_name, user_id)
if tag == None: if tag is None:
tag = self.insert_new_tag(form_data.tag_name, user_id) tag = self.insert_new_tag(form_data.tag_name, user_id)
id = str(uuid.uuid4()) id = str(uuid.uuid4())
@ -132,10 +132,10 @@ class TagTable:
return ChatIdTagModel.model_validate(result) return ChatIdTagModel.model_validate(result)
else: else:
return None return None
except: except Exception:
return None return None
def get_tags_by_user_id(self, user_id: str) -> List[TagModel]: def get_tags_by_user_id(self, user_id: str) -> list[TagModel]:
with get_db() as db: with get_db() as db:
tag_names = [ tag_names = [
chat_id_tag.tag_name chat_id_tag.tag_name
@ -159,7 +159,7 @@ class TagTable:
def get_tags_by_chat_id_and_user_id( def get_tags_by_chat_id_and_user_id(
self, chat_id: str, user_id: str self, chat_id: str, user_id: str
) -> List[TagModel]: ) -> list[TagModel]:
with get_db() as db: with get_db() as db:
tag_names = [ tag_names = [
@ -184,7 +184,7 @@ class TagTable:
def get_chat_ids_by_tag_name_and_user_id( def get_chat_ids_by_tag_name_and_user_id(
self, tag_name: str, user_id: str self, tag_name: str, user_id: str
) -> List[ChatIdTagModel]: ) -> list[ChatIdTagModel]:
with get_db() as db: with get_db() as db:
return [ return [

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict from pydantic import BaseModel, ConfigDict
from typing import List, Optional from typing import Optional
import time import time
import logging import logging
from sqlalchemy import String, Column, BigInteger, Text from sqlalchemy import String, Column, BigInteger, Text
@ -45,7 +45,7 @@ class ToolModel(BaseModel):
user_id: str user_id: str
name: str name: str
content: str content: str
specs: List[dict] specs: list[dict]
meta: ToolMeta meta: ToolMeta
updated_at: int # timestamp in epoch updated_at: int # timestamp in epoch
created_at: int # timestamp in epoch created_at: int # timestamp in epoch
@ -81,7 +81,7 @@ class ToolValves(BaseModel):
class ToolsTable: class ToolsTable:
def insert_new_tool( def insert_new_tool(
self, user_id: str, form_data: ToolForm, specs: List[dict] self, user_id: str, form_data: ToolForm, specs: list[dict]
) -> Optional[ToolModel]: ) -> Optional[ToolModel]:
with get_db() as db: with get_db() as db:
@ -115,10 +115,10 @@ class ToolsTable:
tool = db.get(Tool, id) tool = db.get(Tool, id)
return ToolModel.model_validate(tool) return ToolModel.model_validate(tool)
except: except Exception:
return None return None
def get_tools(self) -> List[ToolModel]: def get_tools(self) -> list[ToolModel]:
with get_db() as db: with get_db() as db:
return [ToolModel.model_validate(tool) for tool in db.query(Tool).all()] return [ToolModel.model_validate(tool) for tool in db.query(Tool).all()]
@ -141,7 +141,7 @@ class ToolsTable:
) )
db.commit() db.commit()
return self.get_tool_by_id(id) return self.get_tool_by_id(id)
except: except Exception:
return None return None
def get_user_valves_by_id_and_user_id( def get_user_valves_by_id_and_user_id(
@ -196,7 +196,7 @@ class ToolsTable:
tool = db.query(Tool).get(id) tool = db.query(Tool).get(id)
db.refresh(tool) db.refresh(tool)
return ToolModel.model_validate(tool) return ToolModel.model_validate(tool)
except: except Exception:
return None return None
def delete_tool_by_id(self, id: str) -> bool: def delete_tool_by_id(self, id: str) -> bool:
@ -206,7 +206,7 @@ class ToolsTable:
db.commit() db.commit()
return True return True
except: except Exception:
return False return False

View File

@ -1,5 +1,5 @@
from pydantic import BaseModel, ConfigDict, parse_obj_as from pydantic import BaseModel, ConfigDict, parse_obj_as
from typing import List, Union, Optional from typing import Union, Optional
import time import time
from sqlalchemy import String, Column, BigInteger, Text from sqlalchemy import String, Column, BigInteger, Text
@ -125,7 +125,7 @@ class UsersTable:
user = db.query(User).filter_by(api_key=api_key).first() user = db.query(User).filter_by(api_key=api_key).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def get_user_by_email(self, email: str) -> Optional[UserModel]: def get_user_by_email(self, email: str) -> Optional[UserModel]:
@ -134,7 +134,7 @@ class UsersTable:
user = db.query(User).filter_by(email=email).first() user = db.query(User).filter_by(email=email).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def get_user_by_oauth_sub(self, sub: str) -> Optional[UserModel]: def get_user_by_oauth_sub(self, sub: str) -> Optional[UserModel]:
@ -143,10 +143,10 @@ class UsersTable:
user = db.query(User).filter_by(oauth_sub=sub).first() user = db.query(User).filter_by(oauth_sub=sub).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def get_users(self, skip: int = 0, limit: int = 50) -> List[UserModel]: def get_users(self, skip: int = 0, limit: int = 50) -> list[UserModel]:
with get_db() as db: with get_db() as db:
users = ( users = (
db.query(User) db.query(User)
@ -164,7 +164,7 @@ class UsersTable:
with get_db() as db: with get_db() as db:
user = db.query(User).order_by(User.created_at).first() user = db.query(User).order_by(User.created_at).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def update_user_role_by_id(self, id: str, role: str) -> Optional[UserModel]: def update_user_role_by_id(self, id: str, role: str) -> Optional[UserModel]:
@ -174,7 +174,7 @@ class UsersTable:
db.commit() db.commit()
user = db.query(User).filter_by(id=id).first() user = db.query(User).filter_by(id=id).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def update_user_profile_image_url_by_id( def update_user_profile_image_url_by_id(
@ -189,7 +189,7 @@ class UsersTable:
user = db.query(User).filter_by(id=id).first() user = db.query(User).filter_by(id=id).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def update_user_last_active_by_id(self, id: str) -> Optional[UserModel]: def update_user_last_active_by_id(self, id: str) -> Optional[UserModel]:
@ -203,7 +203,7 @@ class UsersTable:
user = db.query(User).filter_by(id=id).first() user = db.query(User).filter_by(id=id).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def update_user_oauth_sub_by_id( def update_user_oauth_sub_by_id(
@ -216,7 +216,7 @@ class UsersTable:
user = db.query(User).filter_by(id=id).first() user = db.query(User).filter_by(id=id).first()
return UserModel.model_validate(user) return UserModel.model_validate(user)
except: except Exception:
return None return None
def update_user_by_id(self, id: str, updated: dict) -> Optional[UserModel]: def update_user_by_id(self, id: str, updated: dict) -> Optional[UserModel]:
@ -245,7 +245,7 @@ class UsersTable:
return True return True
else: else:
return False return False
except: except Exception:
return False return False
def update_user_api_key_by_id(self, id: str, api_key: str) -> str: def update_user_api_key_by_id(self, id: str, api_key: str) -> str:
@ -254,7 +254,7 @@ class UsersTable:
result = db.query(User).filter_by(id=id).update({"api_key": api_key}) result = db.query(User).filter_by(id=id).update({"api_key": api_key})
db.commit() db.commit()
return True if result == 1 else False return True if result == 1 else False
except: except Exception:
return False return False
def get_user_api_key_by_id(self, id: str) -> Optional[str]: def get_user_api_key_by_id(self, id: str) -> Optional[str]:

View File

@ -1,6 +1,6 @@
from fastapi import Depends, Request, HTTPException, status from fastapi import Depends, Request, HTTPException, status
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from utils.utils import get_verified_user, get_admin_user from utils.utils import get_verified_user, get_admin_user
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -40,8 +40,8 @@ router = APIRouter()
############################ ############################
@router.get("/", response_model=List[ChatTitleIdResponse]) @router.get("/", response_model=list[ChatTitleIdResponse])
@router.get("/list", response_model=List[ChatTitleIdResponse]) @router.get("/list", response_model=list[ChatTitleIdResponse])
async def get_session_user_chat_list( async def get_session_user_chat_list(
user=Depends(get_verified_user), page: Optional[int] = None user=Depends(get_verified_user), page: Optional[int] = None
): ):
@ -80,7 +80,7 @@ async def delete_all_user_chats(request: Request, user=Depends(get_verified_user
############################ ############################
@router.get("/list/user/{user_id}", response_model=List[ChatTitleIdResponse]) @router.get("/list/user/{user_id}", response_model=list[ChatTitleIdResponse])
async def get_user_chat_list_by_user_id( async def get_user_chat_list_by_user_id(
user_id: str, user_id: str,
user=Depends(get_admin_user), user=Depends(get_admin_user),
@ -119,7 +119,7 @@ async def create_new_chat(form_data: ChatForm, user=Depends(get_verified_user)):
############################ ############################
@router.get("/all", response_model=List[ChatResponse]) @router.get("/all", response_model=list[ChatResponse])
async def get_user_chats(user=Depends(get_verified_user)): async def get_user_chats(user=Depends(get_verified_user)):
return [ return [
ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)}) ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)})
@ -132,7 +132,7 @@ async def get_user_chats(user=Depends(get_verified_user)):
############################ ############################
@router.get("/all/archived", response_model=List[ChatResponse]) @router.get("/all/archived", response_model=list[ChatResponse])
async def get_user_archived_chats(user=Depends(get_verified_user)): async def get_user_archived_chats(user=Depends(get_verified_user)):
return [ return [
ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)}) ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)})
@ -145,7 +145,7 @@ async def get_user_archived_chats(user=Depends(get_verified_user)):
############################ ############################
@router.get("/all/db", response_model=List[ChatResponse]) @router.get("/all/db", response_model=list[ChatResponse])
async def get_all_user_chats_in_db(user=Depends(get_admin_user)): async def get_all_user_chats_in_db(user=Depends(get_admin_user)):
if not ENABLE_ADMIN_EXPORT: if not ENABLE_ADMIN_EXPORT:
raise HTTPException( raise HTTPException(
@ -163,7 +163,7 @@ async def get_all_user_chats_in_db(user=Depends(get_admin_user)):
############################ ############################
@router.get("/archived", response_model=List[ChatTitleIdResponse]) @router.get("/archived", response_model=list[ChatTitleIdResponse])
async def get_archived_session_user_chat_list( async def get_archived_session_user_chat_list(
user=Depends(get_verified_user), skip: int = 0, limit: int = 50 user=Depends(get_verified_user), skip: int = 0, limit: int = 50
): ):
@ -216,7 +216,7 @@ class TagNameForm(BaseModel):
limit: Optional[int] = 50 limit: Optional[int] = 50
@router.post("/tags", response_model=List[ChatTitleIdResponse]) @router.post("/tags", response_model=list[ChatTitleIdResponse])
async def get_user_chat_list_by_tag_name( async def get_user_chat_list_by_tag_name(
form_data: TagNameForm, user=Depends(get_verified_user) form_data: TagNameForm, user=Depends(get_verified_user)
): ):
@ -241,7 +241,7 @@ async def get_user_chat_list_by_tag_name(
############################ ############################
@router.get("/tags/all", response_model=List[TagModel]) @router.get("/tags/all", response_model=list[TagModel])
async def get_all_tags(user=Depends(get_verified_user)): async def get_all_tags(user=Depends(get_verified_user)):
try: try:
tags = Tags.get_tags_by_user_id(user.id) tags = Tags.get_tags_by_user_id(user.id)
@ -417,7 +417,7 @@ async def delete_shared_chat_by_id(id: str, user=Depends(get_verified_user)):
############################ ############################
@router.get("/{id}/tags", response_model=List[TagModel]) @router.get("/{id}/tags", response_model=list[TagModel])
async def get_chat_tags_by_id(id: str, user=Depends(get_verified_user)): async def get_chat_tags_by_id(id: str, user=Depends(get_verified_user)):
tags = Tags.get_tags_by_chat_id_and_user_id(id, user.id) tags = Tags.get_tags_by_chat_id_and_user_id(id, user.id)

View File

@ -1,7 +1,7 @@
from fastapi import Response, Request from fastapi import Response, Request
from fastapi import Depends, FastAPI, HTTPException, status from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union from typing import Union
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -29,12 +29,12 @@ class SetDefaultModelsForm(BaseModel):
class PromptSuggestion(BaseModel): class PromptSuggestion(BaseModel):
title: List[str] title: list[str]
content: str content: str
class SetDefaultSuggestionsForm(BaseModel): class SetDefaultSuggestionsForm(BaseModel):
suggestions: List[PromptSuggestion] suggestions: list[PromptSuggestion]
############################ ############################
@ -50,7 +50,7 @@ async def set_global_default_models(
return request.app.state.config.DEFAULT_MODELS return request.app.state.config.DEFAULT_MODELS
@router.post("/default/suggestions", response_model=List[PromptSuggestion]) @router.post("/default/suggestions", response_model=list[PromptSuggestion])
async def set_global_default_suggestions( async def set_global_default_suggestions(
request: Request, request: Request,
form_data: SetDefaultSuggestionsForm, form_data: SetDefaultSuggestionsForm,
@ -67,10 +67,10 @@ async def set_global_default_suggestions(
class SetBannersForm(BaseModel): class SetBannersForm(BaseModel):
banners: List[BannerModel] banners: list[BannerModel]
@router.post("/banners", response_model=List[BannerModel]) @router.post("/banners", response_model=list[BannerModel])
async def set_banners( async def set_banners(
request: Request, request: Request,
form_data: SetBannersForm, form_data: SetBannersForm,
@ -81,7 +81,7 @@ async def set_banners(
return request.app.state.config.BANNERS return request.app.state.config.BANNERS
@router.get("/banners", response_model=List[BannerModel]) @router.get("/banners", response_model=list[BannerModel])
async def get_banners( async def get_banners(
request: Request, request: Request,
user=Depends(get_verified_user), user=Depends(get_verified_user),

View File

@ -1,6 +1,6 @@
from fastapi import Depends, FastAPI, HTTPException, status from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -24,7 +24,7 @@ router = APIRouter()
############################ ############################
@router.get("/", response_model=List[DocumentResponse]) @router.get("/", response_model=list[DocumentResponse])
async def get_documents(user=Depends(get_verified_user)): async def get_documents(user=Depends(get_verified_user)):
docs = [ docs = [
DocumentResponse( DocumentResponse(
@ -46,7 +46,7 @@ async def get_documents(user=Depends(get_verified_user)):
@router.post("/create", response_model=Optional[DocumentResponse]) @router.post("/create", response_model=Optional[DocumentResponse])
async def create_new_doc(form_data: DocumentForm, user=Depends(get_admin_user)): async def create_new_doc(form_data: DocumentForm, user=Depends(get_admin_user)):
doc = Documents.get_doc_by_name(form_data.name) doc = Documents.get_doc_by_name(form_data.name)
if doc == None: if doc is None:
doc = Documents.insert_new_doc(user.id, form_data) doc = Documents.insert_new_doc(user.id, form_data)
if doc: if doc:
@ -102,7 +102,7 @@ class TagItem(BaseModel):
class TagDocumentForm(BaseModel): class TagDocumentForm(BaseModel):
name: str name: str
tags: List[dict] tags: list[dict]
@router.post("/doc/tags", response_model=Optional[DocumentResponse]) @router.post("/doc/tags", response_model=Optional[DocumentResponse])

View File

@ -11,7 +11,7 @@ from fastapi import (
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from pathlib import Path from pathlib import Path
from fastapi import APIRouter from fastapi import APIRouter
@ -104,7 +104,7 @@ def upload_file(file: UploadFile = File(...), user=Depends(get_verified_user)):
############################ ############################
@router.get("/", response_model=List[FileModel]) @router.get("/", response_model=list[FileModel])
async def list_files(user=Depends(get_verified_user)): async def list_files(user=Depends(get_verified_user)):
files = Files.get_files() files = Files.get_files()
return files return files

View File

@ -1,6 +1,6 @@
from fastapi import Depends, FastAPI, HTTPException, status, Request from fastapi import Depends, FastAPI, HTTPException, status, Request
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -30,7 +30,7 @@ router = APIRouter()
############################ ############################
@router.get("/", response_model=List[FunctionResponse]) @router.get("/", response_model=list[FunctionResponse])
async def get_functions(user=Depends(get_verified_user)): async def get_functions(user=Depends(get_verified_user)):
return Functions.get_functions() return Functions.get_functions()
@ -40,7 +40,7 @@ async def get_functions(user=Depends(get_verified_user)):
############################ ############################
@router.get("/export", response_model=List[FunctionModel]) @router.get("/export", response_model=list[FunctionModel])
async def get_functions(user=Depends(get_admin_user)): async def get_functions(user=Depends(get_admin_user)):
return Functions.get_functions() return Functions.get_functions()
@ -63,7 +63,7 @@ async def create_new_function(
form_data.id = form_data.id.lower() form_data.id = form_data.id.lower()
function = Functions.get_function_by_id(form_data.id) function = Functions.get_function_by_id(form_data.id)
if function == None: if function is None:
function_path = os.path.join(FUNCTIONS_DIR, f"{form_data.id}.py") function_path = os.path.join(FUNCTIONS_DIR, f"{form_data.id}.py")
try: try:
with open(function_path, "w") as function_file: with open(function_path, "w") as function_file:
@ -235,7 +235,7 @@ async def delete_function_by_id(
function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py") function_path = os.path.join(FUNCTIONS_DIR, f"{id}.py")
try: try:
os.remove(function_path) os.remove(function_path)
except: except Exception:
pass pass
return result return result

View File

@ -1,7 +1,7 @@
from fastapi import Response, Request from fastapi import Response, Request
from fastapi import Depends, FastAPI, HTTPException, status from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -30,7 +30,7 @@ async def get_embeddings(request: Request):
############################ ############################
@router.get("/", response_model=List[MemoryModel]) @router.get("/", response_model=list[MemoryModel])
async def get_memories(user=Depends(get_verified_user)): async def get_memories(user=Depends(get_verified_user)):
return Memories.get_memories_by_user_id(user.id) return Memories.get_memories_by_user_id(user.id)

View File

@ -1,6 +1,6 @@
from fastapi import Depends, FastAPI, HTTPException, status, Request from fastapi import Depends, FastAPI, HTTPException, status, Request
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -18,7 +18,7 @@ router = APIRouter()
########################### ###########################
@router.get("/", response_model=List[ModelResponse]) @router.get("/", response_model=list[ModelResponse])
async def get_models(user=Depends(get_verified_user)): async def get_models(user=Depends(get_verified_user)):
return Models.get_all_models() return Models.get_all_models()

View File

@ -1,6 +1,6 @@
from fastapi import Depends, FastAPI, HTTPException, status from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -18,7 +18,7 @@ router = APIRouter()
############################ ############################
@router.get("/", response_model=List[PromptModel]) @router.get("/", response_model=list[PromptModel])
async def get_prompts(user=Depends(get_verified_user)): async def get_prompts(user=Depends(get_verified_user)):
return Prompts.get_prompts() return Prompts.get_prompts()
@ -31,7 +31,7 @@ async def get_prompts(user=Depends(get_verified_user)):
@router.post("/create", response_model=Optional[PromptModel]) @router.post("/create", response_model=Optional[PromptModel])
async def create_new_prompt(form_data: PromptForm, user=Depends(get_admin_user)): async def create_new_prompt(form_data: PromptForm, user=Depends(get_admin_user)):
prompt = Prompts.get_prompt_by_command(form_data.command) prompt = Prompts.get_prompt_by_command(form_data.command)
if prompt == None: if prompt is None:
prompt = Prompts.insert_new_prompt(user.id, form_data) prompt = Prompts.insert_new_prompt(user.id, form_data)
if prompt: if prompt:

View File

@ -1,5 +1,5 @@
from fastapi import Depends, HTTPException, status, Request from fastapi import Depends, HTTPException, status, Request
from typing import List, Optional from typing import Optional
from fastapi import APIRouter from fastapi import APIRouter
@ -27,7 +27,7 @@ router = APIRouter()
############################ ############################
@router.get("/", response_model=List[ToolResponse]) @router.get("/", response_model=list[ToolResponse])
async def get_toolkits(user=Depends(get_verified_user)): async def get_toolkits(user=Depends(get_verified_user)):
toolkits = [toolkit for toolkit in Tools.get_tools()] toolkits = [toolkit for toolkit in Tools.get_tools()]
return toolkits return toolkits
@ -38,7 +38,7 @@ async def get_toolkits(user=Depends(get_verified_user)):
############################ ############################
@router.get("/export", response_model=List[ToolModel]) @router.get("/export", response_model=list[ToolModel])
async def get_toolkits(user=Depends(get_admin_user)): async def get_toolkits(user=Depends(get_admin_user)):
toolkits = [toolkit for toolkit in Tools.get_tools()] toolkits = [toolkit for toolkit in Tools.get_tools()]
return toolkits return toolkits

View File

@ -1,7 +1,7 @@
from fastapi import Response, Request from fastapi import Response, Request
from fastapi import Depends, FastAPI, HTTPException, status from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import List, Union, Optional from typing import Union, Optional
from fastapi import APIRouter from fastapi import APIRouter
from pydantic import BaseModel from pydantic import BaseModel
@ -39,7 +39,7 @@ router = APIRouter()
############################ ############################
@router.get("/", response_model=List[UserModel]) @router.get("/", response_model=list[UserModel])
async def get_users(skip: int = 0, limit: int = 50, user=Depends(get_admin_user)): async def get_users(skip: int = 0, limit: int = 50, user=Depends(get_admin_user)):
return Users.get_users(skip, limit) return Users.get_users(skip, limit)

View File

@ -17,7 +17,7 @@ from utils.misc import calculate_sha256, get_gravatar_url
from config import OLLAMA_BASE_URLS, DATA_DIR, UPLOAD_DIR, ENABLE_ADMIN_EXPORT from config import OLLAMA_BASE_URLS, DATA_DIR, UPLOAD_DIR, ENABLE_ADMIN_EXPORT
from constants import ERROR_MESSAGES from constants import ERROR_MESSAGES
from typing import List
router = APIRouter() router = APIRouter()
@ -57,7 +57,7 @@ async def get_html_from_markdown(
class ChatForm(BaseModel): class ChatForm(BaseModel):
title: str title: str
messages: List[dict] messages: list[dict]
@router.post("/pdf") @router.post("/pdf")

View File

@ -93,11 +93,12 @@ def load_function_module_by_id(function_id):
os.rename(function_path, f"{function_path}.error") os.rename(function_path, f"{function_path}.error")
raise e raise e
def install_frontmatter_requirements(requirements): def install_frontmatter_requirements(requirements):
if requirements: if requirements:
req_list = [req.strip() for req in requirements.split(',')] req_list = [req.strip() for req in requirements.split(",")]
for req in req_list: for req in req_list:
print(f"Installing requirement: {req}") print(f"Installing requirement: {req}")
subprocess.check_call([sys.executable, "-m", "pip", "install", req]) subprocess.check_call([sys.executable, "-m", "pip", "install", req])
else: else:
print("No requirements found in frontmatter.") print("No requirements found in frontmatter.")

View File

@ -104,7 +104,7 @@ ENV = os.environ.get("ENV", "dev")
try: try:
PACKAGE_DATA = json.loads((BASE_DIR / "package.json").read_text()) PACKAGE_DATA = json.loads((BASE_DIR / "package.json").read_text())
except: except Exception:
try: try:
PACKAGE_DATA = {"version": importlib.metadata.version("open-webui")} PACKAGE_DATA = {"version": importlib.metadata.version("open-webui")}
except importlib.metadata.PackageNotFoundError: except importlib.metadata.PackageNotFoundError:
@ -137,7 +137,7 @@ try:
with open(str(changelog_path.absolute()), "r", encoding="utf8") as file: with open(str(changelog_path.absolute()), "r", encoding="utf8") as file:
changelog_content = file.read() changelog_content = file.read()
except: except Exception:
changelog_content = (pkgutil.get_data("open_webui", "CHANGELOG.md") or b"").decode() changelog_content = (pkgutil.get_data("open_webui", "CHANGELOG.md") or b"").decode()
@ -202,12 +202,12 @@ if RESET_CONFIG_ON_START:
os.remove(f"{DATA_DIR}/config.json") os.remove(f"{DATA_DIR}/config.json")
with open(f"{DATA_DIR}/config.json", "w") as f: with open(f"{DATA_DIR}/config.json", "w") as f:
f.write("{}") f.write("{}")
except: except Exception:
pass pass
try: try:
CONFIG_DATA = json.loads((DATA_DIR / "config.json").read_text()) CONFIG_DATA = json.loads((DATA_DIR / "config.json").read_text())
except: except Exception:
CONFIG_DATA = {} CONFIG_DATA = {}
@ -647,7 +647,7 @@ if AIOHTTP_CLIENT_TIMEOUT == "":
else: else:
try: try:
AIOHTTP_CLIENT_TIMEOUT = int(AIOHTTP_CLIENT_TIMEOUT) AIOHTTP_CLIENT_TIMEOUT = int(AIOHTTP_CLIENT_TIMEOUT)
except: except Exception:
AIOHTTP_CLIENT_TIMEOUT = 300 AIOHTTP_CLIENT_TIMEOUT = 300
@ -727,7 +727,7 @@ try:
OPENAI_API_KEY = OPENAI_API_KEYS.value[ OPENAI_API_KEY = OPENAI_API_KEYS.value[
OPENAI_API_BASE_URLS.value.index("https://api.openai.com/v1") OPENAI_API_BASE_URLS.value.index("https://api.openai.com/v1")
] ]
except: except Exception:
pass pass
OPENAI_API_BASE_URL = "https://api.openai.com/v1" OPENAI_API_BASE_URL = "https://api.openai.com/v1"
@ -1043,7 +1043,7 @@ RAG_EMBEDDING_MODEL = PersistentConfig(
"rag.embedding_model", "rag.embedding_model",
os.environ.get("RAG_EMBEDDING_MODEL", "sentence-transformers/all-MiniLM-L6-v2"), os.environ.get("RAG_EMBEDDING_MODEL", "sentence-transformers/all-MiniLM-L6-v2"),
) )
log.info(f"Embedding model set: {RAG_EMBEDDING_MODEL.value}"), log.info(f"Embedding model set: {RAG_EMBEDDING_MODEL.value}")
RAG_EMBEDDING_MODEL_AUTO_UPDATE = ( RAG_EMBEDDING_MODEL_AUTO_UPDATE = (
os.environ.get("RAG_EMBEDDING_MODEL_AUTO_UPDATE", "").lower() == "true" os.environ.get("RAG_EMBEDDING_MODEL_AUTO_UPDATE", "").lower() == "true"
@ -1065,7 +1065,7 @@ RAG_RERANKING_MODEL = PersistentConfig(
os.environ.get("RAG_RERANKING_MODEL", ""), os.environ.get("RAG_RERANKING_MODEL", ""),
) )
if RAG_RERANKING_MODEL.value != "": if RAG_RERANKING_MODEL.value != "":
log.info(f"Reranking model set: {RAG_RERANKING_MODEL.value}"), log.info(f"Reranking model set: {RAG_RERANKING_MODEL.value}")
RAG_RERANKING_MODEL_AUTO_UPDATE = ( RAG_RERANKING_MODEL_AUTO_UPDATE = (
os.environ.get("RAG_RERANKING_MODEL_AUTO_UPDATE", "").lower() == "true" os.environ.get("RAG_RERANKING_MODEL_AUTO_UPDATE", "").lower() == "true"

View File

@ -51,7 +51,7 @@ from apps.webui.internal.db import Session
from pydantic import BaseModel from pydantic import BaseModel
from typing import List, Optional from typing import Optional
from apps.webui.models.auths import Auths from apps.webui.models.auths import Auths
from apps.webui.models.models import Models from apps.webui.models.models import Models
@ -1883,7 +1883,7 @@ async def get_pipeline_valves(
res = r.json() res = r.json()
if "detail" in res: if "detail" in res:
detail = res["detail"] detail = res["detail"]
except: except Exception:
pass pass
raise HTTPException( raise HTTPException(
@ -2027,7 +2027,7 @@ async def get_model_filter_config(user=Depends(get_admin_user)):
class ModelFilterConfigForm(BaseModel): class ModelFilterConfigForm(BaseModel):
enabled: bool enabled: bool
models: List[str] models: list[str]
@app.post("/api/config/model/filter") @app.post("/api/config/model/filter")

View File

@ -2,14 +2,14 @@ from pathlib import Path
import hashlib import hashlib
import re import re
from datetime import timedelta from datetime import timedelta
from typing import Optional, List, Tuple, Callable from typing import Optional, Callable
import uuid import uuid
import time import time
from utils.task import prompt_template from utils.task import prompt_template
def get_last_user_message_item(messages: List[dict]) -> Optional[dict]: def get_last_user_message_item(messages: list[dict]) -> Optional[dict]:
for message in reversed(messages): for message in reversed(messages):
if message["role"] == "user": if message["role"] == "user":
return message return message
@ -26,7 +26,7 @@ def get_content_from_message(message: dict) -> Optional[str]:
return None return None
def get_last_user_message(messages: List[dict]) -> Optional[str]: def get_last_user_message(messages: list[dict]) -> Optional[str]:
message = get_last_user_message_item(messages) message = get_last_user_message_item(messages)
if message is None: if message is None:
return None return None
@ -34,31 +34,31 @@ def get_last_user_message(messages: List[dict]) -> Optional[str]:
return get_content_from_message(message) return get_content_from_message(message)
def get_last_assistant_message(messages: List[dict]) -> Optional[str]: def get_last_assistant_message(messages: list[dict]) -> Optional[str]:
for message in reversed(messages): for message in reversed(messages):
if message["role"] == "assistant": if message["role"] == "assistant":
return get_content_from_message(message) return get_content_from_message(message)
return None return None
def get_system_message(messages: List[dict]) -> Optional[dict]: def get_system_message(messages: list[dict]) -> Optional[dict]:
for message in messages: for message in messages:
if message["role"] == "system": if message["role"] == "system":
return message return message
return None return None
def remove_system_message(messages: List[dict]) -> List[dict]: def remove_system_message(messages: list[dict]) -> list[dict]:
return [message for message in messages if message["role"] != "system"] 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[Optional[dict], list[dict]]:
return get_system_message(messages), remove_system_message(messages) return get_system_message(messages), remove_system_message(messages)
def prepend_to_first_user_message_content( def prepend_to_first_user_message_content(
content: str, messages: List[dict] content: str, messages: list[dict]
) -> List[dict]: ) -> list[dict]:
for message in messages: for message in messages:
if message["role"] == "user": if message["role"] == "user":
if isinstance(message["content"], list): if isinstance(message["content"], list):
@ -71,7 +71,7 @@ def prepend_to_first_user_message_content(
return messages return messages
def add_or_update_system_message(content: str, messages: List[dict]): def add_or_update_system_message(content: str, messages: list[dict]):
""" """
Adds a new system message at the beginning of the messages list Adds a new system message at the beginning of the messages list
or updates the existing system message at the beginning. or updates the existing system message at the beginning.

View File

@ -1,5 +1,5 @@
import inspect import inspect
from typing import get_type_hints, List, Dict, Any from typing import get_type_hints
def doc_to_dict(docstring): def doc_to_dict(docstring):
@ -16,7 +16,7 @@ def doc_to_dict(docstring):
return ret_dict return ret_dict
def get_tools_specs(tools) -> List[dict]: def get_tools_specs(tools) -> list[dict]:
function_list = [ function_list = [
{"name": func, "function": getattr(tools, func)} {"name": func, "function": getattr(tools, func)}
for func in dir(tools) for func in dir(tools)