Files
xiaobai-review/backend/application.py

179 lines
6.6 KiB
Python

from __future__ import annotations
import threading
from datetime import datetime
from http.server import BaseHTTPRequestHandler
from api_access import ROUTES
from backend.bootstrap.config import DATA_DIR, MENTOR_SKILLS_DIR, PRIVATE_MENTOR_SKILLS_DIR
from backend.bootstrap.container import build_application_container
from backend.bootstrap.settings import load_runtime_settings
from backend.data.providers.tushare_client import TushareError
from backend.features.accounts.application import AccountApplicationMixin
from backend.features.accounts.http import AccountHttpMixin
from backend.features.accounts.routes import AccountRoutesMixin
from backend.features.accounts.security import SecretVault
from backend.features.accounts.service import AccountService
from backend.features.alerts import AlertHttpMixin, AlertServiceMixin
from backend.features.alerts.routes import AlertRoutesMixin
from backend.features.auction import AuctionServiceMixin
from backend.features.auction.routes import AuctionRoutesMixin
from backend.features.dragon_tiger import DragonTigerServiceMixin
from backend.features.dragon_tiger.routes import DragonTigerRoutesMixin
from backend.features.heaven import HeavenHttpMixin, HeavenServiceMixin, build_personal_field
from backend.features.heaven.routes import HeavenRoutesMixin
from backend.features.market import MarketServiceMixin
from backend.features.market.routes import MarketRoutesMixin
from backend.features.mentor import MentorHttpMixin, MentorServiceMixin
from backend.features.mentor.routes import MentorRoutesMixin
from backend.features.pools import PoolServiceMixin
from backend.features.pools.routes import PoolRoutesMixin
from backend.features.popularity import PopularityServiceMixin
from backend.features.popularity.routes import PopularityRoutesMixin
from backend.features.review import ReviewHttpMixin, ReviewServiceMixin
from backend.features.review.routes import ReviewRoutesMixin
from backend.features.rotation import RotationServiceMixin
from backend.features.rotation.routes import RotationRoutesMixin
from backend.features.screener.routes import ScreenerRoutesMixin
from backend.features.screener.service import (
SCREENER_LIBRARY_VERSION,
ScreenerServiceMixin,
automatic_screener_jobs,
)
from backend.features.sentiment import SentimentServiceMixin
from backend.features.sentiment.routes import SentimentRoutesMixin
from backend.features.system import SystemHttpMixin
from backend.features.system.routes import SystemRoutesMixin
from backend.features.system.service import SystemServiceMixin
from backend.features.themes import ThemeServiceMixin
from backend.features.themes.routes import ThemeRoutesMixin
from backend.http import HttpTransportMixin
from backend.http.dispatch import (
AUTHENTICATED_POST_HANDLERS,
PUBLIC_POST_HANDLERS,
ApplicationHttpDispatchMixin,
)
from backend.jobs.service import JobServiceMixin
from backend.llm import LLMGateway
from backend.llm.http import LLMHttpMixin
from backend.llm.service import LLMServiceMixin
from database import ReviewDatabase
LEGACY_SECRET_KEYS = {
"TUSHARE_TOKEN",
"IFIND_REFRESH_TOKEN",
"IFIND_ACCESS_TOKEN",
"LLM_API_KEY",
"LLM_BASE_URL",
"LLM_MODEL",
"LLM_PRIMARY_API_KEY",
"LLM_PRIMARY_BASE_URL",
"LLM_PRIMARY_MODEL",
"LLM_FALLBACK_API_KEY",
"LLM_FALLBACK_BASE_URL",
"LLM_FALLBACK_MODEL",
}
class DashboardService(
SystemServiceMixin,
AccountApplicationMixin,
JobServiceMixin,
MarketServiceMixin,
SentimentServiceMixin,
PoolServiceMixin,
RotationServiceMixin,
AuctionServiceMixin,
ThemeServiceMixin,
PopularityServiceMixin,
DragonTigerServiceMixin,
ScreenerServiceMixin,
MentorServiceMixin,
HeavenServiceMixin,
AlertServiceMixin,
ReviewServiceMixin,
LLMServiceMixin,
):
def __init__(self) -> None:
runtime = load_runtime_settings()
self.vault = SecretVault(runtime.encryption_key)
self.database = ReviewDatabase(DATA_DIR / "review.db")
self.sync_lock = threading.Lock()
self.auth_lock = threading.Lock()
self.system_lock = threading.Lock()
self.auto_screener_lock = threading.Lock()
self._auto_screener_last_attempt: dict[str, datetime] = {}
self._ifind_event_lock = threading.Lock()
self._request_context = threading.local()
self.accounts = AccountService(
database=self.database,
vault=self.vault,
current_user_supplier=lambda: self.current_user_id,
access_supplier=lambda: getattr(self._request_context, "access", {}),
bind_user=self.bind_user,
personal_field_builder=build_personal_field,
auth_lock=self.auth_lock,
)
self._system_credentials = self._load_system_credentials(runtime.initial_credentials)
self.container = build_application_container(
self.database,
self._system_credentials,
MENTOR_SKILLS_DIR,
PRIVATE_MENTOR_SKILLS_DIR,
lambda: self.token,
)
self.data_gateway = self.container.data_gateway
self.ifind = self.container.ifind
self.screener = self.container.screener
self.strategy_tracking = self.container.strategy_tracking
self.alert_service = self.container.alert_service
self.trade_journal = self.container.trade_journal
self.mentor_skills = self.container.mentor_skills
self.realtime_aggregator = self.container.realtime_aggregator
self.chart_data = self.container.chart_data
self.jobs = self.container.jobs
self.llm_gateway = LLMGateway(
database=self.database,
user_id_supplier=lambda: self.current_user_id,
membership_supplier=self.membership,
settings_supplier=lambda: self._system_credentials,
profile_supplier=self._resolved_llm_profile,
)
self.screener.ensure_builtin_strategies()
SERVICE = DashboardService()
class RequestHandler(
SystemRoutesMixin,
AccountRoutesMixin,
AlertRoutesMixin,
ReviewRoutesMixin,
MarketRoutesMixin,
AuctionRoutesMixin,
ThemeRoutesMixin,
PopularityRoutesMixin,
SentimentRoutesMixin,
RotationRoutesMixin,
DragonTigerRoutesMixin,
ScreenerRoutesMixin,
MentorRoutesMixin,
HeavenRoutesMixin,
PoolRoutesMixin,
AccountHttpMixin,
SystemHttpMixin,
MentorHttpMixin,
HeavenHttpMixin,
AlertHttpMixin,
ReviewHttpMixin,
LLMHttpMixin,
ApplicationHttpDispatchMixin,
HttpTransportMixin,
BaseHTTPRequestHandler,
):
server_version = "XiaobaiReviewWeb/0.8"
application_service = SERVICE
route_registry = ROUTES