From 6bbb7559970d18846c69511831743fe401b99925 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 3 Sep 2024 21:16:07 +0200 Subject: [PATCH] feat: import/export config --- backend/apps/webui/routers/configs.py | 28 ++++ src/lib/apis/configs/index.ts | 57 +++++++ .../components/admin/Settings/Database.svelte | 149 ++++++++++++++---- 3 files changed, 200 insertions(+), 34 deletions(-) diff --git a/backend/apps/webui/routers/configs.py b/backend/apps/webui/routers/configs.py index 5c891f32a..a887e2c2f 100644 --- a/backend/apps/webui/routers/configs.py +++ b/backend/apps/webui/routers/configs.py @@ -3,9 +3,37 @@ from fastapi import APIRouter, Depends, Request from pydantic import BaseModel from utils.utils import get_admin_user, get_verified_user + +from config import get_config, save_config + router = APIRouter() +############################ +# ImportConfig +############################ + + +class ImportConfigForm(BaseModel): + config: dict + + +@router.post("/import", response_model=dict) +async def import_config(form_data: ImportConfigForm, user=Depends(get_admin_user)): + save_config(form_data.config) + return get_config() + + +############################ +# ExportConfig +############################ + + +@router.get("/export", response_model=dict) +async def export_config(user=Depends(get_admin_user)): + return get_config() + + class SetDefaultModelsForm(BaseModel): models: str diff --git a/src/lib/apis/configs/index.ts b/src/lib/apis/configs/index.ts index 4f53c53c8..0c4de6ad6 100644 --- a/src/lib/apis/configs/index.ts +++ b/src/lib/apis/configs/index.ts @@ -1,6 +1,63 @@ import { WEBUI_API_BASE_URL } from '$lib/constants'; import type { Banner } from '$lib/types'; +export const importConfig = async (token: string, config) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/import`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + }, + body: JSON.stringify({ + config: config + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + +export const exportConfig = async (token: string) => { + let error = null; + + const res = await fetch(`${WEBUI_API_BASE_URL}/configs/export`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}` + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + error = err.detail; + return null; + }); + + if (error) { + throw error; + } + + return res; +}; + export const setDefaultModels = async (token: string, models: string) => { let error = null; diff --git a/src/lib/components/admin/Settings/Database.svelte b/src/lib/components/admin/Settings/Database.svelte index 0ba45263e..3c376cb80 100644 --- a/src/lib/components/admin/Settings/Database.svelte +++ b/src/lib/components/admin/Settings/Database.svelte @@ -7,6 +7,7 @@ import { config, user } from '$lib/stores'; import { toast } from 'svelte-sonner'; import { getAllUserChats } from '$lib/apis/chats'; + import { exportConfig, importConfig } from '$lib/apis/configs'; const i18n = getContext('i18n'); @@ -34,6 +35,92 @@
{$i18n.t('Database')}
+ { + const file = e.target.files[0]; + const reader = new FileReader(); + + reader.onload = async (e) => { + const res = await importConfig(localStorage.token, JSON.parse(e.target.result)).catch( + (error) => { + toast.error(error); + } + ); + + if (res) { + toast.success('Config imported successfully'); + } + e.target.value = null; + }; + + reader.readAsText(file); + }} + /> + + + + + +
+ {#if $config?.features.enable_admin_export ?? true}
@@ -97,40 +184,34 @@
-
- - - -
+