first commit

This commit is contained in:
2026-02-08 14:42:58 +08:00
commit 20e1deae21
8197 changed files with 2264639 additions and 0 deletions

View File

@@ -0,0 +1,569 @@
"""算法服务管理路由,提供服务注册、管理等功能"""
from fastapi import APIRouter, HTTPException, status, Depends
from typing import List, Dict, Any, Optional
from pydantic import BaseModel
import uuid
import os
from app.models.models import AlgorithmService
from app.models.database import SessionLocal
from app.routes.user import get_current_active_user
from app.services.project_analyzer import ProjectAnalyzer
from app.services.service_generator import ServiceGenerator
from app.services.service_orchestrator import ServiceOrchestrator
router = APIRouter(prefix="/services", tags=["services"])
class RegisterServiceRequest(BaseModel):
"""注册服务请求"""
repository_id: str
name: str
version: str = "1.0.0"
service_type: str = "http"
host: str = "0.0.0.0"
port: int = 8000
timeout: int = 30
health_check_path: str = "/health"
environment: Dict[str, str] = {}
class ServiceResponse(BaseModel):
"""服务响应"""
id: str
service_id: str
name: str
algorithm_name: str
version: str
host: str
port: int
api_url: str
status: str
created_at: str
updated_at: str
class ServiceListResponse(BaseModel):
"""服务列表响应"""
success: bool
services: List[ServiceResponse]
class ServiceDetailResponse(BaseModel):
"""服务详情响应"""
success: bool
service: ServiceResponse
class ServiceOperationResponse(BaseModel):
"""服务操作响应"""
success: bool
message: str
service_id: str
status: str
class ServiceStatusResponse(BaseModel):
"""服务状态响应"""
success: bool
status: str
health: str
class ServiceLogsResponse(BaseModel):
"""服务日志响应"""
success: bool
logs: List[str]
class RepositoryAlgorithmsResponse(BaseModel):
"""仓库算法列表响应"""
success: bool
algorithms: List[Dict[str, Any]]
# 初始化服务组件
project_analyzer = ProjectAnalyzer()
service_generator = ServiceGenerator()
service_orchestrator = ServiceOrchestrator()
@router.post("/register", status_code=status.HTTP_201_CREATED)
async def register_service(
request: RegisterServiceRequest,
current_user: dict = Depends(get_current_active_user)
):
"""注册新服务"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 1. 获取仓库信息
# 注意:在实际实现中,应该从数据库中获取仓库信息
# 这里简化处理,假设仓库存在
# 2. 分析项目
repo_path = f"/tmp/repository_{request.repository_id}"
# 注意:在实际实现中,应该从算法仓库中获取项目文件
# 这里简化处理,创建一个模拟的项目结构
os.makedirs(repo_path, exist_ok=True)
# 创建模拟的算法文件
with open(os.path.join(repo_path, "algorithm.py"), "w") as f:
f.write("""
def predict(data):
return {"result": "Prediction result", "input": data}
def run(data):
return {"result": "Run result", "input": data}
def main(data):
return {"result": "Main result", "input": data}
""")
# 分析项目
project_info = project_analyzer.analyze_project(repo_path)
if not project_info["success"]:
raise HTTPException(status_code=400, detail=f"项目分析失败: {project_info['error']}")
# 3. 生成服务包装器
service_config = {
"name": request.name,
"version": request.version,
"service_type": request.service_type,
"host": request.host,
"port": request.port,
"timeout": request.timeout,
"health_check_path": request.health_check_path,
"environment": request.environment
}
generate_result = service_generator.generate_service(project_info, service_config)
if not generate_result["success"]:
raise HTTPException(status_code=400, detail=f"服务生成失败: {generate_result['error']}")
# 4. 部署服务
service_id = str(uuid.uuid4())
deploy_result = service_orchestrator.deploy_service(service_id, service_config, project_info)
if not deploy_result["success"]:
raise HTTPException(status_code=400, detail=f"服务部署失败: {deploy_result['error']}")
# 5. 保存服务信息到数据库
new_service = AlgorithmService(
id=str(uuid.uuid4()),
service_id=service_id,
name=request.name,
algorithm_name="algorithm", # 注意:在实际实现中,应该从仓库信息中获取
version=request.version,
host=request.host,
port=request.port,
api_url=deploy_result["api_url"],
status=deploy_result["status"],
config={
"service_type": request.service_type,
"timeout": request.timeout,
"health_check_path": request.health_check_path,
"environment": request.environment,
"container_id": deploy_result["container_id"]
}
)
db.add(new_service)
db.commit()
db.refresh(new_service)
# 6. 返回响应
return {
"success": True,
"message": "服务注册成功",
"service": {
"id": new_service.id,
"service_id": new_service.service_id,
"name": new_service.name,
"algorithm_name": new_service.algorithm_name,
"version": new_service.version,
"host": new_service.host,
"port": new_service.port,
"api_url": new_service.api_url,
"status": new_service.status,
"created_at": new_service.created_at.isoformat(),
"updated_at": new_service.updated_at.isoformat()
}
}
finally:
db.close()
@router.get("", response_model=ServiceListResponse)
async def list_services(
current_user: dict = Depends(get_current_active_user)
):
"""获取服务列表"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务列表
services = db.query(AlgorithmService).all()
# 转换为响应格式
service_list = []
for service in services:
service_list.append(ServiceResponse(
id=service.id,
service_id=service.service_id,
name=service.name,
algorithm_name=service.algorithm_name,
version=service.version,
host=service.host,
port=service.port,
api_url=service.api_url,
status=service.status,
created_at=service.created_at.isoformat(),
updated_at=service.updated_at.isoformat()
))
return ServiceListResponse(
success=True,
services=service_list
)
finally:
db.close()
@router.get("/{service_id}", response_model=ServiceDetailResponse)
async def get_service(
service_id: str,
current_user: dict = Depends(get_current_active_user)
):
"""获取服务详情"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务
service = db.query(AlgorithmService).filter(AlgorithmService.service_id == service_id).first()
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# 返回响应
return ServiceDetailResponse(
success=True,
service=ServiceResponse(
id=service.id,
service_id=service.service_id,
name=service.name,
algorithm_name=service.algorithm_name,
version=service.version,
host=service.host,
port=service.port,
api_url=service.api_url,
status=service.status,
created_at=service.created_at.isoformat(),
updated_at=service.updated_at.isoformat()
)
)
finally:
db.close()
@router.post("/{service_id}/start")
async def start_service(
service_id: str,
current_user: dict = Depends(get_current_active_user)
):
"""启动服务"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务
service = db.query(AlgorithmService).filter(AlgorithmService.service_id == service_id).first()
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# 获取容器ID
container_id = service.config.get("container_id")
if not container_id:
raise HTTPException(status_code=400, detail="Container ID not found")
# 启动服务
start_result = service_orchestrator.start_service(service_id, container_id)
if not start_result["success"]:
raise HTTPException(status_code=400, detail=f"服务启动失败: {start_result['error']}")
# 更新服务状态
service.status = start_result["status"]
db.commit()
# 返回响应
return ServiceOperationResponse(
success=True,
message="服务启动成功",
service_id=service_id,
status=start_result["status"]
)
finally:
db.close()
@router.post("/{service_id}/stop")
async def stop_service(
service_id: str,
current_user: dict = Depends(get_current_active_user)
):
"""停止服务"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务
service = db.query(AlgorithmService).filter(AlgorithmService.service_id == service_id).first()
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# 获取容器ID
container_id = service.config.get("container_id")
if not container_id:
raise HTTPException(status_code=400, detail="Container ID not found")
# 停止服务
stop_result = service_orchestrator.stop_service(service_id, container_id)
if not stop_result["success"]:
raise HTTPException(status_code=400, detail=f"服务停止失败: {stop_result['error']}")
# 更新服务状态
service.status = stop_result["status"]
db.commit()
# 返回响应
return ServiceOperationResponse(
success=True,
message="服务停止成功",
service_id=service_id,
status=stop_result["status"]
)
finally:
db.close()
@router.post("/{service_id}/restart")
async def restart_service(
service_id: str,
current_user: dict = Depends(get_current_active_user)
):
"""重启服务"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务
service = db.query(AlgorithmService).filter(AlgorithmService.service_id == service_id).first()
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# 获取容器ID
container_id = service.config.get("container_id")
if not container_id:
raise HTTPException(status_code=400, detail="Container ID not found")
# 重启服务
restart_result = service_orchestrator.restart_service(service_id, container_id)
if not restart_result["success"]:
raise HTTPException(status_code=400, detail=f"服务重启失败: {restart_result['error']}")
# 更新服务状态
service.status = restart_result["status"]
db.commit()
# 返回响应
return ServiceOperationResponse(
success=True,
message="服务重启成功",
service_id=service_id,
status=restart_result["status"]
)
finally:
db.close()
@router.delete("/{service_id}")
async def delete_service(
service_id: str,
current_user: dict = Depends(get_current_active_user)
):
"""删除服务"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务
service = db.query(AlgorithmService).filter(AlgorithmService.service_id == service_id).first()
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# 获取容器ID和镜像名称
container_id = service.config.get("container_id")
image_name = f"algorithm-service-{service_id}:{service.version}"
# 删除服务
delete_result = service_orchestrator.delete_service(service_id, container_id, image_name)
if not delete_result["success"]:
# 继续执行即使Docker操作失败
pass
# 删除数据库记录
db.delete(service)
db.commit()
# 返回响应
return {
"success": True,
"message": "服务删除成功",
"service_id": service_id
}
finally:
db.close()
@router.get("/{service_id}/status")
async def get_service_status(
service_id: str,
current_user: dict = Depends(get_current_active_user)
):
"""获取服务状态"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务
service = db.query(AlgorithmService).filter(AlgorithmService.service_id == service_id).first()
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# 获取容器ID
container_id = service.config.get("container_id")
if not container_id:
raise HTTPException(status_code=400, detail="Container ID not found")
# 获取服务状态
status_result = service_orchestrator.get_service_status(container_id)
if not status_result["success"]:
raise HTTPException(status_code=400, detail=f"获取服务状态失败: {status_result['error']}")
# 返回响应
return ServiceStatusResponse(
success=True,
status=status_result["status"],
health=status_result["health"]
)
finally:
db.close()
@router.get("/{service_id}/logs")
async def get_service_logs(
service_id: str,
lines: int = 100,
current_user: dict = Depends(get_current_active_user)
):
"""获取服务日志"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
# 创建数据库会话
db = SessionLocal()
try:
# 查询服务
service = db.query(AlgorithmService).filter(AlgorithmService.service_id == service_id).first()
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# 获取容器ID
container_id = service.config.get("container_id")
if not container_id:
raise HTTPException(status_code=400, detail="Container ID not found")
# 获取服务日志
logs_result = service_orchestrator.get_service_logs(container_id, lines)
if not logs_result["success"]:
raise HTTPException(status_code=400, detail=f"获取服务日志失败: {logs_result['error']}")
# 返回响应
return ServiceLogsResponse(
success=True,
logs=logs_result["logs"]
)
finally:
db.close()
@router.get("/repository/algorithms")
async def get_repository_algorithms(
repository_id: str,
current_user: dict = Depends(get_current_active_user)
):
"""获取仓库中的算法列表"""
# 检查用户权限
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="Insufficient permissions")
try:
# 模拟获取仓库中的算法列表
# 注意:在实际实现中,应该从算法仓库中获取真实的算法列表
algorithms = [
{
"id": "alg-001",
"name": "图像分类算法",
"description": "基于深度学习的图像分类算法",
"type": "computer_vision",
"entry_point": "algorithm.py"
},
{
"id": "alg-002",
"name": "文本分类算法",
"description": "基于BERT的文本分类算法",
"type": "nlp",
"entry_point": "text_algorithm.py"
}
]
return RepositoryAlgorithmsResponse(
success=True,
algorithms=algorithms
)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))