main:删除多余文档并清理项目目录

变更内容:
- 移除冗余文档,包括 Grafana 指南、指标对比、修复总结、OpenAPI 规范等。
- 精简项目文档结构,优化 README 文件内容。
- 提升文档层次清晰度,集中核心指南。
This commit is contained in:
2026-02-02 14:59:34 +08:00
parent 3254fdc3f0
commit 5feb795d12
23 changed files with 3763 additions and 960 deletions

View File

@@ -1,5 +1,6 @@
"""API 数据模型"""
from enum import Enum
from pydantic import BaseModel, Field, ConfigDict
from typing import Any, Dict, Optional
@@ -7,13 +8,7 @@ from typing import Any, Dict, Optional
class InvokeRequest(BaseModel):
"""同步调用请求"""
model_config = ConfigDict(
json_schema_extra={
"example": {
"number": 17
}
}
)
model_config = ConfigDict(json_schema_extra={"example": {"number": 17}})
number: int = Field(..., description="待判断的整数")
@@ -30,13 +25,13 @@ class InvokeResponse(BaseModel):
"number": 17,
"is_prime": True,
"factors": [],
"algorithm": "trial_division"
"algorithm": "trial_division",
},
"metadata": {
"algorithm": "PrimeChecker",
"version": "1.0.0",
"elapsed_time": 0.001
}
"elapsed_time": 0.001,
},
}
}
)
@@ -71,7 +66,7 @@ class ErrorResponse(BaseModel):
"error": "VALIDATION_ERROR",
"message": "number must be an integer",
"details": {"field": "number", "value": "abc"},
"request_id": "550e8400-e29b-41d4-a716-446655440000"
"request_id": "550e8400-e29b-41d4-a716-446655440000",
}
}
)
@@ -80,3 +75,80 @@ class ErrorResponse(BaseModel):
message: str = Field(..., description="错误消息")
details: Optional[Dict[str, Any]] = Field(None, description="错误详情")
request_id: Optional[str] = Field(None, description="请求ID")
class JobStatus(str, Enum):
"""任务状态枚举"""
PENDING = "pending" # 等待执行
RUNNING = "running" # 执行中
COMPLETED = "completed" # 已完成
FAILED = "failed" # 执行失败
class JobRequest(BaseModel):
"""异步任务请求"""
model_config = ConfigDict(
json_schema_extra={
"example": {
"algorithm": "PrimeChecker",
"params": {"number": 17},
"webhook": "https://example.com/callback",
}
}
)
algorithm: str = Field(..., description="算法名称")
params: Dict[str, Any] = Field(..., description="算法参数")
webhook: Optional[str] = Field(None, description="回调 URL")
class JobCreateResponse(BaseModel):
"""任务创建响应"""
model_config = ConfigDict(
json_schema_extra={
"example": {
"job_id": "a1b2c3d4e5f6",
"status": "pending",
"message": "任务已创建",
"created_at": "2026-02-02T10:00:00Z",
}
}
)
job_id: str = Field(..., description="任务唯一标识")
status: JobStatus = Field(..., description="任务状态")
message: str = Field(..., description="状态消息")
created_at: str = Field(..., description="创建时间ISO 8601")
class JobStatusResponse(BaseModel):
"""任务状态查询响应"""
model_config = ConfigDict(
json_schema_extra={
"example": {
"job_id": "a1b2c3d4e5f6",
"status": "completed",
"algorithm": "PrimeChecker",
"created_at": "2026-02-02T10:00:00Z",
"started_at": "2026-02-02T10:00:01Z",
"completed_at": "2026-02-02T10:00:02Z",
"result": {"number": 17, "is_prime": True},
"error": None,
"metadata": {"elapsed_time": 0.001},
}
}
)
job_id: str = Field(..., description="任务唯一标识")
status: JobStatus = Field(..., description="任务状态")
algorithm: str = Field(..., description="算法名称")
created_at: str = Field(..., description="创建时间ISO 8601")
started_at: Optional[str] = Field(None, description="开始执行时间ISO 8601")
completed_at: Optional[str] = Field(None, description="完成时间ISO 8601")
result: Optional[Dict[str, Any]] = Field(None, description="执行结果(仅完成时返回)")
error: Optional[str] = Field(None, description="错误信息(仅失败时返回)")
metadata: Optional[Dict[str, Any]] = Field(None, description="元数据信息")

View File

