Fundamental_Analysis/backend/app/services/external_api_service.py

322 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
外部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