修复apikey不能为空的错误

This commit is contained in:
xunbu committed 2025-12-14 11:14:04 +08:00
1 parent a7c265de55
commit 6df97ce0ca
2 files changed
+20 -7

No files matched your search

+19 -6
View File
@@ -49,6 +49,7 @@ from pydantic import (
BaseModel,
Field,
model_validator,
field_validator, # Added field_validator
AliasChoices,
ConfigDict,
Json,
@@ -299,11 +300,17 @@ class GlossaryAgentConfigPayload(BaseModel):
examples=["https://api.openai.com/v1"],
)
api_key: str = Field(
...,
default="xx",
validation_alias=AliasChoices("api_key", "key"),
description="用于术语表生成的Agent的LLM API密钥。",
description="用于术语表生成的Agent的LLM API密钥(默认为xx)。",
examples=["sk-agent-api-key"],
)
@field_validator("api_key")
@classmethod
def set_default_glossary_api_key(cls, v: str) -> str:
return v if v and v.strip() else "xx"
model_id: str = Field(
..., description="用于术语表生成的Agent的模型ID。", examples=["gpt-4-turbo"]
)
@@ -344,12 +351,18 @@ class BaseWorkflowParams(BaseModel):
description="LLM API的基础URL。当 `skip_translate` 为 `False` 时必填。",
examples=["https://api.openai.com/v1"],
)
api_key: Optional[str] = Field(
default=None,
api_key: str = Field(
default="xx",
validation_alias=AliasChoices("api_key", "key"),
description="LLM API的密钥(可选)。",
description="LLM API的密钥(可选,默认为xx)。",
examples=["sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
)
@field_validator("api_key")
@classmethod
def set_default_api_key(cls, v: str) -> str:
return v if v and v.strip() else "xx"
model_id: Optional[str] = Field(
default=None,
description="要使用的LLM模型ID。当 `skip_translate` 为 `False` 时必填。",
@@ -2481,7 +2494,7 @@ async def redoc_html():
@app.post("/temp/translate", tags=["Temp"])
async def temp_translate(
base_url: str = Body(...),
api_key: str = Body(...),
api_key: str = Body("xx"),
model_id: str = Body(...),
mineru_token: Optional[str] = Body(None),
file_name: str = Body(...),
+1 -1
View File
@@ -1 +1 @@
<!DOCTYPE html> <html lang="zh-CN" data-bs-theme="auto"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DocuTranslate - 交互式文档翻译</title> <link rel="icon" href="/static/favicon.ico" type="image/x-icon"> <!-- Bootstrap CSS --> <link href="/static/bootstrap.css" rel="stylesheet" crossorigin="anonymous"> <!-- Bootstrap Icons --> <link rel="stylesheet" href="/static/bootstrap-icons.css"> <style> /* 复用原版 CSS */ body { background-color: var(--bs-body-bg); } button:focus { outline: none !important; box-shadow: none !important; } .main-container { display: flex; flex-direction: column; height: 100vh; padding-top: 1rem; padding-bottom: 1rem; } .settings-panel { height: calc(100vh - 2rem); overflow-y: auto; padding-right: 15px; } .task-area { height: calc(100vh - 2rem); overflow-y: auto; } .task-card { transition: all 0.3s ease-in-out; } .log-area { height: 150px; background-color: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: .375rem; font-family: monospace; font-size: 0.8rem; padding: 10px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; } .log-area-wrapper { position: relative; } .copy-log-btn { position: absolute; bottom: 5px; right: 5px; z-index: 10; opacity: 0.5; transition: all 0.2s ease-in-out; padding: 0.1rem 0.4rem; line-height: 1; } .copy-log-btn:hover { opacity: 1; } .file-drop-area { border: 2px dashed var(--bs-secondary-bg); border-radius: .375rem; padding: 2rem; text-align: center; cursor: pointer; transition: all 0.2s ease-in-out; background-color: var(--bs-body-bg); } .file-drop-area.drag-over { border-color: var(--bs-primary); background-color: var(--bs-secondary-bg); } .file-drop-area.file-selected { border-style: solid; border-color: var(--bs-success); background-color: var(--bs-success-bg-subtle); } .file-drop-area.input-error { border-color: var(--bs-danger); } #previewOffcanvas { --bs-offcanvas-width: 95vw; max-width: 1600px; } .preview-split-container { display: flex; flex-direction: row; height: 90%; } .preview-pane-wrapper { display: flex; flex-direction: column; overflow: hidden; width: 100%; height: 100%; } .preview-pane-wrapper .preview-pane { flex-grow: 1; border: 1px solid var(--bs-border-color); border-radius: .375rem; overflow: auto; position: relative; } .gutter { background-color: var(--bs-tertiary-bg); background-repeat: no-repeat; background-position: 50%; } .gutter.gutter-horizontal { cursor: col-resize; border-left: 1px solid var(--bs-border-color); border-right: 1px solid var(--bs-border-color); } .gutter.gutter-vertical { cursor: row-resize; border-top: 1px solid var(--bs-border-color); border-bottom: 1px solid var(--bs-border-color); } .preview-pane iframe { width: 100%; height: 100%; border: none; } .preview-pane pre { margin: 0; padding: 1rem; background-color: var(--bs-body-bg); white-space: pre; } .bottom-left-controls { position: fixed; bottom: 1rem; left: 1rem; z-index: 1050; display: flex; gap: 0.5rem; } .step-number { margin-right: 0.25rem; } #translatedPreviewContainer .preview-pane { overflow: hidden; } #translatedPreviewContainer .preview-pane iframe { display: block; width: 100%; height: 100%; } .lang-list-container { max-height: 200px; overflow-y: auto; border: 1px solid var(--bs-border-color); border-radius: 0.375rem; paddinLine truncated
<!DOCTYPE html> <html lang="zh-CN" data-bs-theme="auto"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>DocuTranslate - 交互式文档翻译</title> <link rel="icon" href="/static/favicon.ico" type="image/x-icon"> <!-- Bootstrap CSS --> <link href="/static/bootstrap.css" rel="stylesheet" crossorigin="anonymous"> <!-- Bootstrap Icons --> <link rel="stylesheet" href="/static/bootstrap-icons.css"> <style> /* 复用原版 CSS */ body { background-color: var(--bs-body-bg); } button:focus { outline: none !important; box-shadow: none !important; } .main-container { display: flex; flex-direction: column; height: 100vh; padding-top: 1rem; padding-bottom: 1rem; } .settings-panel { height: calc(100vh - 2rem); overflow-y: auto; padding-right: 15px; } .task-area { height: calc(100vh - 2rem); overflow-y: auto; } .task-card { transition: all 0.3s ease-in-out; } .log-area { height: 150px; background-color: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: .375rem; font-family: monospace; font-size: 0.8rem; padding: 10px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; } .log-area-wrapper { position: relative; } .copy-log-btn { position: absolute; bottom: 5px; right: 5px; z-index: 10; opacity: 0.5; transition: all 0.2s ease-in-out; padding: 0.1rem 0.4rem; line-height: 1; } .copy-log-btn:hover { opacity: 1; } .file-drop-area { border: 2px dashed var(--bs-secondary-bg); border-radius: .375rem; padding: 2rem; text-align: center; cursor: pointer; transition: all 0.2s ease-in-out; background-color: var(--bs-body-bg); } .file-drop-area.drag-over { border-color: var(--bs-primary); background-color: var(--bs-secondary-bg); } .file-drop-area.file-selected { border-style: solid; border-color: var(--bs-success); background-color: var(--bs-success-bg-subtle); } .file-drop-area.input-error { border-color: var(--bs-danger); } #previewOffcanvas { --bs-offcanvas-width: 95vw; max-width: 1600px; } .preview-split-container { display: flex; flex-direction: row; height: 90%; } .preview-pane-wrapper { display: flex; flex-direction: column; overflow: hidden; width: 100%; height: 100%; } .preview-pane-wrapper .preview-pane { flex-grow: 1; border: 1px solid var(--bs-border-color); border-radius: .375rem; overflow: auto; position: relative; } .gutter { background-color: var(--bs-tertiary-bg); background-repeat: no-repeat; background-position: 50%; } .gutter.gutter-horizontal { cursor: col-resize; border-left: 1px solid var(--bs-border-color); border-right: 1px solid var(--bs-border-color); } .gutter.gutter-vertical { cursor: row-resize; border-top: 1px solid var(--bs-border-color); border-bottom: 1px solid var(--bs-border-color); } .preview-pane iframe { width: 100%; height: 100%; border: none; } .preview-pane pre { margin: 0; padding: 1rem; background-color: var(--bs-body-bg); white-space: pre; } .bottom-left-controls { position: fixed; bottom: 1rem; left: 1rem; z-index: 1050; display: flex; gap: 0.5rem; } .step-number { margin-right: 0.25rem; } #translatedPreviewContainer .preview-pane { overflow: hidden; } #translatedPreviewContainer .preview-pane iframe { display: block; width: 100%; height: 100%; } .lang-list-container { max-height: 200px; overflow-y: auto; border: 1px solid var(--bs-border-color); border-radius: 0.375rem; paddinLine truncated