from __future__ import annotations from pathlib import Path from datahub.adapters.tushare import TushareAdapter from datahub.admin_api import AdminAPI from datahub.auth import AuthService from datahub.crypto import SecretVault from datahub.db import HubDB from datahub.governance.circuit import CircuitBreaker from datahub.governance.lkg import LastKnownGood from datahub.governance.ratelimit import TokenBucket from datahub.pipeline import Pipeline from datahub.scheduler import Scheduler from datahub.serving import V1API from datahub.settings import Settings, load_settings class Hub: def __init__(self, settings: Settings, adapter: TushareAdapter | None = None) -> None: if not settings.encryption_key: raise SystemExit("DATAHUB_ENCRYPTION_KEY 未配置") self.settings = settings self.db = HubDB(settings.db_path) self.vault = SecretVault(settings.encryption_key) self.auth = AuthService(self.db, self.vault, settings.api_token, settings.admin_password) token = settings.tushare_token or self.auth.load_credential("tushare_token") if settings.tushare_token: self.auth.store_credential("tushare_token", settings.tushare_token) token = settings.tushare_token self.adapter = adapter or TushareAdapter(token) self.pipeline = Pipeline( self.db, self.adapter, settings, bucket=TokenBucket(settings.tushare_rate_per_minute), breaker=CircuitBreaker(), ) self.lkg = LastKnownGood(self.db) self.scheduler = Scheduler(self.db, self.pipeline) self.api = V1API(self.db, self.pipeline, settings) self.admin = AdminAPI(self.db, self.pipeline, self.scheduler, self.auth) self.static_dir = Path(__file__).resolve().parents[1] / "admin" def start(self) -> None: if self.settings.scheduler_enabled: self.scheduler.start() def stop(self) -> None: self.scheduler.stop() def build_hub(settings: Settings | None = None) -> Hub: return Hub(settings or load_settings())