add exchangeInfo symbol validation
This commit is contained in:
62
app/src/integrations/exchange/rest_client.py
Normal file
62
app/src/integrations/exchange/rest_client.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.parse import urlencode
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
from src.core.config import load_settings
|
||||
from src.integrations.exchange.exceptions import (
|
||||
ExchangeConnectionError,
|
||||
ExchangeResponseError,
|
||||
)
|
||||
|
||||
|
||||
class ExchangeRestClient:
|
||||
def __init__(self) -> None:
|
||||
self.settings = load_settings()
|
||||
if not self.settings.exchange_base_url:
|
||||
raise ExchangeConnectionError("EXCHANGE_BASE_URL is empty.")
|
||||
self.base_url = self.settings.exchange_base_url.rstrip("/")
|
||||
self.timeout = self.settings.exchange_timeout_sec
|
||||
|
||||
def get_json(self, path: str, params: dict[str, str] | None = None) -> dict:
|
||||
query = f"?{urlencode(params)}" if params else ""
|
||||
url = f"{self.base_url}{path}{query}"
|
||||
|
||||
request = Request(
|
||||
url=url,
|
||||
method="GET",
|
||||
headers={
|
||||
"Accept": "application/json",
|
||||
"User-Agent": "dzentra-bot/2.0.0",
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
with urlopen(request, timeout=self.timeout) as response:
|
||||
status = getattr(response, "status", 200)
|
||||
body = response.read().decode("utf-8")
|
||||
except HTTPError as exc:
|
||||
raise ExchangeResponseError(
|
||||
f"HTTP {exc.code} from exchange: {exc.reason}"
|
||||
) from exc
|
||||
except URLError as exc:
|
||||
raise ExchangeConnectionError(
|
||||
f"Network error while calling exchange: {exc.reason}"
|
||||
) from exc
|
||||
except TimeoutError as exc:
|
||||
raise ExchangeConnectionError("Timeout while calling exchange.") from exc
|
||||
|
||||
if status != 200:
|
||||
raise ExchangeResponseError(f"Unexpected HTTP status: {status}")
|
||||
|
||||
try:
|
||||
payload = json.loads(body)
|
||||
except json.JSONDecodeError as exc:
|
||||
raise ExchangeResponseError("Exchange returned non-JSON response.") from exc
|
||||
|
||||
if not isinstance(payload, dict):
|
||||
raise ExchangeResponseError("Exchange response is not a JSON object.")
|
||||
|
||||
return payload
|
||||
Reference in New Issue
Block a user