FA3-Datafetch/backend/app/fetchers/factory.py
2026-01-11 21:33:47 +08:00

107 lines
3.6 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.

"""
Fetcher Factory - Backend Version
Currently supports CN market with Tushare
"""
import os
class FetcherFactory:
"""
数据获取工厂类 (Backend版本)
当前支持的数据源:
- Tushare: CN (中国A股)
- iFinD: HK, JP, US, VN
- Bloomberg: CN, HK, JP, US, VN
"""
@staticmethod
def get_fetcher(market: str, data_source: str = None, **kwargs):
"""
获取对应市场和数据源的 Fetcher
Args:
market: 市场代码 (CN, HK, JP, US, VN)
data_source: 数据源名称 (iFinD, Tushare, Bloomberg)
**kwargs: 额外参数(如 API tokens
Returns:
Fetcher 实例
"""
market = market.upper()
# 如果未指定数据源,使用默认值
if not data_source:
data_source = FetcherFactory._get_default_source(market)
elif data_source == 'iFinD':
return FetcherFactory._get_ifind_fetcher(market, **kwargs)
elif data_source == 'Bloomberg':
return FetcherFactory._get_bloomberg_fetcher(market, **kwargs)
else:
# 其他数据源暂未迁移
raise NotImplementedError(
f"Data source '{data_source}' not supported in backend."
)
@staticmethod
def _get_default_source(market: str) -> str:
"""获取市场的默认数据源"""
defaults = {
'CN': 'Tushare',
'HK': 'iFinD',
'JP': 'iFinD',
'US': 'iFinD',
'VN': 'iFinD'
}
return defaults.get(market, 'iFinD')
@staticmethod
def _get_tushare_fetcher(market: str, **kwargs):
"""获取 Tushare Fetcher"""
if market != 'CN':
raise ValueError("Tushare only supports CN market")
# 获取 Tushare token
tushare_token = kwargs.get('tushare_token') or os.getenv('TUSHARE_TOKEN')
if not tushare_token:
raise ValueError("Tushare token is required for CN market")
from app.fetchers.cn_fetcher import CnFetcher
return CnFetcher(tushare_token)
@staticmethod
def _get_ifind_fetcher(market: str, **kwargs):
"""Get iFinD Fetcher"""
ifind_token = kwargs.get('ifind_token') or os.getenv('IFIND_REFRESH_TOKEN')
if not ifind_token:
# Try legacy env var name if needed, but IFIND_REFRESH_TOKEN is standard
ifind_token = os.getenv('IFIND_REFRESH_TOKEN')
if not ifind_token:
raise ValueError("iFinD refresh token is required (IFIND_REFRESH_TOKEN)")
if market == 'HK':
from app.fetchers.hk_fetcher import HkFetcher
return HkFetcher(ifind_token)
elif market == 'JP':
from app.fetchers.jp_fetcher import JpFetcher
return JpFetcher(ifind_token)
elif market == 'VN':
from app.fetchers.vn_fetcher import VnFetcher
return VnFetcher(ifind_token)
elif market == 'US':
from app.fetchers.us_fetcher import UsFetcher
return UsFetcher(ifind_token)
else:
raise NotImplementedError(f"iFinD fetcher for market {market} not yet migrated to backend.")
@staticmethod
def _get_bloomberg_fetcher(market: str, **kwargs):
"""Get Bloomberg Fetcher"""
# Bloomberg client typically uses internal auth (password based) or default keys.
# We can pass kwargs but default init handles env vars.
from app.fetchers.bloomberg_fetcher import BloombergFetcher
return BloombergFetcher(market=market)