json_rpc_auth_wrapper
parent
df8d1274ae
commit
89e241c132
|
@ -236,6 +236,39 @@ class Client:
|
||||||
|
|
||||||
self.json_rpc = json_rpc
|
self.json_rpc = json_rpc
|
||||||
|
|
||||||
|
self._auth_ts = None
|
||||||
|
self._auth_renew_ts = 5 # seconds to renew auth
|
||||||
|
|
||||||
|
async def _json_rpc_auth_wrapper(self, *args, **kwargs) -> JSONRPCResult:
|
||||||
|
|
||||||
|
"""Background task that adquires a first access token and then will
|
||||||
|
refresh the access token.
|
||||||
|
|
||||||
|
https://docs.deribit.com/?python#authentication-2
|
||||||
|
"""
|
||||||
|
access_scope = 'trade:read_write'
|
||||||
|
current_ts = time.time()
|
||||||
|
|
||||||
|
if not self._auth_ts or current_ts - self._auth_ts < self._auth_renew_ts:
|
||||||
|
# if we are close to token expiry time
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'grant_type': 'client_credentials',
|
||||||
|
'client_id': self._key_id,
|
||||||
|
'client_secret': self._key_secret,
|
||||||
|
'scope': access_scope
|
||||||
|
}
|
||||||
|
|
||||||
|
resp = await self.json_rpc('public/auth', params)
|
||||||
|
result = resp.result
|
||||||
|
|
||||||
|
self._auth_ts = time.time() + result['expires_in']
|
||||||
|
|
||||||
|
return await self.json_rpc(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def get_balances(
|
async def get_balances(
|
||||||
self,
|
self,
|
||||||
kind: str = 'option'
|
kind: str = 'option'
|
||||||
|
@ -246,7 +279,7 @@ class Client:
|
||||||
balances = {}
|
balances = {}
|
||||||
|
|
||||||
for currency in self.currencies:
|
for currency in self.currencies:
|
||||||
resp = await self.json_rpc(
|
resp = await self._json_rpc_auth_wrapper(
|
||||||
'private/get_positions', params={
|
'private/get_positions', params={
|
||||||
'currency': currency.upper(),
|
'currency': currency.upper(),
|
||||||
'kind': kind})
|
'kind': kind})
|
||||||
|
@ -264,7 +297,7 @@ class Client:
|
||||||
by symbol.
|
by symbol.
|
||||||
"""
|
"""
|
||||||
assets = {}
|
assets = {}
|
||||||
resp = await self.json_rpc(
|
resp = await self._json_rpc_auth_wrapper(
|
||||||
'public/get_currencies',
|
'public/get_currencies',
|
||||||
params={}
|
params={}
|
||||||
)
|
)
|
||||||
|
@ -311,7 +344,7 @@ class Client:
|
||||||
'type': 'limit',
|
'type': 'limit',
|
||||||
'price': price,
|
'price': price,
|
||||||
}
|
}
|
||||||
resp = await self.json_rpc(
|
resp = await self._json_rpc_auth_wrapper(
|
||||||
f'private/{action}', params)
|
f'private/{action}', params)
|
||||||
|
|
||||||
return resp.result
|
return resp.result
|
||||||
|
@ -319,7 +352,7 @@ class Client:
|
||||||
async def submit_cancel(self, oid: str):
|
async def submit_cancel(self, oid: str):
|
||||||
"""Send cancel request for order id
|
"""Send cancel request for order id
|
||||||
"""
|
"""
|
||||||
resp = await self.json_rpc(
|
resp = await self._json_rpc_auth_wrapper(
|
||||||
'private/cancel', {'order_id': oid})
|
'private/cancel', {'order_id': oid})
|
||||||
return resp.result
|
return resp.result
|
||||||
|
|
||||||
|
@ -367,7 +400,7 @@ class Client:
|
||||||
'expired': str(expired).lower()
|
'expired': str(expired).lower()
|
||||||
}
|
}
|
||||||
|
|
||||||
resp: JSONRPCResult = await self.json_rpc(
|
resp: JSONRPCResult = await self._json_rpc_auth_wrapper(
|
||||||
'public/get_instruments',
|
'public/get_instruments',
|
||||||
params,
|
params,
|
||||||
)
|
)
|
||||||
|
@ -449,7 +482,7 @@ class Client:
|
||||||
end_time = deribit_timestamp(end_dt)
|
end_time = deribit_timestamp(end_dt)
|
||||||
|
|
||||||
# https://docs.deribit.com/#public-get_tradingview_chart_data
|
# https://docs.deribit.com/#public-get_tradingview_chart_data
|
||||||
resp = await self.json_rpc(
|
resp = await self._json_rpc_auth_wrapper(
|
||||||
'public/get_tradingview_chart_data',
|
'public/get_tradingview_chart_data',
|
||||||
params={
|
params={
|
||||||
'instrument_name': instrument.upper(),
|
'instrument_name': instrument.upper(),
|
||||||
|
@ -486,7 +519,7 @@ class Client:
|
||||||
instrument: str,
|
instrument: str,
|
||||||
count: int = 10
|
count: int = 10
|
||||||
):
|
):
|
||||||
resp = await self.json_rpc(
|
resp = await self._json_rpc_auth_wrapper(
|
||||||
'public/get_last_trades_by_instrument',
|
'public/get_last_trades_by_instrument',
|
||||||
params={
|
params={
|
||||||
'instrument_name': instrument,
|
'instrument_name': instrument,
|
||||||
|
@ -508,68 +541,6 @@ async def get_client(
|
||||||
) as json_rpc
|
) as json_rpc
|
||||||
):
|
):
|
||||||
client = Client(json_rpc)
|
client = Client(json_rpc)
|
||||||
_refresh_token: Optional[str] = None
|
|
||||||
_access_token: Optional[str] = None
|
|
||||||
|
|
||||||
async def _auth_loop(
|
|
||||||
task_status: TaskStatus = trio.TASK_STATUS_IGNORED
|
|
||||||
):
|
|
||||||
"""Background task that adquires a first access token and then will
|
|
||||||
refresh the access token while the nursery isn't cancelled.
|
|
||||||
|
|
||||||
https://docs.deribit.com/?python#authentication-2
|
|
||||||
"""
|
|
||||||
renew_time = 10
|
|
||||||
access_scope = 'trade:read_write'
|
|
||||||
_expiry_time = time.time()
|
|
||||||
got_access = False
|
|
||||||
nonlocal _refresh_token
|
|
||||||
nonlocal _access_token
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if time.time() - _expiry_time < renew_time:
|
|
||||||
# if we are close to token expiry time
|
|
||||||
|
|
||||||
if _refresh_token != None:
|
|
||||||
# if we have a refresh token already dont need to send
|
|
||||||
# secret
|
|
||||||
params = {
|
|
||||||
'grant_type': 'refresh_token',
|
|
||||||
'refresh_token': _refresh_token,
|
|
||||||
'scope': access_scope
|
|
||||||
}
|
|
||||||
|
|
||||||
else:
|
|
||||||
# we don't have refresh token, send secret to initialize
|
|
||||||
params = {
|
|
||||||
'grant_type': 'client_credentials',
|
|
||||||
'client_id': client._key_id,
|
|
||||||
'client_secret': client._key_secret,
|
|
||||||
'scope': access_scope
|
|
||||||
}
|
|
||||||
|
|
||||||
resp = await json_rpc('public/auth', params)
|
|
||||||
result = resp.result
|
|
||||||
|
|
||||||
_expiry_time = time.time() + result['expires_in']
|
|
||||||
_refresh_token = result['refresh_token']
|
|
||||||
|
|
||||||
if 'access_token' in result:
|
|
||||||
_access_token = result['access_token']
|
|
||||||
|
|
||||||
if not got_access:
|
|
||||||
# first time this loop runs we must indicate task is
|
|
||||||
# started, we have auth
|
|
||||||
got_access = True
|
|
||||||
task_status.started()
|
|
||||||
|
|
||||||
else:
|
|
||||||
await trio.sleep(renew_time / 2)
|
|
||||||
|
|
||||||
# if we have client creds launch auth loop
|
|
||||||
if client._key_id is not None:
|
|
||||||
await n.start(_auth_loop)
|
|
||||||
|
|
||||||
await client.cache_symbols()
|
await client.cache_symbols()
|
||||||
yield client
|
yield client
|
||||||
n.cancel_scope.cancel()
|
n.cancel_scope.cancel()
|
||||||
|
|
Loading…
Reference in New Issue