from fastapi import APIRouter, Query, Depends from typing import List, Optional from loguru import logger from models import ( MarketOverview, MarketIndex, PriceDistribution, Stock, DataSourceType, ApiResponse, DataSource, ) from adapters import DataAdapterFactory router = APIRouter(prefix="/market", tags=["市场数据"]) def get_data_source(source: Optional[str] = Query(None, description="数据源")) -> DataSourceType: if source: try: return DataSourceType(source) except ValueError: logger.warning(f"Invalid data source: {source}, using default") return DataSourceType.EASTMONEY @router.get("/overview", response_model=ApiResponse, summary="获取市场概况") async def get_market_overview( source: DataSourceType = Depends(get_data_source) ): try: adapter = DataAdapterFactory.get_adapter(source) data = await adapter.fetch_market_overview() return ApiResponse( success=True, data=data.model_dump(), message=f"数据来源: {adapter.name}", ) except Exception as e: logger.error(f"Failed to fetch market overview: {e}") return ApiResponse(success=False, error=str(e)) @router.get("/indices", response_model=ApiResponse, summary="获取市场指数") async def get_market_indices( source: DataSourceType = Depends(get_data_source) ): try: adapter = DataAdapterFactory.get_adapter(source) data = await adapter.fetch_market_indices() return ApiResponse( success=True, data=[item.model_dump() for item in data], message=f"数据来源: {adapter.name}", ) except Exception as e: logger.error(f"Failed to fetch market indices: {e}") return ApiResponse(success=False, error=str(e)) @router.get("/distribution", response_model=ApiResponse, summary="获取涨跌幅分布") async def get_price_distribution( source: DataSourceType = Depends(get_data_source) ): try: adapter = DataAdapterFactory.get_adapter(source) data = await adapter.fetch_price_distribution() return ApiResponse( success=True, data=[item.model_dump() for item in data], message=f"数据来源: {adapter.name}", ) except Exception as e: logger.error(f"Failed to fetch price distribution: {e}") return ApiResponse(success=False, error=str(e)) @router.get("/hot-stocks", response_model=ApiResponse, summary="获取热门股票") async def get_hot_stocks( limit: int = Query(10, ge=1, le=50, description="返回数量"), source: DataSourceType = Depends(get_data_source) ): try: adapter = DataAdapterFactory.get_adapter(source) data = await adapter.fetch_hot_stocks(limit) return ApiResponse( success=True, data=[item.model_dump() for item in data], message=f"数据来源: {adapter.name}", ) except Exception as e: logger.error(f"Failed to fetch hot stocks: {e}") return ApiResponse(success=False, error=str(e)) @router.get("/cold-stocks", response_model=ApiResponse, summary="获取冷门股票") async def get_cold_stocks( limit: int = Query(10, ge=1, le=50, description="返回数量"), source: DataSourceType = Depends(get_data_source) ): try: adapter = DataAdapterFactory.get_adapter(source) data = await adapter.fetch_cold_stocks(limit) return ApiResponse( success=True, data=[item.model_dump() for item in data], message=f"数据来源: {adapter.name}", ) except Exception as e: logger.error(f"Failed to fetch cold stocks: {e}") return ApiResponse(success=False, error=str(e)) @router.get("/sources", response_model=ApiResponse, summary="获取可用数据源") async def get_data_sources(): try: sources = await DataAdapterFactory.get_available_sources() return ApiResponse( success=True, data=[item.model_dump() for item in sources], ) except Exception as e: logger.error(f"Failed to fetch data sources: {e}") return ApiResponse(success=False, error=str(e))