107 lines
3.6 KiB
Python
107 lines
3.6 KiB
Python
"""
|
||
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)
|