Port `binance` backend to `httpx`
parent
44b8c70521
commit
4c486e6dd2
|
@ -43,7 +43,7 @@ import trio
|
||||||
from pendulum import (
|
from pendulum import (
|
||||||
now,
|
now,
|
||||||
)
|
)
|
||||||
import asks
|
import httpx
|
||||||
from rapidfuzz import process as fuzzy
|
from rapidfuzz import process as fuzzy
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ def binance_timestamp(
|
||||||
|
|
||||||
class Client:
|
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
|
Supports all of the spot, margin and futures endpoints depending
|
||||||
on method.
|
on method.
|
||||||
|
@ -158,6 +158,7 @@ class Client:
|
||||||
|
|
||||||
# TODO: change this to `Client.[mkt_]venue: MarketType`?
|
# TODO: change this to `Client.[mkt_]venue: MarketType`?
|
||||||
mkt_mode: MarketType = 'spot',
|
mkt_mode: MarketType = 'spot',
|
||||||
|
httpx_client: httpx.AsyncClient,
|
||||||
|
|
||||||
) -> None:
|
) -> None:
|
||||||
# build out pair info tables for each market type
|
# build out pair info tables for each market type
|
||||||
|
@ -186,23 +187,7 @@ class Client:
|
||||||
# market symbols for use by search. See `.exch_info()`.
|
# market symbols for use by search. See `.exch_info()`.
|
||||||
self._pairs: ChainMap[str, Pair] = ChainMap()
|
self._pairs: ChainMap[str, Pair] = ChainMap()
|
||||||
|
|
||||||
# spot EPs sesh
|
self._create_sessions(httpx_client)
|
||||||
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
|
|
||||||
|
|
||||||
# global client "venue selection" mode.
|
# global client "venue selection" mode.
|
||||||
# set this when you want to switch venues and not have to
|
# set this when you want to switch venues and not have to
|
||||||
|
@ -212,7 +197,7 @@ class Client:
|
||||||
# per 8
|
# per 8
|
||||||
self.venue_sesh: dict[
|
self.venue_sesh: dict[
|
||||||
str, # venue key
|
str, # venue key
|
||||||
tuple[asks.Session, str] # session, eps path
|
tuple[httpx.AsyncClient, str] # session, eps path
|
||||||
] = {
|
] = {
|
||||||
'spot': (self._sesh, '/api/v3/'),
|
'spot': (self._sesh, '/api/v3/'),
|
||||||
'spot_testnet': (self._test_sesh, '/fapi/v1/'),
|
'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
|
# https://www.binance.com/en/support/faq/how-to-create-api-keys-on-binance-360002502072
|
||||||
self.conf: dict = get_config()
|
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():
|
for key, subconf in self.conf.items():
|
||||||
if api_key := subconf.get('api_key', ''):
|
if api_key := subconf.get('api_key', ''):
|
||||||
venue_keys: list[str] = self.confkey2venuekeys[key]
|
venue_keys: list[str] = self.confkey2venuekeys[key]
|
||||||
|
|
||||||
venue_key: str
|
venue_key: str
|
||||||
sesh: asks.Session
|
sesh: httpx.AsyncClient
|
||||||
for venue_key in venue_keys:
|
for venue_key in venue_keys:
|
||||||
sesh, _ = self.venue_sesh[venue_key]
|
sesh, _ = self.venue_sesh[venue_key]
|
||||||
|
|
||||||
|
@ -272,6 +266,26 @@ class Client:
|
||||||
]
|
]
|
||||||
testnet_sesh.headers.update(api_key_header)
|
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(
|
def _mk_sig(
|
||||||
self,
|
self,
|
||||||
data: dict,
|
data: dict,
|
||||||
|
@ -360,7 +374,7 @@ class Client:
|
||||||
venue=venue_key,
|
venue=venue_key,
|
||||||
)
|
)
|
||||||
|
|
||||||
sesh: asks.Session
|
sesh: httpx.AsyncClient
|
||||||
path: str
|
path: str
|
||||||
|
|
||||||
# Check if we're configured to route order requests to the
|
# Check if we're configured to route order requests to the
|
||||||
|
|
Loading…
Reference in New Issue