You've already forked DataMate
Develop py update schema (#37)
* feature: implement endpoints with multi-level response models * refactor: move `/health` and `/config` endpoints to system module, remove example from base schemas * refactor: remove unused get_standard_response_model()
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
from .system.interface import router as system_router
|
||||||
from .annotation.interface import router as annotation_router
|
from .annotation.interface import router as annotation_router
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/api"
|
prefix="/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
router.include_router(system_router)
|
||||||
router.include_router(annotation_router)
|
router.include_router(annotation_router)
|
||||||
|
|
||||||
__all__ = ["router"]
|
__all__ = ["router"]
|
||||||
@@ -108,8 +108,7 @@ async def create_mapping(
|
|||||||
response_data = DatasetMappingCreateResponse(
|
response_data = DatasetMappingCreateResponse(
|
||||||
id=mapping.id,
|
id=mapping.id,
|
||||||
labeling_project_id=str(mapping.labeling_project_id),
|
labeling_project_id=str(mapping.labeling_project_id),
|
||||||
labeling_project_name=mapping.name or project_name,
|
labeling_project_name=mapping.name or project_name
|
||||||
message="Dataset mapping created successfully"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return StandardResponse(
|
return StandardResponse(
|
||||||
@@ -341,8 +340,7 @@ async def delete_mapping(
|
|||||||
message="success",
|
message="success",
|
||||||
data=DeleteDatasetResponse(
|
data=DeleteDatasetResponse(
|
||||||
id=id,
|
id=id,
|
||||||
status="success",
|
status="success"
|
||||||
message=f"Successfully deleted mapping and Label Studio project '{labeling_project_name}'"
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
from .mapping import (
|
from .mapping import (
|
||||||
DatasetMappingBase,
|
_DatasetMappingBase,
|
||||||
DatasetMappingCreateRequest,
|
DatasetMappingCreateRequest,
|
||||||
DatasetMappingCreateResponse,
|
DatasetMappingCreateResponse,
|
||||||
DatasetMappingUpdateRequest,
|
DatasetMappingUpdateRequest,
|
||||||
DatasetMappingResponse,
|
DatasetMappingResponse,
|
||||||
DeleteDatasetResponse
|
DeleteDatasetResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .sync import (
|
from .sync import (
|
||||||
SyncDatasetRequest,
|
SyncDatasetRequest,
|
||||||
SyncDatasetResponse
|
SyncDatasetResponse,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"DatasetMappingBase",
|
"_DatasetMappingBase",
|
||||||
"DatasetMappingCreateRequest",
|
"DatasetMappingCreateRequest",
|
||||||
"DatasetMappingCreateResponse",
|
"DatasetMappingCreateResponse",
|
||||||
"DatasetMappingUpdateRequest",
|
"DatasetMappingUpdateRequest",
|
||||||
"DatasetMappingResponse",
|
"DatasetMappingResponse",
|
||||||
"SyncDatasetRequest",
|
"SyncDatasetRequest",
|
||||||
"SyncDatasetResponse",
|
"SyncDatasetResponse",
|
||||||
"DeleteDatasetResponse"
|
"DeleteDatasetResponse",
|
||||||
]
|
]
|
||||||
@@ -3,12 +3,13 @@ from typing import Optional
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from app.module.shared.schema import BaseResponseModel
|
from app.module.shared.schema import BaseResponseModel
|
||||||
|
from app.module.shared.schema import StandardResponse
|
||||||
|
|
||||||
class DatasetMappingBase(BaseResponseModel):
|
class _DatasetMappingBase(BaseResponseModel):
|
||||||
"""数据集映射 基础模型"""
|
"""数据集映射 基础模型"""
|
||||||
dataset_id: str = Field(..., description="源数据集ID")
|
dataset_id: str = Field(..., description="源数据集ID")
|
||||||
|
|
||||||
class DatasetMappingCreateRequest(DatasetMappingBase):
|
class DatasetMappingCreateRequest(_DatasetMappingBase):
|
||||||
"""数据集映射 创建 请求模型"""
|
"""数据集映射 创建 请求模型"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -17,13 +18,12 @@ class DatasetMappingCreateResponse(BaseResponseModel):
|
|||||||
id: str = Field(..., description="映射UUID")
|
id: str = Field(..., description="映射UUID")
|
||||||
labeling_project_id: str = Field(..., description="Label Studio项目ID")
|
labeling_project_id: str = Field(..., description="Label Studio项目ID")
|
||||||
labeling_project_name: str = Field(..., description="Label Studio项目名称")
|
labeling_project_name: str = Field(..., description="Label Studio项目名称")
|
||||||
message: str = Field(..., description="响应消息")
|
|
||||||
|
|
||||||
class DatasetMappingUpdateRequest(BaseResponseModel):
|
class DatasetMappingUpdateRequest(BaseResponseModel):
|
||||||
"""数据集映射 更新 请求模型"""
|
"""数据集映射 更新 请求模型"""
|
||||||
dataset_id: Optional[str] = Field(None, description="源数据集ID")
|
dataset_id: Optional[str] = Field(None, description="源数据集ID")
|
||||||
|
|
||||||
class DatasetMappingResponse(DatasetMappingBase):
|
class DatasetMappingResponse(_DatasetMappingBase):
|
||||||
"""数据集映射 查询 响应模型"""
|
"""数据集映射 查询 响应模型"""
|
||||||
id: str = Field(..., description="映射UUID")
|
id: str = Field(..., description="映射UUID")
|
||||||
labeling_project_id: str = Field(..., description="标注项目ID")
|
labeling_project_id: str = Field(..., description="标注项目ID")
|
||||||
@@ -38,5 +38,4 @@ class DatasetMappingResponse(DatasetMappingBase):
|
|||||||
class DeleteDatasetResponse(BaseResponseModel):
|
class DeleteDatasetResponse(BaseResponseModel):
|
||||||
"""删除数据集响应模型"""
|
"""删除数据集响应模型"""
|
||||||
id: str = Field(..., description="映射UUID")
|
id: str = Field(..., description="映射UUID")
|
||||||
status: str = Field(..., description="删除状态")
|
status: str = Field(..., description="删除状态")
|
||||||
message: str = Field(..., description="响应消息")
|
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from typing import Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from app.module.shared.schema import BaseResponseModel
|
from app.module.shared.schema import BaseResponseModel
|
||||||
|
from app.module.shared.schema import StandardResponse
|
||||||
|
|
||||||
|
|
||||||
class SyncDatasetRequest(BaseResponseModel):
|
class SyncDatasetRequest(BaseResponseModel):
|
||||||
@@ -17,3 +16,6 @@ class SyncDatasetResponse(BaseResponseModel):
|
|||||||
synced_files: int = Field(..., description="已同步文件数量")
|
synced_files: int = Field(..., description="已同步文件数量")
|
||||||
total_files: int = Field(0, description="总文件数量")
|
total_files: int = Field(0, description="总文件数量")
|
||||||
message: str = Field(..., description="响应消息")
|
message: str = Field(..., description="响应消息")
|
||||||
|
|
||||||
|
class SyncDatasetResponseStd(StandardResponse[SyncDatasetResponse]):
|
||||||
|
pass
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
from fastapi import APIRouter
|
|
||||||
from typing import Dict, Any
|
|
||||||
from app.core.config import settings
|
|
||||||
from app.schemas import StandardResponse
|
|
||||||
|
|
||||||
router = APIRouter()
|
|
||||||
|
|
||||||
@router.get("/health", response_model=StandardResponse[Dict[str, Any]])
|
|
||||||
async def health_check():
|
|
||||||
"""健康检查端点"""
|
|
||||||
return StandardResponse(
|
|
||||||
code=200,
|
|
||||||
message="success",
|
|
||||||
data={
|
|
||||||
"status": "healthy",
|
|
||||||
"service": "Label Studio Adapter",
|
|
||||||
"version": settings.app_version
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
@router.get("/config", response_model=StandardResponse[Dict[str, Any]])
|
|
||||||
async def get_config():
|
|
||||||
"""获取配置信息"""
|
|
||||||
return StandardResponse(
|
|
||||||
code=200,
|
|
||||||
message="success",
|
|
||||||
data={
|
|
||||||
"app_name": settings.app_name,
|
|
||||||
"version": settings.app_version,
|
|
||||||
"label_studio_url": settings.label_studio_base_url,
|
|
||||||
"debug": settings.debug
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
通用响应模型
|
通用响应模型
|
||||||
"""
|
"""
|
||||||
from typing import Generic, TypeVar, Optional, List
|
from typing import Generic, TypeVar, Optional, List, Type
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
# 定义泛型类型变量
|
# 定义泛型类型变量
|
||||||
@@ -29,18 +29,11 @@ class StandardResponse(BaseResponseModel, Generic[T]):
|
|||||||
"""
|
"""
|
||||||
code: int = Field(..., description="HTTP状态码")
|
code: int = Field(..., description="HTTP状态码")
|
||||||
message: str = Field(..., description="响应消息")
|
message: str = Field(..., description="响应消息")
|
||||||
data: Optional[T] = Field(None, description="响应数据")
|
data: T = Field(..., description="响应数据")
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
populate_by_name = True
|
populate_by_name = True
|
||||||
alias_generator = to_camel
|
alias_generator = to_camel
|
||||||
json_schema_extra = {
|
|
||||||
"example": {
|
|
||||||
"code": 200,
|
|
||||||
"message": "success",
|
|
||||||
"data": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PaginatedData(BaseResponseModel, Generic[T]):
|
class PaginatedData(BaseResponseModel, Generic[T]):
|
||||||
"""分页数据容器"""
|
"""分页数据容器"""
|
||||||
@@ -49,14 +42,3 @@ class PaginatedData(BaseResponseModel, Generic[T]):
|
|||||||
total_elements: int = Field(..., description="总条数")
|
total_elements: int = Field(..., description="总条数")
|
||||||
total_pages: int = Field(..., description="总页数")
|
total_pages: int = Field(..., description="总页数")
|
||||||
content: List[T] = Field(..., description="当前页数据")
|
content: List[T] = Field(..., description="当前页数据")
|
||||||
|
|
||||||
class Config:
|
|
||||||
json_schema_extra = {
|
|
||||||
"example": {
|
|
||||||
"page": 1,
|
|
||||||
"size": 20,
|
|
||||||
"totalElements": 100,
|
|
||||||
"totalPages": 5,
|
|
||||||
"content": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
|
from .about import router as about_router
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
router.include_router(about_router)
|
||||||
36
runtime/datamate-python/app/module/system/interface/about.py
Normal file
36
runtime/datamate-python/app/module/system/interface/about.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
from typing import Dict, Any
|
||||||
|
from app.core.config import settings
|
||||||
|
from app.module.shared.schema import StandardResponse
|
||||||
|
|
||||||
|
from ..schema import ConfigResponse, HealthResponse
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.get("/health", response_model=StandardResponse[HealthResponse])
|
||||||
|
async def health_check():
|
||||||
|
"""健康检查端点"""
|
||||||
|
|
||||||
|
return StandardResponse(
|
||||||
|
code=200,
|
||||||
|
message="success",
|
||||||
|
data=HealthResponse(
|
||||||
|
status="healthy",
|
||||||
|
service="Label Studio Adapter",
|
||||||
|
version=settings.app_version
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@router.get("/config", response_model=StandardResponse[ConfigResponse])
|
||||||
|
async def get_config():
|
||||||
|
"""获取配置信息"""
|
||||||
|
return StandardResponse(
|
||||||
|
code=200,
|
||||||
|
message="success",
|
||||||
|
data=ConfigResponse(
|
||||||
|
app_name=settings.app_name,
|
||||||
|
version=settings.app_version,
|
||||||
|
label_studio_url=settings.label_studio_base_url,
|
||||||
|
debug=settings.debug
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
from .config import ConfigResponse
|
||||||
|
from .health import HealthResponse
|
||||||
|
|
||||||
|
__all__ = ["ConfigResponse", "HealthResponse"]
|
||||||
11
runtime/datamate-python/app/module/system/schema/config.py
Normal file
11
runtime/datamate-python/app/module/system/schema/config.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from pydantic import Field
|
||||||
|
|
||||||
|
from app.module.shared.schema import BaseResponseModel
|
||||||
|
from app.module.shared.schema import StandardResponse
|
||||||
|
|
||||||
|
class ConfigResponse(BaseResponseModel):
|
||||||
|
"""配置信息响应模型"""
|
||||||
|
app_name: str = Field(..., description="应用名称")
|
||||||
|
version: str = Field(..., description="应用版本")
|
||||||
|
label_studio_url: str = Field(..., description="Label Studio基础URL")
|
||||||
|
debug: bool = Field(..., description="调试模式状态")
|
||||||
10
runtime/datamate-python/app/module/system/schema/health.py
Normal file
10
runtime/datamate-python/app/module/system/schema/health.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from pydantic import Field
|
||||||
|
|
||||||
|
from app.module.shared.schema import BaseResponseModel
|
||||||
|
from app.module.shared.schema import StandardResponse
|
||||||
|
|
||||||
|
class HealthResponse(BaseResponseModel):
|
||||||
|
"""健康检查响应模型"""
|
||||||
|
status: str = Field(..., description="服务状态")
|
||||||
|
service: str = Field(..., description="服务名称")
|
||||||
|
version: str = Field(..., description="应用版本")
|
||||||
Reference in New Issue
Block a user