65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
import asyncio
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
import yaml
|
|
from pydantic import BaseModel, Field
|
|
from pydantic_settings import BaseSettings
|
|
|
|
|
|
class FHobSettings(BaseModel):
|
|
symbols: list[str] = Field(
|
|
default_factory=list,
|
|
description="Trading pairs to subscribe to. Empty = no subscriptions. oe_em adds pairs via REST.",
|
|
)
|
|
log_level: str = Field(default="INFO", description="Logging level")
|
|
log_file: Path = Field(
|
|
default=Path("/tmp/fh_ob.log"),
|
|
description="Path to log file. Logs are written here in addition to stdout.",
|
|
)
|
|
socket_path: Path = Field(
|
|
default=Path("/tmp/fh_ob.sock"),
|
|
description="Unix domain socket path for OE+EM",
|
|
)
|
|
rest_host: str = Field(default="0.0.0.0", description="FastAPI debug host")
|
|
rest_port: int = Field(default=8000, description="FastAPI debug port")
|
|
ws_url: str = Field(
|
|
default="wss://ws-api-spot.kucoin.com",
|
|
description="KuCoin WebSocket endpoint",
|
|
)
|
|
token_url: str = Field(
|
|
default="https://api.kucoin.com/api/v1/bullet-public",
|
|
description="KuCoin public token endpoint",
|
|
)
|
|
reconnect_base_delay: float = Field(
|
|
default=1.0,
|
|
description="Base delay for reconnect exponential backoff (seconds)",
|
|
)
|
|
reconnect_max_delay: float = Field(
|
|
default=60.0,
|
|
description="Max delay for reconnect exponential backoff (seconds)",
|
|
)
|
|
heartbeat_interval: float = Field(
|
|
default=18.0,
|
|
description="WS ping interval (seconds) - KuCoin uses 18s",
|
|
)
|
|
|
|
|
|
class Settings(BaseSettings):
|
|
fh_ob: FHobSettings = Field(default_factory=FHobSettings)
|
|
|
|
@classmethod
|
|
async def from_yaml(cls, path: Path) -> "Settings":
|
|
loop = asyncio.get_running_loop()
|
|
|
|
def _read() -> dict:
|
|
with open(path) as f:
|
|
return yaml.safe_load(f) or {}
|
|
|
|
data = await loop.run_in_executor(None, _read)
|
|
fh_ob_data = data.get("fh_ob", {})
|
|
if fh_ob_data.get("symbols") is None:
|
|
fh_ob_data["symbols"] = []
|
|
return cls(**data)
|
|
|
|
model_config = {"env_prefix": "TRIARB_", "extra": "ignore"} |