@@ -1,7 +1,7 @@
"""API 路由"""
import asyncio
from fastapi import APIRouter, HTTPException, Depends, status
from fastapi.responses import JSONResponse
import time
import logging
@@ -11,10 +11,15 @@ from .models import (
HealthResponse,
ReadinessResponse,
ErrorResponse,
JobRequest,
JobCreateResponse,
JobStatusResponse,
JobStatus,
)
from .dependencies import get_request_id
from ..algorithms.prime_checker import PrimeChecker
from ..core.errors import FunctionalScaffoldError, ValidationError, AlgorithmError
from ..core.errors import ValidationError, AlgorithmError
from ..core.job_manager import get_job_manager
logger = logging.getLogger(__name__)
@@ -134,17 +139,156 @@ async def readiness_check():
@router.post(
"/jobs",
status_code=status.HTTP_501_NOT_IMPLEMENTED,
summary="异步任务接口(预留)",
description="异步任务接口,当前版本未实现",
response_model=JobCreateResponse,
status_code=status.HTTP_202_ACCEPTED,
summary="创建异步任务",
description="创建异步任务,立即返回任务 ID任务在后台执行",
responses={
202: {"description": "任务已创建", "model": JobCreateResponse},
400: {"description": "请求参数错误", "model": ErrorResponse},
404: {"description": "算法不存在", "model": ErrorResponse},
503: {"description": "服务不可用", "model": ErrorResponse},
},
)
async def create_job():
async def create_job(
request: JobRequest,
request_id: str = Depends(get_request_id),
):
"""
异步任务接口(预留)
创建异步任务
用于提交长时间运行的任务
- **algorithm**: 算法名称(如 PrimeChecker
- **params**: 算法参数
- **webhook**: 任务完成后的回调 URL可选
"""
raise HTTPException(
status_code=status.HTTP_501_NOT_IMPLEMENTED,
detail={"error": "NOT_IMPLEMENTED", "message": "Async jobs not implemented yet"},
)
try:
job_manager = await get_job_manager()
# 检查任务管理器是否可用
if not job_manager.is_available():
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail={
"error": "SERVICE_UNAVAILABLE",
"message": "任务服务暂不可用,请稍后重试",
"request_id": request_id,
},
)
# 验证算法存在
available_algorithms = job_manager.get_available_algorithms()
if request.algorithm not in available_algorithms:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={
"error": "ALGORITHM_NOT_FOUND",
"message": f"算法 '{request.algorithm}' 不存在",
"details": {"available_algorithms": available_algorithms},
"request_id": request_id,
},
)
# 创建任务
job_id = await job_manager.create_job(
algorithm=request.algorithm,
params=request.params,
webhook=request.webhook,
request_id=request_id,
)
# 获取任务信息
job_data = await job_manager.get_job(job_id)
# 后台执行任务
asyncio.create_task(job_manager.execute_job(job_id))
logger.info(f"异步任务已创建: job_id={job_id}, request_id={request_id}")
return JobCreateResponse(
job_id=job_id,
status=JobStatus.PENDING,
message="任务已创建",
created_at=job_data["created_at"],
)
except HTTPException:
raise
except Exception as e:
logger.error(f"创建任务失败: {str(e)}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail={
"error": "INTERNAL_ERROR",
"message": str(e),
"request_id": request_id,
},
)
@router.get(
"/jobs/{job_id}",
response_model=JobStatusResponse,
summary="查询任务状态",
description="查询异步任务的执行状态和结果",
responses={
200: {"description": "成功", "model": JobStatusResponse},
404: {"description": "任务不存在或已过期", "model": ErrorResponse},
503: {"description": "服务不可用", "model": ErrorResponse},
},
)
async def get_job_status(job_id: str):
"""
查询任务状态
- **job_id**: 任务唯一标识
"""
try:
job_manager = await get_job_manager()
# 检查任务管理器是否可用
if not job_manager.is_available():
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail={
"error": "SERVICE_UNAVAILABLE",
"message": "任务服务暂不可用,请稍后重试",
},
)
# 获取任务信息
job_data = await job_manager.get_job(job_id)
if not job_data:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={
"error": "JOB_NOT_FOUND",
"message": f"任务 '{job_id}' 不存在或已过期",
},
)
return JobStatusResponse(
job_id=job_data["job_id"],
status=JobStatus(job_data["status"]),
algorithm=job_data["algorithm"],
created_at=job_data["created_at"],
started_at=job_data["started_at"],
completed_at=job_data["completed_at"],
result=job_data["result"],
error=job_data["error"],
metadata=job_data["metadata"],
)
except HTTPException:
raise
except Exception as e:
logger.error(f"查询任务状态失败: {str(e)}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail={
"error": "INTERNAL_ERROR",
"message": str(e),
},
)