322 lines
13 KiB
Python
322 lines
13 KiB
Python
"""
|
||
外部API集成服务
|
||
统一管理所有外部API调用和数据源切换
|
||
"""
|
||
|
||
from typing import Dict, Any, Optional, List
|
||
import asyncio
|
||
from datetime import datetime
|
||
|
||
from .data_source_manager import DataSourceManager, create_data_source_manager
|
||
from ..core.config import api_config
|
||
from ..core.exceptions import (
|
||
DataSourceError,
|
||
AIAnalysisError,
|
||
ConfigurationError
|
||
)
|
||
from ..schemas.data import (
|
||
FinancialDataResponse,
|
||
MarketDataResponse,
|
||
SymbolValidationResponse,
|
||
DataSourcesStatusResponse
|
||
)
|
||
from ..schemas.report import AIAnalysisResponse
|
||
|
||
|
||
class ExternalAPIService:
|
||
"""外部API服务"""
|
||
|
||
def __init__(self):
|
||
self._data_source_manager: Optional[DataSourceManager] = None
|
||
self._initialize_manager()
|
||
|
||
def _initialize_manager(self):
|
||
"""初始化数据源管理器"""
|
||
try:
|
||
config = api_config.get_data_source_manager_config()
|
||
self._data_source_manager = create_data_source_manager(config)
|
||
except Exception as e:
|
||
print(f"警告: 初始化数据源管理器失败: {str(e)}")
|
||
|
||
async def get_financial_data(self, symbol: str, market: str, preferred_source: Optional[str] = None) -> FinancialDataResponse:
|
||
"""获取财务数据"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
try:
|
||
return await self._data_source_manager.fetch_financial_data(symbol, market, preferred_source)
|
||
except Exception as e:
|
||
raise DataSourceError(f"获取财务数据失败: {str(e)}", preferred_source or "unknown")
|
||
|
||
async def get_market_data(self, symbol: str, market: str, preferred_source: Optional[str] = None) -> MarketDataResponse:
|
||
"""获取市场数据"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
try:
|
||
return await self._data_source_manager.fetch_market_data(symbol, market, preferred_source)
|
||
except Exception as e:
|
||
raise DataSourceError(f"获取市场数据失败: {str(e)}", preferred_source or "unknown")
|
||
|
||
async def validate_stock_symbol(self, symbol: str, market: str, preferred_source: Optional[str] = None) -> SymbolValidationResponse:
|
||
"""验证股票代码"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
try:
|
||
return await self._data_source_manager.validate_symbol(symbol, market, preferred_source)
|
||
except Exception as e:
|
||
# 验证失败时返回无效结果而不是抛出异常
|
||
return SymbolValidationResponse(
|
||
symbol=symbol,
|
||
market=market,
|
||
is_valid=False,
|
||
message=f"验证失败: {str(e)}"
|
||
)
|
||
|
||
async def analyze_business_info(self, symbol: str, market: str, financial_data: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""分析公司业务信息"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"business_info", symbol, market, {"financial_data": financial_data}
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"业务信息分析失败: {str(e)}", "gemini")
|
||
|
||
async def analyze_fundamental(self, symbol: str, market: str, financial_data: Dict[str, Any], business_info: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""基本面分析"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
context_data = {
|
||
"financial_data": financial_data,
|
||
"business_info": business_info
|
||
}
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"fundamental_analysis", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"基本面分析失败: {str(e)}", "gemini")
|
||
|
||
async def analyze_bullish_case(self, symbol: str, market: str, context_data: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""看涨分析"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"bullish_analysis", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"看涨分析失败: {str(e)}", "gemini")
|
||
|
||
async def analyze_bearish_case(self, symbol: str, market: str, context_data: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""看跌分析"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"bearish_analysis", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"看跌分析失败: {str(e)}", "gemini")
|
||
|
||
async def analyze_market_sentiment(self, symbol: str, market: str, context_data: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""市场情绪分析"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"market_analysis", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"市场分析失败: {str(e)}", "gemini")
|
||
|
||
async def analyze_news_catalysts(self, symbol: str, market: str, context_data: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""新闻催化剂分析"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"news_analysis", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"新闻分析失败: {str(e)}", "gemini")
|
||
|
||
async def analyze_trading_dynamics(self, symbol: str, market: str, context_data: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""交易动态分析"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"trading_analysis", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"交易分析失败: {str(e)}", "gemini")
|
||
|
||
async def analyze_insider_institutional(self, symbol: str, market: str, context_data: Dict[str, Any]) -> AIAnalysisResponse:
|
||
"""内部人与机构动向分析"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"insider_analysis", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"内部人分析失败: {str(e)}", "gemini")
|
||
|
||
async def generate_final_conclusion(self, symbol: str, market: str, all_analyses: List[Dict[str, Any]]) -> AIAnalysisResponse:
|
||
"""生成最终结论"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
if not self._data_source_manager.is_ai_analyzer_available():
|
||
raise AIAnalysisError("AI分析器不可用", "gemini")
|
||
|
||
try:
|
||
context_data = {"all_analyses": all_analyses}
|
||
return await self._data_source_manager.analyze_with_ai(
|
||
"final_conclusion", symbol, market, context_data
|
||
)
|
||
except Exception as e:
|
||
raise AIAnalysisError(f"最终结论生成失败: {str(e)}", "gemini")
|
||
|
||
async def check_all_services_status(self) -> DataSourcesStatusResponse:
|
||
"""检查所有外部服务状态"""
|
||
if not self._data_source_manager:
|
||
raise ConfigurationError("数据源管理器未初始化")
|
||
|
||
try:
|
||
return await self._data_source_manager.check_all_sources_status()
|
||
except Exception as e:
|
||
raise DataSourceError(f"检查服务状态失败: {str(e)}")
|
||
|
||
def get_supported_data_sources(self) -> List[str]:
|
||
"""获取支持的数据源列表"""
|
||
if not self._data_source_manager:
|
||
return []
|
||
|
||
return self._data_source_manager.get_supported_sources()
|
||
|
||
def get_available_data_sources(self) -> List[str]:
|
||
"""获取当前可用的数据源列表"""
|
||
if not self._data_source_manager:
|
||
return []
|
||
|
||
return self._data_source_manager.get_available_sources()
|
||
|
||
def is_ai_service_available(self) -> bool:
|
||
"""检查AI服务是否可用"""
|
||
if not self._data_source_manager:
|
||
return False
|
||
|
||
return self._data_source_manager.is_ai_analyzer_available()
|
||
|
||
def get_data_source_for_market(self, market: str) -> str:
|
||
"""根据市场获取推荐的数据源"""
|
||
if not self._data_source_manager:
|
||
return "tushare" # 默认值
|
||
|
||
return self._data_source_manager.get_data_source_for_market(market)
|
||
|
||
def update_configuration(self, new_config: Dict[str, Any]):
|
||
"""更新配置"""
|
||
if self._data_source_manager:
|
||
self._data_source_manager.update_config(new_config)
|
||
else:
|
||
# 如果管理器未初始化,尝试重新初始化
|
||
self._initialize_manager()
|
||
|
||
async def test_data_source_connection(self, data_source: str, config: Dict[str, Any]) -> Dict[str, Any]:
|
||
"""测试数据源连接"""
|
||
try:
|
||
# 创建临时的数据获取器进行测试
|
||
from .data_fetcher import DataFetcherFactory
|
||
|
||
test_fetcher = DataFetcherFactory.create_fetcher(data_source, config)
|
||
status = await test_fetcher.check_status()
|
||
|
||
return {
|
||
"success": status.is_available,
|
||
"response_time_ms": status.response_time_ms,
|
||
"error_message": status.error_message
|
||
}
|
||
except Exception as e:
|
||
return {
|
||
"success": False,
|
||
"error_message": str(e)
|
||
}
|
||
|
||
async def test_ai_service_connection(self, service_type: str, config: Dict[str, Any]) -> Dict[str, Any]:
|
||
"""测试AI服务连接"""
|
||
try:
|
||
if service_type.lower() == "gemini":
|
||
from .ai_analyzer import AIAnalyzerFactory
|
||
|
||
test_analyzer = AIAnalyzerFactory.create_gemini_analyzer(
|
||
config.get("api_key"), config
|
||
)
|
||
|
||
# 简单的测试调用
|
||
start_time = datetime.now()
|
||
await test_analyzer._call_gemini_api("测试连接,请回答:OK")
|
||
end_time = datetime.now()
|
||
|
||
response_time = int((end_time - start_time).total_seconds() * 1000)
|
||
|
||
return {
|
||
"success": True,
|
||
"response_time_ms": response_time
|
||
}
|
||
else:
|
||
return {
|
||
"success": False,
|
||
"error_message": f"不支持的AI服务类型: {service_type}"
|
||
}
|
||
except Exception as e:
|
||
return {
|
||
"success": False,
|
||
"error_message": str(e)
|
||
}
|
||
|
||
|
||
# 创建全局服务实例
|
||
external_api_service = ExternalAPIService()
|
||
|
||
|
||
def get_external_api_service() -> ExternalAPIService:
|
||
"""获取外部API服务实例"""
|
||
return external_api_service |