perf: Internationalization of API Documentation

This commit is contained in:
fit2cloud-chenyw
2025-12-12 17:31:24 +08:00
committed by fit2cloud-chenyw
parent 190c6ea174
commit 87596aac6a
7 changed files with 125 additions and 48 deletions
+8
View File
@@ -54,6 +54,14 @@ tags_metadata = [
"name": "system_ws",
"description": f"{PLACEHOLDER_PREFIX}system_ws_api"
},
{
"name": "system_model",
"description": f"{PLACEHOLDER_PREFIX}system_model_api"
},
{
"name": "system_assistant",
"description": f"{PLACEHOLDER_PREFIX}system_assistant_api"
},
{ "name": "Table Relation",
"description": f"{PLACEHOLDER_PREFIX}tr_api"
},
+33
View File
@@ -69,6 +69,39 @@
"weight": "Weight (1: Admin, 0: Regular User)",
"system_model_api": "Model Configuration APIs",
"system_model_default": "Set Default Model",
"system_model_grid": "Get Model List",
"system_model_query": "Get Model Details",
"system_model_create": "Save Model",
"system_model_update": "Update Model",
"system_model_del": "Delete Model",
"model_name": "Name",
"model_type": "Type",
"base_model": "Base Model",
"supplier": "Operator",
"protocol": "Protocol",
"default_model": "Is Default",
"api_domain": "Base URL",
"api_key": "API Key",
"config_list": "Parameter List",
"arg_name": "Parameter Name",
"arg_val": "Parameter Value",
"arg_show_name": "Parameter Display Name",
"system_assistant_api": "Assistant APIs",
"assistant_picture_api": "Get Pictures",
"assistant_ui_api": "Set Appearance",
"assistant_grid_api": "Get List",
"assistant_query_api": "Get Details",
"assistant_create_api": "Create",
"assistant_update_api": "Update",
"assistant_del_api": "Delete",
"assistant_domain": "Domain",
"assistant_type": "Assistant Type (0: Basic, 1: Advanced, 4: Page)",
"assistant_configuration": "Configuration",
"assistant_description": "Description",
"per_api": "Data Permission",
"per_save": "Save Permission",
"per_delete": "Delete Permission",
+33
View File
@@ -69,6 +69,39 @@
"weight": "权重(1: 管理员, 0: 普通用户)",
"system_model_api": "模型配置api",
"system_model_default": "设置默认模型",
"system_model_grid": "查询模型列表",
"system_model_query": "查询模型详情",
"system_model_create": "保存模型",
"system_model_update": "更新模型",
"system_model_del": "删除模型",
"model_name": "名称",
"model_type": "类型",
"base_model": "基础模型",
"supplier": "运营商",
"protocol": "协议",
"default_model": "是否默认",
"api_domain": "基础 Url",
"api_key": "Api key",
"config_list": "参数列表",
"arg_name": "参数名称",
"arg_val": "参数值",
"arg_show_name": "参数展示名称",
"system_assistant_api": "小助手api",
"assistant_picture_api": "查询图片",
"assistant_ui_api": "设置外观",
"assistant_grid_api": "查询列表",
"assistant_query_api": "查询详情",
"assistant_create_api": "创建",
"assistant_update_api": "修改",
"assistant_del_api": "删除",
"assistant_domain": "域名",
"assistant_type": "助手类型(0: 基础, 1: 高级, 4: 页面)",
"assistant_configuration": "配置",
"assistant_description": "描述",
"per_api": "数据权限",
"per_save": "保存权限",
"per_delete": "删除权限",
+15 -14
View File
@@ -3,8 +3,9 @@ from typing import List, Union
from fastapi.responses import StreamingResponse
from apps.ai_model.model_factory import LLMConfig, LLMFactory
from apps.swagger.i18n import PLACEHOLDER_PREFIX
from apps.system.schemas.ai_model_schema import AiModelConfigItem, AiModelCreator, AiModelEditor, AiModelGridItem
from fastapi import APIRouter, Query
from fastapi import APIRouter, Path, Query
from sqlmodel import func, select, update
from apps.system.models.system_model import AiModelDetail
@@ -14,9 +15,9 @@ from common.utils.crypto import sqlbot_decrypt
from common.utils.time import get_timestamp
from common.utils.utils import SQLBotLogUtil, prepare_model_arg
router = APIRouter(tags=["system/aimodel"], prefix="/system/aimodel")
router = APIRouter(tags=["system_model"], prefix="/system/aimodel")
@router.post("/status")
@router.post("/status", include_in_schema=False)
async def check_llm(info: AiModelCreator, trans: Trans):
async def generate():
try:
@@ -43,7 +44,7 @@ async def check_llm(info: AiModelCreator, trans: Trans):
return StreamingResponse(generate(), media_type="application/x-ndjson")
@router.get("/default")
@router.get("/default", include_in_schema=False)
async def check_default(session: SessionDep, trans: Trans):
db_model = session.exec(
select(AiModelDetail).where(AiModelDetail.default_model == True)
@@ -51,9 +52,9 @@ async def check_default(session: SessionDep, trans: Trans):
if not db_model:
raise Exception(trans('i18n_llm.miss_default'))
@router.put("/default/{id}")
@router.put("/default/{id}", summary=f"{PLACEHOLDER_PREFIX}system_model_default", description=f"{PLACEHOLDER_PREFIX}system_model_default")
@require_permissions(permission=SqlbotPermission(role=['admin']))
async def set_default(session: SessionDep, id: int):
async def set_default(session: SessionDep, id: int = Path(description="ID")):
db_model = session.get(AiModelDetail, id)
if not db_model:
raise ValueError(f"AiModelDetail with id {id} not found")
@@ -71,11 +72,11 @@ async def set_default(session: SessionDep, id: int):
session.rollback()
raise e
@router.get("", response_model=list[AiModelGridItem])
@router.get("", response_model=list[AiModelGridItem], summary=f"{PLACEHOLDER_PREFIX}system_model_grid", description=f"{PLACEHOLDER_PREFIX}system_model_grid")
@require_permissions(permission=SqlbotPermission(role=['admin']))
async def query(
session: SessionDep,
keyword: Union[str, None] = Query(default=None, max_length=255)
keyword: Union[str, None] = Query(default=None, max_length=255, description=f"{PLACEHOLDER_PREFIX}keyword")
):
statement = select(AiModelDetail.id,
AiModelDetail.name,
@@ -90,10 +91,10 @@ async def query(
items = session.exec(statement).all()
return items
@router.get("/{id}", response_model=AiModelEditor)
@router.get("/{id}", response_model=AiModelEditor, summary=f"{PLACEHOLDER_PREFIX}system_model_query", description=f"{PLACEHOLDER_PREFIX}system_model_query")
async def get_model_by_id(
session: SessionDep,
id: int
id: int = Path(description="ID")
):
db_model = session.get(AiModelDetail, id)
if not db_model:
@@ -115,7 +116,7 @@ async def get_model_by_id(
data["config_list"] = config_list
return AiModelEditor(**data)
@router.post("")
@router.post("", summary=f"{PLACEHOLDER_PREFIX}system_model_create", description=f"{PLACEHOLDER_PREFIX}system_model_create")
@require_permissions(permission=SqlbotPermission(role=['admin']))
async def add_model(
session: SessionDep,
@@ -132,7 +133,7 @@ async def add_model(
session.add(detail)
session.commit()
@router.put("")
@router.put("", summary=f"{PLACEHOLDER_PREFIX}system_model_update", description=f"{PLACEHOLDER_PREFIX}system_model_update")
@require_permissions(permission=SqlbotPermission(role=['admin']))
async def update_model(
session: SessionDep,
@@ -148,12 +149,12 @@ async def update_model(
session.add(db_model)
session.commit()
@router.delete("/{id}")
@router.delete("/{id}", summary=f"{PLACEHOLDER_PREFIX}system_model_del", description=f"{PLACEHOLDER_PREFIX}system_model_del")
@require_permissions(permission=SqlbotPermission(role=['admin']))
async def delete_model(
session: SessionDep,
trans: Trans,
id: int
id: int = Path(description="ID")
):
item = session.get(AiModelDetail, id)
if item.default_model:
+17 -16
View File
@@ -3,11 +3,12 @@ import os
from datetime import timedelta
from typing import List, Optional
from fastapi import APIRouter, Form, HTTPException, Query, Request, Response, UploadFile
from fastapi import APIRouter, Form, HTTPException, Path, Query, Request, Response, UploadFile
from fastapi.responses import StreamingResponse
from sqlbot_xpack.file_utils import SQLBotFileUtils
from sqlmodel import select
from apps.swagger.i18n import PLACEHOLDER_PREFIX
from apps.system.crud.assistant import get_assistant_info
from apps.system.crud.assistant_manage import dynamic_upgrade_cors, save
from apps.system.models.system_model import AssistantModel
@@ -19,10 +20,10 @@ from common.core.security import create_access_token
from common.core.sqlbot_cache import clear_cache
from common.utils.utils import get_origin_from_referer, origin_match_domain
router = APIRouter(tags=["system/assistant"], prefix="/system/assistant")
router = APIRouter(tags=["system_assistant"], prefix="/system/assistant")
@router.get("/info/{id}")
@router.get("/info/{id}", include_in_schema=False)
async def info(request: Request, response: Response, session: SessionDep, trans: Trans, id: int) -> AssistantModel:
if not id:
raise Exception('miss assistant id')
@@ -42,7 +43,7 @@ async def info(request: Request, response: Response, session: SessionDep, trans:
return db_model
@router.get("/app/{appId}")
@router.get("/app/{appId}", include_in_schema=False)
async def getApp(request: Request, response: Response, session: SessionDep, trans: Trans, appId: str) -> AssistantModel:
if not appId:
raise Exception('miss assistant appId')
@@ -61,7 +62,7 @@ async def getApp(request: Request, response: Response, session: SessionDep, tran
return db_model
@router.get("/validator", response_model=AssistantValidator)
@router.get("/validator", response_model=AssistantValidator, include_in_schema=False)
async def validator(session: SessionDep, id: int, virtual: Optional[int] = Query(None)):
if not id:
raise Exception('miss assistant id')
@@ -86,8 +87,8 @@ async def validator(session: SessionDep, id: int, virtual: Optional[int] = Query
return AssistantValidator(True, True, True, access_token)
@router.get('/picture/{file_id}')
async def picture(file_id: str):
@router.get('/picture/{file_id}', summary=f"{PLACEHOLDER_PREFIX}assistant_picture_api", description=f"{PLACEHOLDER_PREFIX}assistant_picture_api")
async def picture(file_id: str = Path(description="file_id")):
file_path = SQLBotFileUtils.get_file_path(file_id=file_id)
if not os.path.exists(file_path):
raise HTTPException(status_code=404, detail="File not found")
@@ -104,7 +105,7 @@ async def picture(file_id: str):
return StreamingResponse(iterfile(), media_type=media_type)
@router.patch('/ui')
@router.patch('/ui', summary=f"{PLACEHOLDER_PREFIX}assistant_ui_api", description=f"{PLACEHOLDER_PREFIX}assistant_ui_api")
async def ui(session: SessionDep, data: str = Form(), files: List[UploadFile] = []):
json_data = json.loads(data)
uiSchema = AssistantUiSchema(**json_data)
@@ -152,26 +153,26 @@ async def clear_ui_cache(id: int):
pass
@router.get("", response_model=list[AssistantModel])
@router.get("", response_model=list[AssistantModel], summary=f"{PLACEHOLDER_PREFIX}assistant_grid_api", description=f"{PLACEHOLDER_PREFIX}assistant_grid_api")
async def query(session: SessionDep):
list_result = session.exec(select(AssistantModel).where(AssistantModel.type != 4).order_by(AssistantModel.name,
AssistantModel.create_time)).all()
return list_result
@router.get("/advanced_application", response_model=list[AssistantModel])
@router.get("/advanced_application", response_model=list[AssistantModel], include_in_schema=False)
async def query_advanced_application(session: SessionDep):
list_result = session.exec(select(AssistantModel).where(AssistantModel.type == 1).order_by(AssistantModel.name,
AssistantModel.create_time)).all()
return list_result
@router.post("")
@router.post("", summary=f"{PLACEHOLDER_PREFIX}assistant_create_api", description=f"{PLACEHOLDER_PREFIX}assistant_create_api")
async def add(request: Request, session: SessionDep, creator: AssistantBase):
await save(request, session, creator)
@router.put("")
@router.put("", summary=f"{PLACEHOLDER_PREFIX}assistant_update_api", description=f"{PLACEHOLDER_PREFIX}assistant_update_api")
@clear_cache(namespace=CacheNamespace.EMBEDDED_INFO, cacheName=CacheName.ASSISTANT_INFO, keyExpression="editor.id")
async def update(request: Request, session: SessionDep, editor: AssistantDTO):
id = editor.id
@@ -185,8 +186,8 @@ async def update(request: Request, session: SessionDep, editor: AssistantDTO):
dynamic_upgrade_cors(request=request, session=session)
@router.get("/{id}", response_model=AssistantModel)
async def get_one(session: SessionDep, id: int):
@router.get("/{id}", response_model=AssistantModel, summary=f"{PLACEHOLDER_PREFIX}assistant_query_api", description=f"{PLACEHOLDER_PREFIX}assistant_query_api")
async def get_one(session: SessionDep, id: int = Path(description="ID")):
db_model = await get_assistant_info(session=session, assistant_id=id)
if not db_model:
raise ValueError(f"AssistantModel with id {id} not found")
@@ -194,9 +195,9 @@ async def get_one(session: SessionDep, id: int):
return db_model
@router.delete("/{id}")
@router.delete("/{id}", response_model=AssistantModel, summary=f"{PLACEHOLDER_PREFIX}assistant_del_api", description=f"{PLACEHOLDER_PREFIX}assistant_del_api")
@clear_cache(namespace=CacheNamespace.EMBEDDED_INFO, cacheName=CacheName.ASSISTANT_INFO, keyExpression="id")
async def delete(request: Request, session: SessionDep, id: int):
async def delete(request: Request, session: SessionDep, id: int = Path(description="ID")):
db_model = session.get(AssistantModel, id)
if not db_model:
raise ValueError(f"AssistantModel with id {id} not found")
+14 -13
View File
@@ -1,29 +1,30 @@
from typing import List
from pydantic import BaseModel
from pydantic import BaseModel, Field
from apps.swagger.i18n import PLACEHOLDER_PREFIX
from common.core.schemas import BaseCreatorDTO
class AiModelItem(BaseModel):
name: str
model_type: int
base_model: str
supplier: int
protocol: int
default_model: bool = False
name: str = Field(description=f"{PLACEHOLDER_PREFIX}model_name")
model_type: int = Field(description=f"{PLACEHOLDER_PREFIX}model_type")
base_model: str = Field(description=f"{PLACEHOLDER_PREFIX}base_model")
supplier: int = Field(description=f"{PLACEHOLDER_PREFIX}supplier")
protocol: int = Field(description=f"{PLACEHOLDER_PREFIX}protocol")
default_model: bool = Field(default=False, description=f"{PLACEHOLDER_PREFIX}default_model")
class AiModelGridItem(AiModelItem, BaseCreatorDTO):
pass
class AiModelConfigItem(BaseModel):
key: str
val: object
name: str
key: str = Field(description=f"{PLACEHOLDER_PREFIX}arg_name")
val: object = Field(description=f"{PLACEHOLDER_PREFIX}arg_val")
name: str = Field(description=f"{PLACEHOLDER_PREFIX}arg_show_name")
class AiModelCreator(AiModelItem):
api_domain: str
api_key: str
config_list: List[AiModelConfigItem]
api_domain: str = Field(description=f"{PLACEHOLDER_PREFIX}api_domain")
api_key: str = Field(description=f"{PLACEHOLDER_PREFIX}api_key")
config_list: List[AiModelConfigItem] = Field(description=f"{PLACEHOLDER_PREFIX}config_list")
class AiModelEditor(AiModelCreator, BaseCreatorDTO):
pass
+5 -5
View File
@@ -103,11 +103,11 @@ class UserInfoDTO(UserEditor):
class AssistantBase(BaseModel):
name: str
domain: str
type: int = 0 # 0普通小助手 1高级 4页面嵌入
configuration: Optional[str] = None
description: Optional[str] = None
name: str = Field(description=f"{PLACEHOLDER_PREFIX}model_name")
domain: str = Field(description=f"{PLACEHOLDER_PREFIX}assistant_domain")
type: int = Field(default=0, description=f"{PLACEHOLDER_PREFIX}assistant_type") # 0普通小助手 1高级 4页面嵌入
configuration: Optional[str] = Field(default=None, description=f"{PLACEHOLDER_PREFIX}assistant_configuration")
description: Optional[str] = Field(default=None, description=f"{PLACEHOLDER_PREFIX}assistant_description")
class AssistantDTO(AssistantBase, BaseCreatorDTO):