| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- """
- 本地模型API路由
- 提供本地模型管理的RESTful API端点
- 需求: 2.1, 2.8, 4.5, 4.6, 4.7
- """
- from typing import List
- from fastapi import APIRouter, Depends, HTTPException, status
- from sqlalchemy.orm import Session
- from app.database import get_db
- from app.dependencies.auth import get_current_user
- from app.dependencies.admin_auth import get_current_admin
- from app.models.user import User
- from app.models.admin import AdminUser
- from app.services.local_model_service import LocalModelService
- from app.services.system_config_manager import get_config_bool
- from app.schemas.local_model import (
- LocalModelCreate,
- LocalModelUpdate,
- LocalModelResponse,
- ConnectionTestRequest,
- ConnectionTestResponse
- )
- from app.schemas.model_schema import ApiResponse
- router = APIRouter(prefix="/api/models/local", tags=["本地模型"])
- @router.post("", response_model=ApiResponse[LocalModelResponse])
- def create_local_model(
- request: LocalModelCreate,
- current_admin: AdminUser = Depends(get_current_admin),
- db: Session = Depends(get_db)
- ):
- """
- 添加本地模型
-
- 需求 2.1: 管理员可以添加本地部署的OpenAI API兼容模型
- """
- try:
- service = LocalModelService(db)
- model = service.create_local_model(
- user_id=None,
- name=request.name,
- supplier=request.supplier or 'Custom',
- base_url=request.base_url,
- api_key=request.api_key,
- visibility=request.visibility or 'global',
- categories=request.categories or [0]
- )
- return ApiResponse(code=200, message="success", data=LocalModelResponse.from_model(model))
- except HTTPException:
- raise
- except Exception as e:
- raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
- @router.get("", response_model=ApiResponse[List[LocalModelResponse]])
- async def get_local_models(
- current_user: User = Depends(get_current_user),
- db: Session = Depends(get_db)
- ):
- """
- 获取本地模型列表
-
- 需求 4.1: 用户可以查看自己添加的本地模型列表
- """
- service = LocalModelService(db)
-
- # 检查本地模型是否启用
- if get_config_bool("enable_local_models", True):
- # 如果本地模型启用,获取所有模型(无论visibility是什么)
- models = await service.get_all_local_models()
- else:
- # 如果本地模型未启用,获取用户有权限的模型
- models = await service.get_user_local_models(current_user.id)
-
- return ApiResponse(
- code=200,
- message="success",
- data=[LocalModelResponse.from_model(m) for m in models]
- )
- @router.put("/{model_id}", response_model=ApiResponse[LocalModelResponse])
- async def update_local_model(
- model_id: int,
- request: LocalModelUpdate,
- current_admin: AdminUser = Depends(get_current_admin),
- db: Session = Depends(get_db)
- ):
- """
- 更新本地模型
-
- 需求 4.5: 管理员可以编辑本地模型的配置
- """
- try:
- service = LocalModelService(db)
- model = service.update_local_model(
- model_id=model_id,
- user_id=None,
- name=request.name,
- supplier=request.supplier,
- base_url=request.base_url,
- api_key=request.api_key,
- visibility=request.visibility,
- categories=request.categories
- )
- if not model:
- raise HTTPException(status_code=404, detail="模型不存在或无权限")
-
- # 异步清理缓存
- from app.services.cache_service import CacheService
- await CacheService.delete_model(model_id)
-
- return ApiResponse(code=200, message="success", data=LocalModelResponse.from_model(model))
- except HTTPException:
- raise
- except Exception as e:
- raise HTTPException(status_code=500, detail=f"Database error: {str(e)}")
- @router.delete("/{model_id}", response_model=ApiResponse[dict])
- async def delete_local_model(
- model_id: int,
- current_admin: AdminUser = Depends(get_current_admin),
- db: Session = Depends(get_db)
- ):
- """
- 删除本地模型
-
- 需求 4.6: 管理员可以删除本地模型
- 需求 4.7: 删除前需要确认
- """
- service = LocalModelService(db)
- success = service.delete_local_model(model_id, None) # 本地模型不关联用户
- if not success:
- raise HTTPException(status_code=404, detail="模型不存在或无权限")
-
- # 异步清理缓存
- from app.services.cache_service import CacheService
- await CacheService.delete_model(model_id)
-
- return ApiResponse(code=200, message="success", data={"success": True})
- @router.post("/test", response_model=ApiResponse[ConnectionTestResponse])
- async def test_connection(
- request: ConnectionTestRequest,
- db: Session = Depends(get_db),
- current_admin: AdminUser = Depends(get_current_admin)
- ):
- """
- 测试本地模型连接(管理员)
-
- 需求 2.5: 提供"测试连接"按钮
- 需求 2.6: 测试成功显示绿色提示
- 需求 2.7: 测试失败显示红色错误信息
- """
- service = LocalModelService(db)
- result = await service.test_connection(request.base_url, request.api_key, request.model_name, (request.categories or [0])[0])
- return ApiResponse(code=200, message="success", data=ConnectionTestResponse(**result))
- @router.post("/test-public", response_model=ApiResponse[ConnectionTestResponse])
- async def test_connection_public(
- request: ConnectionTestRequest,
- db: Session = Depends(get_db),
- current_user: User = Depends(get_current_user)
- ):
- """
- 测试本地模型连接(普通用户)
-
- 需求 2.5: 提供"测试连接"按钮
- 需求 2.6: 测试成功显示绿色提示
- 需求 2.7: 测试失败显示红色错误信息
- """
- # 检查本地模型是否启用
- if not get_config_bool("enable_local_models", False):
- raise HTTPException(
- status_code=status.HTTP_403_FORBIDDEN,
- detail="本地模型功能已关闭"
- )
-
- service = LocalModelService(db)
- result = await service.test_connection(request.base_url, request.api_key, request.model_name, (request.categories or [0])[0])
- return ApiResponse(code=200, message="success", data=ConnectionTestResponse(**result))
|