You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.2 KiB

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))