ccxt 4.3.32__py2.py3-none-any.whl → 4.3.34__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +1 -1
- ccxt/abstract/binance.py +1 -0
- ccxt/abstract/binancecoinm.py +1 -0
- ccxt/abstract/binanceus.py +1 -0
- ccxt/abstract/binanceusdm.py +1 -0
- ccxt/abstract/bitget.py +1 -1
- ccxt/ace.py +2 -2
- ccxt/alpaca.py +1 -1
- ccxt/ascendex.py +2 -2
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/ace.py +2 -2
- ccxt/async_support/alpaca.py +1 -1
- ccxt/async_support/ascendex.py +2 -2
- ccxt/async_support/base/exchange.py +17 -1
- ccxt/async_support/bigone.py +2 -2
- ccxt/async_support/binance.py +4 -3
- ccxt/async_support/bingx.py +2 -2
- ccxt/async_support/bit2c.py +1 -1
- ccxt/async_support/bitbank.py +1 -1
- ccxt/async_support/bitbns.py +1 -1
- ccxt/async_support/bitfinex.py +2 -2
- ccxt/async_support/bitfinex2.py +1 -1
- ccxt/async_support/bitflyer.py +1 -1
- ccxt/async_support/bitget.py +4 -4
- ccxt/async_support/bithumb.py +1 -1
- ccxt/async_support/bitmart.py +2 -2
- ccxt/async_support/bitmex.py +3 -3
- ccxt/async_support/bitopro.py +3 -3
- ccxt/async_support/bitrue.py +2 -2
- ccxt/async_support/bitso.py +2 -2
- ccxt/async_support/bitstamp.py +2 -2
- ccxt/async_support/bitteam.py +3 -3
- ccxt/async_support/bitvavo.py +2 -2
- ccxt/async_support/blockchaincom.py +1 -1
- ccxt/async_support/blofin.py +3 -3
- ccxt/async_support/btcalpha.py +3 -3
- ccxt/async_support/btcbox.py +1 -1
- ccxt/async_support/btcmarkets.py +3 -3
- ccxt/async_support/btcturk.py +1 -1
- ccxt/async_support/bybit.py +2 -2
- ccxt/async_support/cex.py +1 -1
- ccxt/async_support/coinbase.py +96 -55
- ccxt/async_support/coinbaseexchange.py +1 -1
- ccxt/async_support/coinbaseinternational.py +3 -3
- ccxt/async_support/coincheck.py +2 -2
- ccxt/async_support/coinex.py +2 -2
- ccxt/async_support/coinlist.py +2 -2
- ccxt/async_support/coinmate.py +2 -2
- ccxt/async_support/coinmetro.py +2 -2
- ccxt/async_support/coinone.py +1 -1
- ccxt/async_support/coinsph.py +2 -2
- ccxt/async_support/cryptocom.py +1 -1
- ccxt/async_support/currencycom.py +2 -2
- ccxt/async_support/delta.py +1 -1
- ccxt/async_support/deribit.py +2 -2
- ccxt/async_support/digifinex.py +2 -2
- ccxt/async_support/exmo.py +2 -2
- ccxt/async_support/gate.py +2 -2
- ccxt/async_support/gemini.py +2 -2
- ccxt/async_support/hitbtc.py +2 -2
- ccxt/async_support/hollaex.py +1 -1
- ccxt/async_support/htx.py +2 -2
- ccxt/async_support/huobijp.py +2 -2
- ccxt/async_support/hyperliquid.py +2 -2
- ccxt/async_support/idex.py +2 -2
- ccxt/async_support/indodax.py +2 -2
- ccxt/async_support/kraken.py +2 -2
- ccxt/async_support/krakenfutures.py +1 -1
- ccxt/async_support/kucoin.py +2 -2
- ccxt/async_support/kuna.py +2 -2
- ccxt/async_support/latoken.py +2 -2
- ccxt/async_support/lbank.py +1 -1
- ccxt/async_support/luno.py +1 -1
- ccxt/async_support/lykke.py +1 -1
- ccxt/async_support/mercado.py +1 -1
- ccxt/async_support/mexc.py +1 -1
- ccxt/async_support/ndax.py +2 -2
- ccxt/async_support/novadax.py +3 -3
- ccxt/async_support/oceanex.py +2 -2
- ccxt/async_support/okcoin.py +3 -3
- ccxt/async_support/okx.py +3 -3
- ccxt/async_support/onetrading.py +2 -2
- ccxt/async_support/p2b.py +2 -2
- ccxt/async_support/paymium.py +1 -1
- ccxt/async_support/phemex.py +4 -4
- ccxt/async_support/poloniex.py +3 -3
- ccxt/async_support/poloniexfutures.py +2 -2
- ccxt/async_support/probit.py +3 -3
- ccxt/async_support/timex.py +2 -2
- ccxt/async_support/tokocrypto.py +1 -1
- ccxt/async_support/tradeogre.py +1 -1
- ccxt/async_support/upbit.py +3 -3
- ccxt/async_support/wavesexchange.py +1 -1
- ccxt/async_support/wazirx.py +3 -3
- ccxt/async_support/whitebit.py +3 -3
- ccxt/async_support/woo.py +3 -3
- ccxt/async_support/woofipro.py +3 -3
- ccxt/async_support/yobit.py +1 -1
- ccxt/async_support/zaif.py +2 -2
- ccxt/async_support/zonda.py +1 -1
- ccxt/base/exchange.py +25 -3
- ccxt/base/types.py +0 -1
- ccxt/bigone.py +2 -2
- ccxt/binance.py +4 -3
- ccxt/bingx.py +2 -2
- ccxt/bit2c.py +1 -1
- ccxt/bitbank.py +1 -1
- ccxt/bitbns.py +1 -1
- ccxt/bitfinex.py +2 -2
- ccxt/bitfinex2.py +1 -1
- ccxt/bitflyer.py +1 -1
- ccxt/bitget.py +4 -4
- ccxt/bithumb.py +1 -1
- ccxt/bitmart.py +2 -2
- ccxt/bitmex.py +3 -3
- ccxt/bitopro.py +3 -3
- ccxt/bitrue.py +2 -2
- ccxt/bitso.py +2 -2
- ccxt/bitstamp.py +2 -2
- ccxt/bitteam.py +3 -3
- ccxt/bitvavo.py +2 -2
- ccxt/blockchaincom.py +1 -1
- ccxt/blofin.py +3 -3
- ccxt/btcalpha.py +3 -3
- ccxt/btcbox.py +1 -1
- ccxt/btcmarkets.py +3 -3
- ccxt/btcturk.py +1 -1
- ccxt/bybit.py +2 -2
- ccxt/cex.py +1 -1
- ccxt/coinbase.py +96 -55
- ccxt/coinbaseexchange.py +1 -1
- ccxt/coinbaseinternational.py +3 -3
- ccxt/coincheck.py +2 -2
- ccxt/coinex.py +2 -2
- ccxt/coinlist.py +2 -2
- ccxt/coinmate.py +2 -2
- ccxt/coinmetro.py +2 -2
- ccxt/coinone.py +1 -1
- ccxt/coinsph.py +2 -2
- ccxt/cryptocom.py +1 -1
- ccxt/currencycom.py +2 -2
- ccxt/delta.py +1 -1
- ccxt/deribit.py +2 -2
- ccxt/digifinex.py +2 -2
- ccxt/exmo.py +2 -2
- ccxt/gate.py +2 -2
- ccxt/gemini.py +2 -2
- ccxt/hitbtc.py +2 -2
- ccxt/hollaex.py +1 -1
- ccxt/htx.py +2 -2
- ccxt/huobijp.py +2 -2
- ccxt/hyperliquid.py +2 -2
- ccxt/idex.py +2 -2
- ccxt/indodax.py +2 -2
- ccxt/kraken.py +2 -2
- ccxt/krakenfutures.py +1 -1
- ccxt/kucoin.py +2 -2
- ccxt/kuna.py +2 -2
- ccxt/latoken.py +2 -2
- ccxt/lbank.py +1 -1
- ccxt/luno.py +1 -1
- ccxt/lykke.py +1 -1
- ccxt/mercado.py +1 -1
- ccxt/mexc.py +1 -1
- ccxt/ndax.py +2 -2
- ccxt/novadax.py +3 -3
- ccxt/oceanex.py +2 -2
- ccxt/okcoin.py +3 -3
- ccxt/okx.py +3 -3
- ccxt/onetrading.py +2 -2
- ccxt/p2b.py +2 -2
- ccxt/paymium.py +1 -1
- ccxt/phemex.py +4 -4
- ccxt/poloniex.py +3 -3
- ccxt/poloniexfutures.py +2 -2
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/binance.py +331 -2
- ccxt/pro/bitmex.py +98 -1
- ccxt/pro/bybit.py +82 -1
- ccxt/pro/gate.py +173 -1
- ccxt/pro/kucoinfutures.py +4 -0
- ccxt/pro/okx.py +245 -2
- ccxt/probit.py +3 -3
- ccxt/test/base/__init__.py +1 -0
- ccxt/test/base/test_liquidation.py +50 -0
- ccxt/timex.py +2 -2
- ccxt/tokocrypto.py +1 -1
- ccxt/tradeogre.py +1 -1
- ccxt/upbit.py +3 -3
- ccxt/wavesexchange.py +1 -1
- ccxt/wazirx.py +3 -3
- ccxt/whitebit.py +3 -3
- ccxt/woo.py +3 -3
- ccxt/woofipro.py +3 -3
- ccxt/yobit.py +1 -1
- ccxt/zaif.py +2 -2
- ccxt/zonda.py +1 -1
- {ccxt-4.3.32.dist-info → ccxt-4.3.34.dist-info}/METADATA +4 -4
- {ccxt-4.3.32.dist-info → ccxt-4.3.34.dist-info}/RECORD +201 -200
- {ccxt-4.3.32.dist-info → ccxt-4.3.34.dist-info}/WHEEL +0 -0
- {ccxt-4.3.32.dist-info → ccxt-4.3.34.dist-info}/top_level.txt +0 -0
ccxt/pro/gate.py
CHANGED
@@ -6,13 +6,14 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Liquidation, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import AuthenticationError
|
13
13
|
from ccxt.base.errors import ArgumentsRequired
|
14
14
|
from ccxt.base.errors import BadRequest
|
15
15
|
from ccxt.base.errors import InvalidNonce
|
16
|
+
from ccxt.base.precise import Precise
|
16
17
|
|
17
18
|
|
18
19
|
class gate(ccxt.async_support.gate):
|
@@ -30,6 +31,10 @@ class gate(ccxt.async_support.gate):
|
|
30
31
|
'watchOHLCV': True,
|
31
32
|
'watchBalance': True,
|
32
33
|
'watchOrders': True,
|
34
|
+
'watchLiquidations': False,
|
35
|
+
'watchLiquidationsForSymbols': False,
|
36
|
+
'watchMyLiquidations': True,
|
37
|
+
'watchMyLiquidationsForSymbols': True,
|
33
38
|
'watchPositions': True,
|
34
39
|
},
|
35
40
|
'urls': {
|
@@ -963,6 +968,172 @@ class gate(ccxt.async_support.gate):
|
|
963
968
|
client.resolve(self.orders, messageHash)
|
964
969
|
client.resolve(self.orders, 'orders')
|
965
970
|
|
971
|
+
async def watch_my_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
972
|
+
"""
|
973
|
+
watch the public liquidations of a trading pair
|
974
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
|
975
|
+
:see: https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
|
976
|
+
:see: https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
|
977
|
+
:param str symbol: unified CCXT market symbol
|
978
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
979
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
980
|
+
:param dict [params]: exchange specific parameters for the bitmex api endpoint
|
981
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
982
|
+
"""
|
983
|
+
return self.watch_my_liquidations_for_symbols([symbol], since, limit, params)
|
984
|
+
|
985
|
+
async def watch_my_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
986
|
+
"""
|
987
|
+
watch the private liquidations of a trading pair
|
988
|
+
:see: https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
|
989
|
+
:see: https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
|
990
|
+
:see: https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
|
991
|
+
:param str symbol: unified CCXT market symbol
|
992
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
993
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
994
|
+
:param dict [params]: exchange specific parameters for the gate api endpoint
|
995
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
996
|
+
"""
|
997
|
+
await self.load_markets()
|
998
|
+
symbols = self.market_symbols(symbols, None, True, True)
|
999
|
+
market = self.get_market_from_symbols(symbols)
|
1000
|
+
type = None
|
1001
|
+
query = None
|
1002
|
+
type, query = self.handle_market_type_and_params('watchMyLiquidationsForSymbols', market, params)
|
1003
|
+
typeId = self.get_supported_mapping(type, {
|
1004
|
+
'future': 'futures',
|
1005
|
+
'swap': 'futures',
|
1006
|
+
'option': 'options',
|
1007
|
+
})
|
1008
|
+
subType = None
|
1009
|
+
subType, query = self.handle_sub_type_and_params('watchMyLiquidationsForSymbols', market, query)
|
1010
|
+
isInverse = (subType == 'inverse')
|
1011
|
+
url = self.get_url_by_market_type(type, isInverse)
|
1012
|
+
payload = []
|
1013
|
+
messageHash = ''
|
1014
|
+
if self.is_empty(symbols):
|
1015
|
+
if typeId != 'futures' and not isInverse:
|
1016
|
+
raise BadRequest(self.id + ' watchMyLiquidationsForSymbols() does not support listening to all symbols, you must call watchMyLiquidations() instead for each symbol you wish to watch.')
|
1017
|
+
messageHash = 'myLiquidations'
|
1018
|
+
payload.append('not all')
|
1019
|
+
else:
|
1020
|
+
symbolsLength = len(symbols)
|
1021
|
+
if symbolsLength != 1:
|
1022
|
+
raise BadRequest(self.id + ' watchMyLiquidationsForSymbols() only allows one symbol at a time. To listen to several symbols call watchMyLiquidationsForSymbols() several times.')
|
1023
|
+
messageHash = 'myLiquidations::' + symbols[0]
|
1024
|
+
payload.append(market['id'])
|
1025
|
+
channel = typeId + '.liquidates'
|
1026
|
+
newLiquidations = await self.subscribe_private(url, messageHash, payload, channel, query, True)
|
1027
|
+
if self.newUpdates:
|
1028
|
+
return newLiquidations
|
1029
|
+
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
1030
|
+
|
1031
|
+
def handle_liquidation(self, client: Client, message):
|
1032
|
+
#
|
1033
|
+
# future / delivery
|
1034
|
+
# {
|
1035
|
+
# "channel":"futures.liquidates",
|
1036
|
+
# "event":"update",
|
1037
|
+
# "time":1541505434,
|
1038
|
+
# "time_ms":1541505434123,
|
1039
|
+
# "result":[
|
1040
|
+
# {
|
1041
|
+
# "entry_price":209,
|
1042
|
+
# "fill_price":215.1,
|
1043
|
+
# "left":0,
|
1044
|
+
# "leverage":0.0,
|
1045
|
+
# "liq_price":213,
|
1046
|
+
# "margin":0.007816722941,
|
1047
|
+
# "mark_price":213,
|
1048
|
+
# "order_id":4093362,
|
1049
|
+
# "order_price":215.1,
|
1050
|
+
# "size":-124,
|
1051
|
+
# "time":1541486601,
|
1052
|
+
# "time_ms":1541486601123,
|
1053
|
+
# "contract":"BTC_USD",
|
1054
|
+
# "user":"1040xxxx"
|
1055
|
+
# }
|
1056
|
+
# ]
|
1057
|
+
# }
|
1058
|
+
# option
|
1059
|
+
# {
|
1060
|
+
# "channel":"options.liquidates",
|
1061
|
+
# "event":"update",
|
1062
|
+
# "time":1630654851,
|
1063
|
+
# "result":[
|
1064
|
+
# {
|
1065
|
+
# "user":"1xxxx",
|
1066
|
+
# "init_margin":1190,
|
1067
|
+
# "maint_margin":1042.5,
|
1068
|
+
# "order_margin":0,
|
1069
|
+
# "time":1639051907,
|
1070
|
+
# "time_ms":1639051907000
|
1071
|
+
# }
|
1072
|
+
# ]
|
1073
|
+
# }
|
1074
|
+
#
|
1075
|
+
rawLiquidations = self.safe_list(message, 'result', [])
|
1076
|
+
newLiquidations = []
|
1077
|
+
for i in range(0, len(rawLiquidations)):
|
1078
|
+
rawLiquidation = rawLiquidations[i]
|
1079
|
+
liquidation = self.parse_ws_liquidation(rawLiquidation)
|
1080
|
+
symbol = self.safe_string(liquidation, 'symbol')
|
1081
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
1082
|
+
if liquidations is None:
|
1083
|
+
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
1084
|
+
liquidations = ArrayCache(limit)
|
1085
|
+
liquidations.append(liquidation)
|
1086
|
+
self.liquidations[symbol] = liquidations
|
1087
|
+
client.resolve(liquidations, 'myLiquidations::' + symbol)
|
1088
|
+
client.resolve(newLiquidations, 'myLiquidations')
|
1089
|
+
|
1090
|
+
def parse_ws_liquidation(self, liquidation, market=None):
|
1091
|
+
#
|
1092
|
+
# future / delivery
|
1093
|
+
# {
|
1094
|
+
# "entry_price": 209,
|
1095
|
+
# "fill_price": 215.1,
|
1096
|
+
# "left": 0,
|
1097
|
+
# "leverage": 0.0,
|
1098
|
+
# "liq_price": 213,
|
1099
|
+
# "margin": 0.007816722941,
|
1100
|
+
# "mark_price": 213,
|
1101
|
+
# "order_id": 4093362,
|
1102
|
+
# "order_price": 215.1,
|
1103
|
+
# "size": -124,
|
1104
|
+
# "time": 1541486601,
|
1105
|
+
# "time_ms": 1541486601123,
|
1106
|
+
# "contract": "BTC_USD",
|
1107
|
+
# "user": "1040xxxx"
|
1108
|
+
# }
|
1109
|
+
# option
|
1110
|
+
# {
|
1111
|
+
# "user": "1xxxx",
|
1112
|
+
# "init_margin": 1190,
|
1113
|
+
# "maint_margin": 1042.5,
|
1114
|
+
# "order_margin": 0,
|
1115
|
+
# "time": 1639051907,
|
1116
|
+
# "time_ms": 1639051907000
|
1117
|
+
# }
|
1118
|
+
#
|
1119
|
+
marketId = self.safe_string(liquidation, 'contract')
|
1120
|
+
market = self.safe_market(marketId, market)
|
1121
|
+
timestamp = self.safe_integer(liquidation, 'time_ms')
|
1122
|
+
originalSize = self.safe_string(liquidation, 'size')
|
1123
|
+
left = self.safe_string(liquidation, 'left')
|
1124
|
+
amount = Precise.string_abs(Precise.string_sub(originalSize, left))
|
1125
|
+
return self.safe_liquidation({
|
1126
|
+
'info': liquidation,
|
1127
|
+
'symbol': self.safe_symbol(marketId, market),
|
1128
|
+
'contracts': self.parse_number(amount),
|
1129
|
+
'contractSize': self.safe_number(market, 'contractSize'),
|
1130
|
+
'price': self.safe_number(liquidation, 'fill_price'),
|
1131
|
+
'baseValue': None,
|
1132
|
+
'quoteValue': None,
|
1133
|
+
'timestamp': timestamp,
|
1134
|
+
'datetime': self.iso8601(timestamp),
|
1135
|
+
})
|
1136
|
+
|
966
1137
|
def handle_error_message(self, client: Client, message):
|
967
1138
|
# {
|
968
1139
|
# "time": 1647274664,
|
@@ -1126,6 +1297,7 @@ class gate(ccxt.async_support.gate):
|
|
1126
1297
|
'trades': self.handle_trades,
|
1127
1298
|
'order_book_update': self.handle_order_book,
|
1128
1299
|
'balances': self.handle_balance,
|
1300
|
+
'liquidates': self.handle_liquidation,
|
1129
1301
|
}
|
1130
1302
|
method = self.safe_value(v4Methods, channelType)
|
1131
1303
|
if method is not None:
|
ccxt/pro/kucoinfutures.py
CHANGED
@@ -18,6 +18,10 @@ class kucoinfutures(ccxt.async_support.kucoinfutures):
|
|
18
18
|
return self.deep_extend(super(kucoinfutures, self).describe(), {
|
19
19
|
'has': {
|
20
20
|
'ws': True,
|
21
|
+
'watchLiquidations': False,
|
22
|
+
'watchLiquidatinsForSymbols': False,
|
23
|
+
'watchMyLiquidations': None,
|
24
|
+
'watchMyLiquidationsForSymbols': None,
|
21
25
|
'watchTicker': True,
|
22
26
|
'watchTickers': True,
|
23
27
|
'watchBidsAsks': True,
|
ccxt/pro/okx.py
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
import ccxt.async_support
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade
|
9
|
+
from ccxt.base.types import Balances, Int, Liquidation, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
@@ -29,6 +29,10 @@ class okx(ccxt.async_support.okx):
|
|
29
29
|
'watchTradesForSymbols': True,
|
30
30
|
'watchOrderBookForSymbols': True,
|
31
31
|
'watchBalance': True,
|
32
|
+
'watchLiquidations': 'emulated',
|
33
|
+
'watchLiquidationsForSymbols': True,
|
34
|
+
'watchMyLiquidations': 'emulated',
|
35
|
+
'watchMyLiquidationsForSymbols': True,
|
32
36
|
'watchOHLCV': True,
|
33
37
|
'watchOHLCVForSymbols': True,
|
34
38
|
'watchOrders': True,
|
@@ -160,7 +164,7 @@ class okx(ccxt.async_support.okx):
|
|
160
164
|
self.deep_extend(firstArgument, params),
|
161
165
|
],
|
162
166
|
}
|
163
|
-
return
|
167
|
+
return self.watch(url, messageHash, request, messageHash)
|
164
168
|
|
165
169
|
async def watch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
166
170
|
"""
|
@@ -399,6 +403,240 @@ class okx(ccxt.async_support.okx):
|
|
399
403
|
client.resolve(tickers, messageHash)
|
400
404
|
return message
|
401
405
|
|
406
|
+
async def watch_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
407
|
+
"""
|
408
|
+
watch the public liquidations of a trading pair
|
409
|
+
:see: https://www.okx.com/docs-v5/en/#public-data-websocket-liquidation-orders-channel
|
410
|
+
:param str symbol: unified CCXT market symbol
|
411
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
412
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
413
|
+
:param dict [params]: exchange specific parameters for the okx api endpoint
|
414
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
415
|
+
"""
|
416
|
+
await self.load_markets()
|
417
|
+
symbols = self.market_symbols(symbols, None, True, True)
|
418
|
+
messageHash = 'liquidations'
|
419
|
+
if symbols is not None:
|
420
|
+
messageHash += '::' + ','.join(symbols)
|
421
|
+
market = self.get_market_from_symbols(symbols)
|
422
|
+
type = None
|
423
|
+
type, params = self.handle_market_type_and_params('watchliquidationsForSymbols', market, params)
|
424
|
+
channel = 'liquidation-orders'
|
425
|
+
if type == 'spot':
|
426
|
+
type = 'SWAP'
|
427
|
+
elif type == 'future':
|
428
|
+
type = 'futures'
|
429
|
+
uppercaseType = type.upper()
|
430
|
+
request = {
|
431
|
+
'instType': uppercaseType,
|
432
|
+
}
|
433
|
+
newLiquidations = await self.subscribe('public', messageHash, channel, None, self.extend(request, params))
|
434
|
+
if self.newUpdates:
|
435
|
+
return newLiquidations
|
436
|
+
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
437
|
+
|
438
|
+
def handle_liquidation(self, client: Client, message):
|
439
|
+
#
|
440
|
+
# {
|
441
|
+
# "arg": {
|
442
|
+
# "channel": "liquidation-orders",
|
443
|
+
# "instType": "SWAP"
|
444
|
+
# },
|
445
|
+
# "data": [
|
446
|
+
# {
|
447
|
+
# "details": [
|
448
|
+
# {
|
449
|
+
# "bkLoss": "0",
|
450
|
+
# "bkPx": "0.007831",
|
451
|
+
# "ccy": "",
|
452
|
+
# "posSide": "short",
|
453
|
+
# "side": "buy",
|
454
|
+
# "sz": "13",
|
455
|
+
# "ts": "1692266434010"
|
456
|
+
# }
|
457
|
+
# ],
|
458
|
+
# "instFamily": "IOST-USDT",
|
459
|
+
# "instId": "IOST-USDT-SWAP",
|
460
|
+
# "instType": "SWAP",
|
461
|
+
# "uly": "IOST-USDT"
|
462
|
+
# }
|
463
|
+
# ]
|
464
|
+
# }
|
465
|
+
#
|
466
|
+
rawLiquidations = self.safe_list(message, 'data', [])
|
467
|
+
for i in range(0, len(rawLiquidations)):
|
468
|
+
rawLiquidation = rawLiquidations[i]
|
469
|
+
liquidation = self.parse_ws_liquidation(rawLiquidation)
|
470
|
+
symbol = self.safe_string(liquidation, 'symbol')
|
471
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
472
|
+
if liquidations is None:
|
473
|
+
limit = self.safe_integer(self.options, 'liquidationsLimit', 1000)
|
474
|
+
liquidations = ArrayCache(limit)
|
475
|
+
liquidations.append(liquidation)
|
476
|
+
self.liquidations[symbol] = liquidations
|
477
|
+
client.resolve([liquidation], 'liquidations')
|
478
|
+
client.resolve([liquidation], 'liquidations::' + symbol)
|
479
|
+
|
480
|
+
async def watch_my_liquidations_for_symbols(self, symbols: List[str] = None, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
481
|
+
"""
|
482
|
+
watch the private liquidations of a trading pair
|
483
|
+
:see: https://www.okx.com/docs-v5/en/#trading-account-websocket-balance-and-position-channel
|
484
|
+
:param str symbol: unified CCXT market symbol
|
485
|
+
:param int [since]: the earliest time in ms to fetch liquidations for
|
486
|
+
:param int [limit]: the maximum number of liquidation structures to retrieve
|
487
|
+
:param dict [params]: exchange specific parameters for the okx api endpoint
|
488
|
+
:returns dict: an array of `liquidation structures <https://github.com/ccxt/ccxt/wiki/Manual#liquidation-structure>`
|
489
|
+
"""
|
490
|
+
await self.load_markets()
|
491
|
+
isStop = self.safe_value_2(params, 'stop', 'trigger', False)
|
492
|
+
params = self.omit(params, ['stop', 'trigger'])
|
493
|
+
await self.authenticate({'access': 'business' if isStop else 'private'})
|
494
|
+
symbols = self.market_symbols(symbols, None, True, True)
|
495
|
+
messageHash = 'myLiquidations'
|
496
|
+
if symbols is not None:
|
497
|
+
messageHash += '::' + ','.join(symbols)
|
498
|
+
channel = 'balance_and_position'
|
499
|
+
newLiquidations = await self.subscribe('private', messageHash, channel, None, params)
|
500
|
+
if self.newUpdates:
|
501
|
+
return newLiquidations
|
502
|
+
return self.filter_by_symbols_since_limit(self.liquidations, symbols, since, limit, True)
|
503
|
+
|
504
|
+
def handle_my_liquidation(self, client: Client, message):
|
505
|
+
#
|
506
|
+
# {
|
507
|
+
# "arg": {
|
508
|
+
# "channel": "balance_and_position",
|
509
|
+
# "uid": "77982378738415879"
|
510
|
+
# },
|
511
|
+
# "data": [{
|
512
|
+
# "pTime": "1597026383085",
|
513
|
+
# "eventType": "snapshot",
|
514
|
+
# "balData": [{
|
515
|
+
# "ccy": "BTC",
|
516
|
+
# "cashBal": "1",
|
517
|
+
# "uTime": "1597026383085"
|
518
|
+
# }],
|
519
|
+
# "posData": [{
|
520
|
+
# "posId": "1111111111",
|
521
|
+
# "tradeId": "2",
|
522
|
+
# "instId": "BTC-USD-191018",
|
523
|
+
# "instType": "FUTURES",
|
524
|
+
# "mgnMode": "cross",
|
525
|
+
# "posSide": "long",
|
526
|
+
# "pos": "10",
|
527
|
+
# "ccy": "BTC",
|
528
|
+
# "posCcy": "",
|
529
|
+
# "avgPx": "3320",
|
530
|
+
# "uTIme": "1597026383085"
|
531
|
+
# }],
|
532
|
+
# "trades": [{
|
533
|
+
# "instId": "BTC-USD-191018",
|
534
|
+
# "tradeId": "2",
|
535
|
+
# }]
|
536
|
+
# }]
|
537
|
+
# }
|
538
|
+
#
|
539
|
+
rawLiquidations = self.safe_list(message, 'data', [])
|
540
|
+
for i in range(0, len(rawLiquidations)):
|
541
|
+
rawLiquidation = rawLiquidations[i]
|
542
|
+
eventType = self.safe_string(rawLiquidation, 'eventType')
|
543
|
+
if eventType != 'liquidation':
|
544
|
+
return
|
545
|
+
liquidation = self.parse_ws_my_liquidation(rawLiquidation)
|
546
|
+
symbol = self.safe_string(liquidation, 'symbol')
|
547
|
+
liquidations = self.safe_value(self.liquidations, symbol)
|
548
|
+
if liquidations is None:
|
549
|
+
limit = self.safe_integer(self.options, 'myLiquidationsLimit', 1000)
|
550
|
+
liquidations = ArrayCache(limit)
|
551
|
+
liquidations.append(liquidation)
|
552
|
+
self.liquidations[symbol] = liquidations
|
553
|
+
client.resolve([liquidation], 'myLiquidations')
|
554
|
+
client.resolve([liquidation], 'myLiquidations::' + symbol)
|
555
|
+
|
556
|
+
def parse_ws_my_liquidation(self, liquidation, market=None):
|
557
|
+
#
|
558
|
+
# {
|
559
|
+
# "pTime": "1597026383085",
|
560
|
+
# "eventType": "snapshot",
|
561
|
+
# "balData": [{
|
562
|
+
# "ccy": "BTC",
|
563
|
+
# "cashBal": "1",
|
564
|
+
# "uTime": "1597026383085"
|
565
|
+
# }],
|
566
|
+
# "posData": [{
|
567
|
+
# "posId": "1111111111",
|
568
|
+
# "tradeId": "2",
|
569
|
+
# "instId": "BTC-USD-191018",
|
570
|
+
# "instType": "FUTURES",
|
571
|
+
# "mgnMode": "cross",
|
572
|
+
# "posSide": "long",
|
573
|
+
# "pos": "10",
|
574
|
+
# "ccy": "BTC",
|
575
|
+
# "posCcy": "",
|
576
|
+
# "avgPx": "3320",
|
577
|
+
# "uTIme": "1597026383085"
|
578
|
+
# }],
|
579
|
+
# "trades": [{
|
580
|
+
# "instId": "BTC-USD-191018",
|
581
|
+
# "tradeId": "2",
|
582
|
+
# }]
|
583
|
+
# }
|
584
|
+
#
|
585
|
+
posData = self.safe_list(liquidation, 'posData', [])
|
586
|
+
firstPosData = self.safe_dict(posData, 0, {})
|
587
|
+
marketId = self.safe_string(firstPosData, 'instId')
|
588
|
+
market = self.safe_market(marketId, market)
|
589
|
+
timestamp = self.safe_integer(firstPosData, 'uTIme')
|
590
|
+
return self.safe_liquidation({
|
591
|
+
'info': liquidation,
|
592
|
+
'symbol': self.safe_symbol(marketId, market),
|
593
|
+
'contracts': self.safe_number(firstPosData, 'pos'),
|
594
|
+
'contractSize': self.safe_number(market, 'contractSize'),
|
595
|
+
'price': self.safe_number(liquidation, 'avgPx'),
|
596
|
+
'baseValue': None,
|
597
|
+
'quoteValue': None,
|
598
|
+
'timestamp': timestamp,
|
599
|
+
'datetime': self.iso8601(timestamp),
|
600
|
+
})
|
601
|
+
|
602
|
+
def parse_ws_liquidation(self, liquidation, market=None):
|
603
|
+
#
|
604
|
+
# public liquidation
|
605
|
+
# {
|
606
|
+
# "details": [
|
607
|
+
# {
|
608
|
+
# "bkLoss": "0",
|
609
|
+
# "bkPx": "0.007831",
|
610
|
+
# "ccy": "",
|
611
|
+
# "posSide": "short",
|
612
|
+
# "side": "buy",
|
613
|
+
# "sz": "13",
|
614
|
+
# "ts": "1692266434010"
|
615
|
+
# }
|
616
|
+
# ],
|
617
|
+
# "instFamily": "IOST-USDT",
|
618
|
+
# "instId": "IOST-USDT-SWAP",
|
619
|
+
# "instType": "SWAP",
|
620
|
+
# "uly": "IOST-USDT"
|
621
|
+
# }
|
622
|
+
#
|
623
|
+
details = self.safe_list(liquidation, 'details', [])
|
624
|
+
liquidationDetails = self.safe_dict(details, 0, {})
|
625
|
+
marketId = self.safe_string(liquidation, 'instId')
|
626
|
+
market = self.safe_market(marketId, market)
|
627
|
+
timestamp = self.safe_integer(liquidationDetails, 'ts')
|
628
|
+
return self.safe_liquidation({
|
629
|
+
'info': liquidation,
|
630
|
+
'symbol': self.safe_symbol(marketId, market),
|
631
|
+
'contracts': self.safe_number(liquidationDetails, 'sz'),
|
632
|
+
'contractSize': self.safe_number(market, 'contractSize'),
|
633
|
+
'price': self.safe_number(liquidationDetails, 'bkPx'),
|
634
|
+
'baseValue': None,
|
635
|
+
'quoteValue': None,
|
636
|
+
'timestamp': timestamp,
|
637
|
+
'datetime': self.iso8601(timestamp),
|
638
|
+
})
|
639
|
+
|
402
640
|
async def watch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
403
641
|
"""
|
404
642
|
watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
@@ -819,6 +1057,9 @@ class okx(ccxt.async_support.okx):
|
|
819
1057
|
await self.authenticate()
|
820
1058
|
return await self.subscribe('private', 'account', 'account', None, params)
|
821
1059
|
|
1060
|
+
def handle_balance_and_position(self, client: Client, message):
|
1061
|
+
self.handle_my_liquidation(client, message)
|
1062
|
+
|
822
1063
|
def handle_balance(self, client: Client, message):
|
823
1064
|
#
|
824
1065
|
# {
|
@@ -1600,6 +1841,8 @@ class okx(ccxt.async_support.okx):
|
|
1600
1841
|
# 'margin_account': self.handle_balance,
|
1601
1842
|
'orders': self.handle_orders,
|
1602
1843
|
'orders-algo': self.handle_orders,
|
1844
|
+
'liquidation-orders': self.handle_liquidation,
|
1845
|
+
'balance_and_position': self.handle_balance_and_position,
|
1603
1846
|
}
|
1604
1847
|
method = self.safe_value(methods, channel)
|
1605
1848
|
if method is None:
|
ccxt/probit.py
CHANGED
@@ -276,7 +276,7 @@ class probit(Exchange, ImplicitAPI):
|
|
276
276
|
markets = self.safe_value(response, 'data', [])
|
277
277
|
return self.parse_markets(markets)
|
278
278
|
|
279
|
-
def parse_market(self, market) -> Market:
|
279
|
+
def parse_market(self, market: dict) -> Market:
|
280
280
|
id = self.safe_string(market, 'id')
|
281
281
|
baseId = self.safe_string(market, 'base_currency_id')
|
282
282
|
quoteId = self.safe_string(market, 'quote_currency_id')
|
@@ -1511,7 +1511,7 @@ class probit(Exchange, ImplicitAPI):
|
|
1511
1511
|
'info': transaction,
|
1512
1512
|
}
|
1513
1513
|
|
1514
|
-
def parse_transaction_status(self, status):
|
1514
|
+
def parse_transaction_status(self, status: Str):
|
1515
1515
|
statuses: dict = {
|
1516
1516
|
'requested': 'pending',
|
1517
1517
|
'pending': 'pending',
|
@@ -1720,7 +1720,7 @@ class probit(Exchange, ImplicitAPI):
|
|
1720
1720
|
self.options['expires'] = self.sum(self.milliseconds(), expiresIn * 1000)
|
1721
1721
|
return response
|
1722
1722
|
|
1723
|
-
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
1723
|
+
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
1724
1724
|
if response is None:
|
1725
1725
|
return None # fallback to default error handler
|
1726
1726
|
if 'errorCode' in response:
|
ccxt/test/base/__init__.py
CHANGED
@@ -14,6 +14,7 @@ from ccxt.test.base.test_funding_rate_history import test_funding_rate_history #
|
|
14
14
|
from ccxt.test.base.test_last_price import test_last_price # noqa E402
|
15
15
|
from ccxt.test.base.test_ledger_entry import test_ledger_entry # noqa E402
|
16
16
|
from ccxt.test.base.test_leverage_tier import test_leverage_tier # noqa E402
|
17
|
+
from ccxt.test.base.test_liquidation import test_liquidation # noqa E402
|
17
18
|
from ccxt.test.base.test_margin_mode import test_margin_mode # noqa E402
|
18
19
|
from ccxt.test.base.test_margin_modification import test_margin_modification # noqa E402
|
19
20
|
from ccxt.test.base.test_market import test_market # noqa E402
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import os
|
2
|
+
import sys
|
3
|
+
|
4
|
+
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
5
|
+
sys.path.append(root)
|
6
|
+
|
7
|
+
# ----------------------------------------------------------------------------
|
8
|
+
|
9
|
+
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
10
|
+
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
11
|
+
|
12
|
+
# ----------------------------------------------------------------------------
|
13
|
+
# -*- coding: utf-8 -*-
|
14
|
+
|
15
|
+
from ccxt.base.precise import Precise # noqa E402
|
16
|
+
from ccxt.test.base import test_shared_methods # noqa E402
|
17
|
+
|
18
|
+
def test_liquidation(exchange, skipped_properties, method, entry, symbol):
|
19
|
+
format = {
|
20
|
+
'info': {},
|
21
|
+
'symbol': 'ETH/BTC',
|
22
|
+
'contracts': exchange.parse_number('1.234'),
|
23
|
+
'contractSize': exchange.parse_number('1.234'),
|
24
|
+
'price': exchange.parse_number('1.234'),
|
25
|
+
'baseValue': exchange.parse_number('1.234'),
|
26
|
+
'quoteValue': exchange.parse_number('1.234'),
|
27
|
+
'timestamp': 1502962946216,
|
28
|
+
'datetime': '2017-09-01T00:00:00',
|
29
|
+
}
|
30
|
+
# todo: atm, many exchanges fail, so temporarily decrease stict mode
|
31
|
+
empty_allowed_for = ['timestamp', 'datetime', 'quoteValue', 'baseValue', 'previousClose', 'price', 'contractSize', 'contracts']
|
32
|
+
test_shared_methods.assert_structure(exchange, skipped_properties, method, entry, format, empty_allowed_for)
|
33
|
+
test_shared_methods.assert_timestamp_and_datetime(exchange, skipped_properties, method, entry)
|
34
|
+
log_text = test_shared_methods.log_template(exchange, method, entry)
|
35
|
+
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'contracts', '0')
|
36
|
+
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'contractSize', '0')
|
37
|
+
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'price', '0')
|
38
|
+
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'baseValue', '0')
|
39
|
+
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'quoteValue', '0')
|
40
|
+
contracts = exchange.safe_string(entry, 'contracts')
|
41
|
+
contract_size = exchange.safe_string(entry, 'contractSize')
|
42
|
+
price = exchange.safe_string(entry, 'price')
|
43
|
+
base_value = exchange.safe_string(entry, 'baseValue')
|
44
|
+
if contracts and contract_size:
|
45
|
+
assert Precise.string_eq(base_value, Precise.string_mul(contracts, contract_size)), 'baseValue == contracts * contractSize' + log_text
|
46
|
+
if price:
|
47
|
+
assert Precise.string_eq(base_value, Precise.string_mul(Precise.string_mul(contracts, contract_size), price)), 'quoteValue == contracts * contractSize * price' + log_text
|
48
|
+
# if singular was called, then symbol needs to be asserted
|
49
|
+
if method == 'watchLiquidations' or method == 'fetchLiquidations':
|
50
|
+
test_shared_methods.assert_symbol(exchange, skipped_properties, method, entry, 'symbol', symbol)
|
ccxt/timex.py
CHANGED
@@ -1142,7 +1142,7 @@ class timex(Exchange, ImplicitAPI):
|
|
1142
1142
|
result = self.safe_value(response, 0, {})
|
1143
1143
|
return self.parse_trading_fee(result, market)
|
1144
1144
|
|
1145
|
-
def parse_market(self, market) -> Market:
|
1145
|
+
def parse_market(self, market: dict) -> Market:
|
1146
1146
|
#
|
1147
1147
|
# {
|
1148
1148
|
# "symbol": "ETHBTC",
|
@@ -1572,7 +1572,7 @@ class timex(Exchange, ImplicitAPI):
|
|
1572
1572
|
headers = {'authorization': secret}
|
1573
1573
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
1574
1574
|
|
1575
|
-
def handle_errors(self, statusCode, statusText, url, method, responseHeaders, responseBody, response, requestHeaders, requestBody):
|
1575
|
+
def handle_errors(self, statusCode: int, statusText: str, url: str, method: str, responseHeaders: dict, responseBody, response, requestHeaders, requestBody):
|
1576
1576
|
if response is None:
|
1577
1577
|
return None
|
1578
1578
|
if statusCode >= 400:
|
ccxt/tokocrypto.py
CHANGED
@@ -2331,7 +2331,7 @@ class tokocrypto(Exchange, ImplicitAPI):
|
|
2331
2331
|
url += '?' + self.urlencode(params)
|
2332
2332
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
2333
2333
|
|
2334
|
-
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
2334
|
+
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
2335
2335
|
if (code == 418) or (code == 429):
|
2336
2336
|
raise DDoSProtection(self.id + ' ' + str(code) + ' ' + reason + ' ' + body)
|
2337
2337
|
# error response in a form: {"code": -1013, "msg": "Invalid quantity."}
|
ccxt/tradeogre.py
CHANGED
@@ -581,7 +581,7 @@ class tradeogre(Exchange, ImplicitAPI):
|
|
581
581
|
body = self.urlencode(params)
|
582
582
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
583
583
|
|
584
|
-
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
584
|
+
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
585
585
|
if response is None:
|
586
586
|
return None
|
587
587
|
if not ('success' in response):
|
ccxt/upbit.py
CHANGED
@@ -423,7 +423,7 @@ class upbit(Exchange, ImplicitAPI):
|
|
423
423
|
#
|
424
424
|
return self.parse_markets(response)
|
425
425
|
|
426
|
-
def parse_market(self, market) -> Market:
|
426
|
+
def parse_market(self, market: dict) -> Market:
|
427
427
|
id = self.safe_string(market, 'market')
|
428
428
|
quoteId, baseId = id.split('-')
|
429
429
|
base = self.safe_currency_code(baseId)
|
@@ -1261,7 +1261,7 @@ class upbit(Exchange, ImplicitAPI):
|
|
1261
1261
|
#
|
1262
1262
|
return self.parse_transaction(response, currency)
|
1263
1263
|
|
1264
|
-
def parse_transaction_status(self, status):
|
1264
|
+
def parse_transaction_status(self, status: Str):
|
1265
1265
|
statuses: dict = {
|
1266
1266
|
'submitting': 'pending', # 처리 중
|
1267
1267
|
'submitted': 'pending', # 처리 완료
|
@@ -1801,7 +1801,7 @@ class upbit(Exchange, ImplicitAPI):
|
|
1801
1801
|
headers['Content-Type'] = 'application/json'
|
1802
1802
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
1803
1803
|
|
1804
|
-
def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
1804
|
+
def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
1805
1805
|
if response is None:
|
1806
1806
|
return None # fallback to default error handler
|
1807
1807
|
#
|