feat(V2): URL exchange configurabili da .env (DERIBIT_URL_*, BYBIT_URL_*, ecc.)
This commit is contained in:
@@ -14,35 +14,43 @@ async def build_client(
|
||||
if exchange == "deribit":
|
||||
from cerbero_mcp.exchanges.deribit.client import DeribitClient
|
||||
|
||||
url = settings.deribit.url_testnet if env == "testnet" else settings.deribit.url_live
|
||||
return DeribitClient(
|
||||
client_id=settings.deribit.client_id,
|
||||
client_secret=settings.deribit.client_secret.get_secret_value(),
|
||||
testnet=(env == "testnet"),
|
||||
base_url_override=url,
|
||||
)
|
||||
if exchange == "bybit":
|
||||
from cerbero_mcp.exchanges.bybit.client import BybitClient
|
||||
|
||||
url = settings.bybit.url_testnet if env == "testnet" else settings.bybit.url_live
|
||||
return BybitClient(
|
||||
api_key=settings.bybit.api_key,
|
||||
api_secret=settings.bybit.api_secret.get_secret_value(),
|
||||
testnet=(env == "testnet"),
|
||||
base_url=url,
|
||||
)
|
||||
if exchange == "hyperliquid":
|
||||
from cerbero_mcp.exchanges.hyperliquid.client import HyperliquidClient
|
||||
|
||||
url = settings.hyperliquid.url_testnet if env == "testnet" else settings.hyperliquid.url_live
|
||||
return HyperliquidClient(
|
||||
wallet_address=settings.hyperliquid.wallet_address,
|
||||
private_key=settings.hyperliquid.private_key.get_secret_value(),
|
||||
testnet=(env == "testnet"),
|
||||
api_wallet_address=settings.hyperliquid.api_wallet_address,
|
||||
base_url=url,
|
||||
)
|
||||
if exchange == "alpaca":
|
||||
from cerbero_mcp.exchanges.alpaca.client import AlpacaClient
|
||||
|
||||
url = settings.alpaca.url_testnet if env == "testnet" else settings.alpaca.url_live
|
||||
return AlpacaClient(
|
||||
api_key=settings.alpaca.api_key_id,
|
||||
secret_key=settings.alpaca.secret_key.get_secret_value(),
|
||||
paper=(env == "testnet"),
|
||||
base_url=url,
|
||||
)
|
||||
if exchange == "macro":
|
||||
# Read-only data provider — env ignored. Il registry
|
||||
|
||||
@@ -92,6 +92,7 @@ class AlpacaClient:
|
||||
api_key: str,
|
||||
secret_key: str,
|
||||
paper: bool = True,
|
||||
base_url: str | None = None,
|
||||
trading: Any | None = None,
|
||||
stock_data: Any | None = None,
|
||||
crypto_data: Any | None = None,
|
||||
@@ -100,9 +101,18 @@ class AlpacaClient:
|
||||
self.api_key = api_key
|
||||
self.secret_key = secret_key
|
||||
self.paper = paper
|
||||
self._trading = trading or TradingClient(
|
||||
api_key=api_key, secret_key=secret_key, paper=paper
|
||||
)
|
||||
self.base_url = base_url
|
||||
# alpaca-py TradingClient accetta `url_override` per override URL trading.
|
||||
# Data clients (Stock/Crypto/Option) non supportano url_override sul costruttore;
|
||||
# usano endpoint dati separati (data.alpaca.markets) — `base_url` è ignorato per essi.
|
||||
if trading is None:
|
||||
trading_kwargs: dict[str, Any] = {
|
||||
"api_key": api_key, "secret_key": secret_key, "paper": paper,
|
||||
}
|
||||
if base_url:
|
||||
trading_kwargs["url_override"] = base_url
|
||||
trading = TradingClient(**trading_kwargs)
|
||||
self._trading = trading
|
||||
self._stock = stock_data or StockHistoricalDataClient(
|
||||
api_key=api_key, secret_key=secret_key
|
||||
)
|
||||
|
||||
@@ -30,15 +30,24 @@ class BybitClient:
|
||||
api_secret: str,
|
||||
testnet: bool = True,
|
||||
http: Any | None = None,
|
||||
base_url: str | None = None,
|
||||
) -> None:
|
||||
self.api_key = api_key
|
||||
self.api_secret = api_secret
|
||||
self.testnet = testnet
|
||||
self._http = http or HTTP(
|
||||
api_key=api_key,
|
||||
api_secret=api_secret,
|
||||
testnet=testnet,
|
||||
)
|
||||
# pybit HTTP non accetta `endpoint` come kwarg (vedi _V5HTTPManager.__init__:
|
||||
# solo `domain`/`tld`/`testnet`). Override URL applicato post-init
|
||||
# sovrascrivendo l'attributo `endpoint` dell'istanza HTTP.
|
||||
self.base_url = base_url
|
||||
if http is None:
|
||||
http = HTTP(
|
||||
api_key=api_key,
|
||||
api_secret=api_secret,
|
||||
testnet=testnet,
|
||||
)
|
||||
if base_url:
|
||||
http.endpoint = base_url
|
||||
self._http = http
|
||||
|
||||
async def _run(self, fn, /, **kwargs):
|
||||
return await asyncio.to_thread(fn, **kwargs)
|
||||
|
||||
@@ -28,11 +28,14 @@ class DeribitClient:
|
||||
client_id: str
|
||||
client_secret: str
|
||||
testnet: bool = True
|
||||
base_url_override: str | None = None
|
||||
_token: str | None = field(default=None, init=False, repr=False)
|
||||
_token_expires_at: float = field(default=0.0, init=False, repr=False)
|
||||
|
||||
@property
|
||||
def base_url(self) -> str:
|
||||
if self.base_url_override:
|
||||
return self.base_url_override
|
||||
return BASE_TESTNET if self.testnet else BASE_LIVE
|
||||
|
||||
# ── Auth ─────────────────────────────────────────────────────
|
||||
|
||||
@@ -52,12 +52,17 @@ class HyperliquidClient:
|
||||
private_key: str,
|
||||
testnet: bool = True,
|
||||
api_wallet_address: str | None = None,
|
||||
base_url: str | None = None,
|
||||
):
|
||||
self.wallet_address = wallet_address
|
||||
self.private_key = private_key
|
||||
self.testnet = testnet
|
||||
self.api_wallet_address = api_wallet_address or wallet_address
|
||||
self.base_url = BASE_TESTNET if testnet else BASE_LIVE
|
||||
self._base_url_override = base_url
|
||||
if base_url:
|
||||
self.base_url = base_url
|
||||
else:
|
||||
self.base_url = BASE_TESTNET if testnet else BASE_LIVE
|
||||
self._exchange: Any | None = None
|
||||
|
||||
# ── SDK exchange (lazy) ────────────────────────────────────
|
||||
@@ -70,13 +75,16 @@ class HyperliquidClient:
|
||||
)
|
||||
if self._exchange is None:
|
||||
account = Account.from_key(self.private_key)
|
||||
base_url = (
|
||||
hl_constants.TESTNET_API_URL if self.testnet else hl_constants.MAINNET_API_URL
|
||||
)
|
||||
if self._base_url_override:
|
||||
sdk_base_url = self._base_url_override
|
||||
else:
|
||||
sdk_base_url = (
|
||||
hl_constants.TESTNET_API_URL if self.testnet else hl_constants.MAINNET_API_URL
|
||||
)
|
||||
empty_spot_meta: dict[str, Any] = {"universe": [], "tokens": []}
|
||||
self._exchange = Exchange(
|
||||
account,
|
||||
base_url,
|
||||
sdk_base_url,
|
||||
account_address=self.wallet_address,
|
||||
spot_meta=empty_spot_meta,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user