Port `binance` backend to `httpx`

go_httpx_binance
Nelson Torres 2024-05-23 17:48:49 -03:00
parent 44b8c70521
commit 4c486e6dd2
1 changed files with 36 additions and 22 deletions

View File

@ -43,7 +43,7 @@ import trio
from pendulum import (
now,
)
import asks
import httpx
from rapidfuzz import process as fuzzy
import numpy as np
@ -147,7 +147,7 @@ def binance_timestamp(
class Client:
'''
Async ReST API client using ``trio`` + ``asks`` B)
Async ReST API client using ``trio`` + ``httpx`` B)
Supports all of the spot, margin and futures endpoints depending
on method.
@ -158,6 +158,7 @@ class Client:
# TODO: change this to `Client.[mkt_]venue: MarketType`?
mkt_mode: MarketType = 'spot',
httpx_client: httpx.AsyncClient,
) -> None:
# build out pair info tables for each market type
@ -186,23 +187,7 @@ class Client:
# market symbols for use by search. See `.exch_info()`.
self._pairs: ChainMap[str, Pair] = ChainMap()
# spot EPs sesh
self._sesh = asks.Session(connections=4)
self._sesh.base_location: str = _spot_url
# spot testnet
self._test_sesh: asks.Session = asks.Session(connections=4)
self._test_sesh.base_location: str = _testnet_spot_url
# margin and extended spot endpoints session.
self._sapi_sesh = asks.Session(connections=4)
self._sapi_sesh.base_location: str = _spot_url
# futes EPs sesh
self._fapi_sesh = asks.Session(connections=4)
self._fapi_sesh.base_location: str = _futes_url
# futes testnet
self._test_fapi_sesh: asks.Session = asks.Session(connections=4)
self._test_fapi_sesh.base_location: str = _testnet_futes_url
self._create_sessions(httpx_client)
# global client "venue selection" mode.
# set this when you want to switch venues and not have to
@ -212,7 +197,7 @@ class Client:
# per 8
self.venue_sesh: dict[
str, # venue key
tuple[asks.Session, str] # session, eps path
tuple[httpx.AsyncClient, str] # session, eps path
] = {
'spot': (self._sesh, '/api/v3/'),
'spot_testnet': (self._test_sesh, '/fapi/v1/'),
@ -242,12 +227,21 @@ class Client:
# https://www.binance.com/en/support/faq/how-to-create-api-keys-on-binance-360002502072
self.conf: dict = get_config()
self._setup_api_keys()
def _setup_api_keys(
self
) -> None:
"""
Set up API keys for the configured venues and sessions.
"""
for key, subconf in self.conf.items():
if api_key := subconf.get('api_key', ''):
venue_keys: list[str] = self.confkey2venuekeys[key]
venue_key: str
sesh: asks.Session
sesh: httpx.AsyncClient
for venue_key in venue_keys:
sesh, _ = self.venue_sesh[venue_key]
@ -272,6 +266,26 @@ class Client:
]
testnet_sesh.headers.update(api_key_header)
def _create_sessions(
self,
httpx_client: httpx.AsyncClient
) -> None:
"""
Create the necessary AsyncClient sessions for different endpoints.
"""
# spot EPs sesh
self._sesh: httpx.AsyncClient = httpx_client.AsyncClient(base_url=_spot_url)
# spot testnet
self._test_sesh: httpx.AsyncClient = httpx_client.AsyncClient(base_url=__testnet_spot_url)
# margin and extended spot endpoints session.
self._sapi_sesh: httpx.AsyncClient = httpx_client.AsyncClient(base_url=_spot_url)
# futes EPs sesh
self._fapi_sesh: httpx.AsyncClient = httpx_client.AsyncClient(base_url=_futes_url)
# futes testnet
self._test_fapi_sesh: httpx.AsyncClient = httpx_client.AsyncClient(base_url=_testnet_futes_url)
def _mk_sig(
self,
data: dict,
@ -360,7 +374,7 @@ class Client:
venue=venue_key,
)
sesh: asks.Session
sesh: httpx.AsyncClient
path: str
# Check if we're configured to route order requests to the