forked from open-webui/open-webui
		
	feat: chat export
This commit is contained in:
		
							parent
							
								
									a2b1e3756b
								
							
						
					
					
						commit
						4221594778
					
				
					 5 changed files with 81 additions and 11 deletions
				
			
		|  | @ -1,7 +1,7 @@ | |||
| from fastapi import FastAPI, Request, Depends, HTTPException | ||||
| from fastapi.middleware.cors import CORSMiddleware | ||||
| 
 | ||||
| from apps.web.routers import auths, users, chats, utils | ||||
| from apps.web.routers import auths, users, chats, modelfiles, utils | ||||
| from config import WEBUI_VERSION, WEBUI_AUTH | ||||
| 
 | ||||
| app = FastAPI() | ||||
|  | @ -19,8 +19,11 @@ app.add_middleware( | |||
| 
 | ||||
| app.include_router(auths.router, prefix="/auths", tags=["auths"]) | ||||
| app.include_router(users.router, prefix="/users", tags=["users"]) | ||||
| app.include_router(utils.router, prefix="/utils", tags=["utils"]) | ||||
| app.include_router(chats.router, prefix="/chats", tags=["chats"]) | ||||
| app.include_router(modelfiles.router, prefix="/modelfiles", tags=["modelfiles"]) | ||||
| 
 | ||||
| 
 | ||||
| app.include_router(utils.router, prefix="/utils", tags=["utils"]) | ||||
| 
 | ||||
| 
 | ||||
| @app.get("/") | ||||
|  |  | |||
|  | @ -123,6 +123,14 @@ class ChatTable: | |||
|             # .offset(skip) | ||||
|         ] | ||||
| 
 | ||||
|     def get_all_chats_by_user_id(self, user_id: str) -> List[ChatModel]: | ||||
|         return [ | ||||
|             ChatModel(**model_to_dict(chat)) | ||||
|             for chat in Chat.select() | ||||
|             .where(Chat.user_id == user_id) | ||||
|             .order_by(Chat.timestamp.desc()) | ||||
|         ] | ||||
| 
 | ||||
|     def get_chat_by_id_and_user_id(self, id: str, user_id: str) -> Optional[ChatModel]: | ||||
|         try: | ||||
|             chat = Chat.get(Chat.id == id, Chat.user_id == user_id) | ||||
|  |  | |||
|  | @ -43,6 +43,28 @@ async def get_user_chats(skip: int = 0, limit: int = 50, cred=Depends(bearer_sch | |||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| ############################ | ||||
| # GetAllChats | ||||
| ############################ | ||||
| 
 | ||||
| 
 | ||||
| @router.get("/all", response_model=List[ChatResponse]) | ||||
| async def get_all_user_chats(cred=Depends(bearer_scheme)): | ||||
|     token = cred.credentials | ||||
|     user = Users.get_user_by_token(token) | ||||
| 
 | ||||
|     if user: | ||||
|         return [ | ||||
|             ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)}) | ||||
|             for chat in Chats.get_all_chats_by_user_id(user.id) | ||||
|         ] | ||||
|     else: | ||||
|         raise HTTPException( | ||||
|             status_code=status.HTTP_401_UNAUTHORIZED, | ||||
|             detail=ERROR_MESSAGES.INVALID_TOKEN, | ||||
|         ) | ||||
| 
 | ||||
| 
 | ||||
| ############################ | ||||
| # CreateNewChat | ||||
| ############################ | ||||
|  |  | |||
|  | @ -62,6 +62,37 @@ export const getChatList = async (token: string = '') => { | |||
| 	return res; | ||||
| }; | ||||
| 
 | ||||
| export const getAllChats = async (token: string) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
| 	const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all`, { | ||||
| 		method: 'GET', | ||||
| 		headers: { | ||||
| 			Accept: 'application/json', | ||||
| 			'Content-Type': 'application/json', | ||||
| 			...(token && { authorization: `Bearer ${token}` }) | ||||
| 		} | ||||
| 	}) | ||||
| 		.then(async (res) => { | ||||
| 			if (!res.ok) throw await res.json(); | ||||
| 			return res.json(); | ||||
| 		}) | ||||
| 		.then((json) => { | ||||
| 			return json; | ||||
| 		}) | ||||
| 		.catch((err) => { | ||||
| 			error = err; | ||||
| 			console.log(err); | ||||
| 			return null; | ||||
| 		}); | ||||
| 
 | ||||
| 	if (error) { | ||||
| 		throw error; | ||||
| 	} | ||||
| 
 | ||||
| 	return res; | ||||
| }; | ||||
| 
 | ||||
| export const getChatById = async (token: string, id: string) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,20 +1,23 @@ | |||
| <script lang="ts"> | ||||
| 	import Modal from '../common/Modal.svelte'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 	import fileSaver from 'file-saver'; | ||||
| 	const { saveAs } = fileSaver; | ||||
| 
 | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { config, models, settings, user, chats } from '$lib/stores'; | ||||
| 	import { splitStream, getGravatarURL } from '$lib/utils'; | ||||
| 
 | ||||
| 	import { getOllamaVersion } from '$lib/apis/ollama'; | ||||
| 	import { createNewChat, getAllChats, getChatList } from '$lib/apis/chats'; | ||||
| 	import { | ||||
| 		WEB_UI_VERSION, | ||||
| 		OLLAMA_API_BASE_URL, | ||||
| 		WEBUI_API_BASE_URL, | ||||
| 		WEBUI_BASE_URL | ||||
| 	} from '$lib/constants'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { config, models, settings, user, chats } from '$lib/stores'; | ||||
| 	import { splitStream, getGravatarURL } from '$lib/utils'; | ||||
| 
 | ||||
| 	import Advanced from './Settings/Advanced.svelte'; | ||||
| 	import { stringify } from 'postcss'; | ||||
| 	import { getOllamaVersion } from '$lib/apis/ollama'; | ||||
| 	import { createNewChat, getChatList } from '$lib/apis/chats'; | ||||
| 	import Modal from '../common/Modal.svelte'; | ||||
| 
 | ||||
| 	export let show = false; | ||||
| 
 | ||||
|  | @ -91,7 +94,10 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const exportChats = async () => { | ||||
| 		console.log('TODO: export all chats'); | ||||
| 		let blob = new Blob([JSON.stringify(await getAllChats(localStorage.token))], { | ||||
| 			type: 'application/json' | ||||
| 		}); | ||||
| 		saveAs(blob, `chat-export-${Date.now()}.json`); | ||||
| 	}; | ||||
| 
 | ||||
| 	$: if (importFiles) { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek