mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-11 20:05:19 +00:00
feat: refactor model import to a single backend endpoint
This refactors the model import functionality to improve performance and user experience by centralizing the logic on the backend. Previously, the frontend would parse an imported JSON file and send an individual API request for each model, which was slow and inefficient. This change introduces a new backend endpoint, `/api/v1/models/import`, that accepts a list of model objects. The frontend now reads the selected JSON file, parses it, and sends the entire payload to the backend in a single request. The backend then processes this list, creating or updating models as necessary. This commit also includes the following fixes: - Handles cases where the imported JSON contains models without `meta` or `params` fields by providing default empty values.
This commit is contained in:
parent
231d182c35
commit
fe28097817
3 changed files with 29 additions and 19 deletions
|
|
@ -22,8 +22,6 @@ from fastapi import (
|
|||
Request,
|
||||
status,
|
||||
Response,
|
||||
UploadFile,
|
||||
File,
|
||||
)
|
||||
from fastapi.responses import FileResponse, StreamingResponse
|
||||
|
||||
|
|
@ -112,12 +110,16 @@ async def export_models(user=Depends(get_admin_user)):
|
|||
############################
|
||||
|
||||
|
||||
class ModelsImportForm(BaseModel):
|
||||
models: list[dict]
|
||||
|
||||
|
||||
@router.post("/import", response_model=bool)
|
||||
async def import_models(
|
||||
user: str = Depends(get_admin_user), file: UploadFile = File(...)
|
||||
user: str = Depends(get_admin_user), form_data: ModelsImportForm = (...)
|
||||
):
|
||||
try:
|
||||
data = json.loads(await file.read())
|
||||
data = form_data.models
|
||||
if isinstance(data, list):
|
||||
for model_data in data:
|
||||
# Here, you can add logic to validate model_data if needed
|
||||
|
|
|
|||
|
|
@ -31,18 +31,16 @@ export const getModels = async (token: string = '') => {
|
|||
return res;
|
||||
};
|
||||
|
||||
export const importModels = async (token: string, file: File) => {
|
||||
export const importModels = async (token: string, models: object[]) => {
|
||||
let error = null;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/models/import`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
},
|
||||
body: formData
|
||||
body: JSON.stringify({ models: models })
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
|
|
|
|||
|
|
@ -465,18 +465,28 @@ let modelsImportInProgress = false;
|
|||
type="file"
|
||||
accept=".json"
|
||||
hidden
|
||||
on:change={async () => {
|
||||
on:change={() => {
|
||||
if (importFiles.length > 0) {
|
||||
modelsImportInProgress = true;
|
||||
const res = await importModels(localStorage.token, importFiles[0]);
|
||||
modelsImportInProgress = false;
|
||||
const reader = new FileReader();
|
||||
reader.onload = async (event) => {
|
||||
try {
|
||||
const models = JSON.parse(String(event.target.result));
|
||||
modelsImportInProgress = true;
|
||||
const res = await importModels(localStorage.token, models);
|
||||
modelsImportInProgress = false;
|
||||
|
||||
if (res) {
|
||||
toast.success($i18n.t('Models imported successfully'));
|
||||
await init();
|
||||
} else {
|
||||
toast.error($i18n.t('Failed to import models'));
|
||||
}
|
||||
if (res) {
|
||||
toast.success($i18n.t('Models imported successfully'));
|
||||
await init();
|
||||
} else {
|
||||
toast.error($i18n.t('Failed to import models'));
|
||||
}
|
||||
} catch (e) {
|
||||
toast.error($i18n.t('Invalid JSON file'));
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
reader.readAsText(importFiles[0]);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue