""" AmazingData 数据服务平台 - Pydantic 数据模型 """ from pydantic import BaseModel, Field from typing import Optional, List, Dict, Any from datetime import datetime from enum import Enum # ==================== 通用响应模型 ==================== class ResponseCode(int, Enum): SUCCESS = 200 ERROR = 500 UNAUTHORIZED = 401 FORBIDDEN = 403 NOT_FOUND = 404 class BaseResponse(BaseModel): """基础响应模型""" code: int = ResponseCode.SUCCESS message: str = "success" data: Optional[Any] = None # ==================== 认证模型 ==================== class LoginRequest(BaseModel): """登录请求""" username: str = Field(..., min_length=3, max_length=50) password: str = Field(..., min_length=6) class LoginResponse(BaseModel): """登录响应""" access_token: str token_type: str = "bearer" user_info: Dict[str, Any] class UserInfo(BaseModel): """用户信息""" id: int username: str role: str is_active: bool last_login: Optional[datetime] # ==================== 历史数据模型 ==================== class PeriodEnum(str, Enum): """K线周期枚举""" DAILY = "day" MIN1 = "min1" MIN5 = "min5" MIN15 = "min15" MIN30 = "min30" MIN60 = "min60" class SingleKlineRequest(BaseModel): """单只K线请求""" code: str = Field(..., description="代码,如 000001.SZ 或 ag2605.SHF") trading_day: Optional[str] = Field(None, description="交易日,格式 YYYYMMDD,默认最近交易日") period: PeriodEnum = Field(PeriodEnum.DAILY, description="K线周期") save_path: Optional[str] = Field("./data/single", description="保存路径") class BatchStockRequest(BaseModel): """批量股票请求""" codes: Optional[List[str]] = Field(None, description="股票代码列表,None表示全部A股") trading_days: Optional[List[str]] = Field(None, description="交易日列表") save_path: Optional[str] = Field("./data/stock", description="保存路径") batch_size: int = Field(100, description="批次大小") class BatchFutureRequest(BaseModel): """批量期货请求""" underlying_codes: Optional[List[str]] = Field(None, description="品种代码列表") use_main_contract: bool = Field(True, description="是否使用主力合约") trading_days: Optional[List[str]] = Field(None, description="交易日列表") save_path: Optional[str] = Field("./data/future", description="保存路径") class KlineDataResponse(BaseModel): """K线数据响应""" code: str trading_day: str period: str count: int data: List[Dict[str, Any]] file_path: str # ==================== 实时订阅模型 ==================== class SubscribePeriodEnum(str, Enum): """订阅周期枚举""" MIN1 = "min1" MIN5 = "min5" MIN15 = "min15" MIN30 = "min30" MIN60 = "min60" class SubscribeRequest(BaseModel): """订阅请求""" codes: List[str] = Field(..., description="品种代码列表") periods: List[SubscribePeriodEnum] = Field([SubscribePeriodEnum.MIN5], description="订阅周期") save_path: Optional[str] = Field("./data/realtime", description="保存路径") duration: int = Field(0, description="运行时长(秒),0=无限") save_interval: int = Field(60, description="保存间隔(秒)") task_name: Optional[str] = Field(None, description="任务名称") class SubscribeResponse(BaseModel): """订阅响应""" task_id: int task_name: str status: str message: str class TaskStatus(BaseModel): """任务状态""" id: int task_name: str codes: List[str] periods: List[str] status: str started_at: Optional[datetime] stopped_at: Optional[datetime] created_at: datetime # ==================== 批量任务模型 ==================== class BatchTaskRequest(BaseModel): """批量任务请求""" task_type: str = Field(..., description="任务类型: stock/future") codes: Optional[List[str]] = Field(None, description="代码列表") use_main_contract: bool = Field(True, description="是否主力合约") trading_days: Optional[List[str]] = Field(None, description="交易日列表") save_path: Optional[str] = Field("./data/batch", description="保存路径") batch_size: int = Field(100, description="批次大小") class BatchTaskStatus(BaseModel): """批量任务状态""" id: int task_type: str total_count: int processed_count: int success_count: int failed_count: int status: str output_path: Optional[str] error_message: Optional[str] started_at: Optional[datetime] completed_at: Optional[datetime] # ==================== 缓存管理模型 ==================== class CacheFileItem(BaseModel): """缓存文件项""" id: int filename: str file_type: str trading_day: Optional[str] code: Optional[str] period: Optional[str] record_count: int file_size: int file_path: str created_at: datetime class CacheStats(BaseModel): """缓存统计""" total_files: int total_size: int by_type: Dict[str, int] by_day: Dict[str, int] # ==================== 系统配置模型 ==================== class ConfigItem(BaseModel): """配置项""" id: int config_key: str config_value: str config_type: str description: Optional[str] class ConfigUpdateRequest(BaseModel): """配置更新请求""" config_value: str class TestConnectionResponse(BaseModel): """连接测试响应""" success: bool message: str details: Optional[Dict[str, Any]] = None