trio-binance 0.3.0__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.
- LICENSE +21 -0
- trio_binance/__init__.py +3 -0
- trio_binance/client.py +1671 -0
- trio_binance/enums.py +70 -0
- trio_binance/exceptions.py +76 -0
- trio_binance/helpers.py +49 -0
- trio_binance/streams.py +101 -0
- trio_binance-0.3.0.dist-info/LICENSE +21 -0
- trio_binance-0.3.0.dist-info/METADATA +62 -0
- trio_binance-0.3.0.dist-info/RECORD +11 -0
- trio_binance-0.3.0.dist-info/WHEEL +4 -0
trio_binance/enums.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
SYMBOL_TYPE_SPOT = "SPOT"
|
|
4
|
+
|
|
5
|
+
ORDER_STATUS_NEW = "NEW"
|
|
6
|
+
ORDER_STATUS_PARTIALLY_FILLED = "PARTIALLY_FILLED"
|
|
7
|
+
ORDER_STATUS_FILLED = "FILLED"
|
|
8
|
+
ORDER_STATUS_CANCELED = "CANCELED"
|
|
9
|
+
ORDER_STATUS_PENDING_CANCEL = "PENDING_CANCEL"
|
|
10
|
+
ORDER_STATUS_REJECTED = "REJECTED"
|
|
11
|
+
ORDER_STATUS_EXPIRED = "EXPIRED"
|
|
12
|
+
|
|
13
|
+
KLINE_INTERVAL_1MINUTE = "1m"
|
|
14
|
+
KLINE_INTERVAL_3MINUTE = "3m"
|
|
15
|
+
KLINE_INTERVAL_5MINUTE = "5m"
|
|
16
|
+
KLINE_INTERVAL_15MINUTE = "15m"
|
|
17
|
+
KLINE_INTERVAL_30MINUTE = "30m"
|
|
18
|
+
KLINE_INTERVAL_1HOUR = "1h"
|
|
19
|
+
KLINE_INTERVAL_2HOUR = "2h"
|
|
20
|
+
KLINE_INTERVAL_4HOUR = "4h"
|
|
21
|
+
KLINE_INTERVAL_6HOUR = "6h"
|
|
22
|
+
KLINE_INTERVAL_8HOUR = "8h"
|
|
23
|
+
KLINE_INTERVAL_12HOUR = "12h"
|
|
24
|
+
KLINE_INTERVAL_1DAY = "1d"
|
|
25
|
+
KLINE_INTERVAL_3DAY = "3d"
|
|
26
|
+
KLINE_INTERVAL_1WEEK = "1w"
|
|
27
|
+
KLINE_INTERVAL_1MONTH = "1M"
|
|
28
|
+
|
|
29
|
+
SIDE_BUY = "BUY"
|
|
30
|
+
SIDE_SELL = "SELL"
|
|
31
|
+
|
|
32
|
+
ORDER_TYPE_LIMIT = "LIMIT"
|
|
33
|
+
ORDER_TYPE_MARKET = "MARKET"
|
|
34
|
+
ORDER_TYPE_STOP_LOSS = "STOP_LOSS"
|
|
35
|
+
ORDER_TYPE_STOP_LOSS_LIMIT = "STOP_LOSS_LIMIT"
|
|
36
|
+
ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT"
|
|
37
|
+
ORDER_TYPE_TAKE_PROFIT_LIMIT = "TAKE_PROFIT_LIMIT"
|
|
38
|
+
ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER"
|
|
39
|
+
|
|
40
|
+
FUTURE_ORDER_TYPE_LIMIT = "LIMIT"
|
|
41
|
+
FUTURE_ORDER_TYPE_MARKET = "MARKET"
|
|
42
|
+
FUTURE_ORDER_TYPE_STOP = "STOP"
|
|
43
|
+
FUTURE_ORDER_TYPE_STOP_MARKET = "STOP_MARKET"
|
|
44
|
+
FUTURE_ORDER_TYPE_TAKE_PROFIT = "TAKE_PROFIT"
|
|
45
|
+
FUTURE_ORDER_TYPE_TAKE_PROFIT_MARKET = "TAKE_PROFIT_MARKET"
|
|
46
|
+
FUTURE_ORDER_TYPE_LIMIT_MAKER = "LIMIT_MAKER"
|
|
47
|
+
|
|
48
|
+
TIME_IN_FORCE_GTC = "GTC" # Good till cancelled
|
|
49
|
+
TIME_IN_FORCE_IOC = "IOC" # Immediate or cancel
|
|
50
|
+
TIME_IN_FORCE_FOK = "FOK" # Fill or kill
|
|
51
|
+
TIME_IN_FORCE_GTX = "GTX" # Post only order
|
|
52
|
+
|
|
53
|
+
ORDER_RESP_TYPE_ACK = "ACK"
|
|
54
|
+
ORDER_RESP_TYPE_RESULT = "RESULT"
|
|
55
|
+
ORDER_RESP_TYPE_FULL = "FULL"
|
|
56
|
+
|
|
57
|
+
WEBSOCKET_DEPTH_5 = "5"
|
|
58
|
+
WEBSOCKET_DEPTH_10 = "10"
|
|
59
|
+
WEBSOCKET_DEPTH_20 = "20"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class FuturesType(Enum):
|
|
63
|
+
USD_M = 1
|
|
64
|
+
COIN_M = 2
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class ContractType(Enum):
|
|
68
|
+
PERPETUAL = "perpetual"
|
|
69
|
+
CURRENT_QUARTER = "current_quarter"
|
|
70
|
+
NEXT_QUARTER = "next_quarter"
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import orjson
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BinanceAPIException(Exception):
|
|
5
|
+
def __init__(self, response, status_code, text):
|
|
6
|
+
self.code = 0
|
|
7
|
+
try:
|
|
8
|
+
json_res = orjson.loads(text)
|
|
9
|
+
except ValueError:
|
|
10
|
+
self.message = "Invalid JSON error message from Binance: {}".format(response.text)
|
|
11
|
+
else:
|
|
12
|
+
self.code = json_res["code"]
|
|
13
|
+
self.message = json_res["msg"]
|
|
14
|
+
self.status_code = status_code
|
|
15
|
+
self.response = response
|
|
16
|
+
self.request = getattr(response, "request", None)
|
|
17
|
+
|
|
18
|
+
def __str__(self): # pragma: no cover
|
|
19
|
+
return "APIError(code=%s): %s" % (self.code, self.message)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BinanceRequestException(Exception):
|
|
23
|
+
def __init__(self, message):
|
|
24
|
+
self.message = message
|
|
25
|
+
|
|
26
|
+
def __str__(self):
|
|
27
|
+
return "BinanceRequestException: %s" % self.message
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class BinanceOrderException(Exception):
|
|
31
|
+
def __init__(self, code, message):
|
|
32
|
+
self.code = code
|
|
33
|
+
self.message = message
|
|
34
|
+
|
|
35
|
+
def __str__(self):
|
|
36
|
+
return "BinanceOrderException(code=%s): %s" % (self.code, self.message)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BinanceOrderMinAmountException(BinanceOrderException):
|
|
40
|
+
def __init__(self, value):
|
|
41
|
+
message = "Amount must be a multiple of %s" % value
|
|
42
|
+
super().__init__(-1013, message)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BinanceOrderMinPriceException(BinanceOrderException):
|
|
46
|
+
def __init__(self, value):
|
|
47
|
+
message = "Price must be at least %s" % value
|
|
48
|
+
super().__init__(-1013, message)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class BinanceOrderMinTotalException(BinanceOrderException):
|
|
52
|
+
def __init__(self, value):
|
|
53
|
+
message = "Total must be at least %s" % value
|
|
54
|
+
super().__init__(-1013, message)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class BinanceOrderUnknownSymbolException(BinanceOrderException):
|
|
58
|
+
def __init__(self, value):
|
|
59
|
+
message = "Unknown symbol %s" % value
|
|
60
|
+
super().__init__(-1013, message)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class BinanceOrderInactiveSymbolException(BinanceOrderException):
|
|
64
|
+
def __init__(self, value):
|
|
65
|
+
message = "Attempting to trade an inactive symbol %s" % value
|
|
66
|
+
super().__init__(-1013, message)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class BinanceWebsocketUnableToConnect(Exception):
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class NotImplementedException(Exception):
|
|
74
|
+
def __init__(self, value):
|
|
75
|
+
message = f"Not implemented: {value}"
|
|
76
|
+
super().__init__(message)
|
trio_binance/helpers.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
from typing import Union, Optional, Dict
|
|
3
|
+
|
|
4
|
+
import dateparser
|
|
5
|
+
import math
|
|
6
|
+
import pytz
|
|
7
|
+
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def date_to_milliseconds(date_str: str) -> int:
|
|
12
|
+
"""Convert UTC date to milliseconds
|
|
13
|
+
|
|
14
|
+
If using offset strings add "UTC" to date string e.g. "now UTC", "11 hours ago UTC"
|
|
15
|
+
|
|
16
|
+
See dateparse docs for formats http://dateparser.readthedocs.io/en/latest/
|
|
17
|
+
|
|
18
|
+
:param date_str: date in readable format, i.e. "January 01, 2018", "11 hours ago UTC", "now UTC"
|
|
19
|
+
"""
|
|
20
|
+
# get epoch value in UTC
|
|
21
|
+
epoch: datetime = datetime.utcfromtimestamp(0).replace(tzinfo=pytz.utc)
|
|
22
|
+
# parse our date string
|
|
23
|
+
d: Optional[datetime] = dateparser.parse(date_str, settings={"TIMEZONE": "UTC"})
|
|
24
|
+
# if the date is not timezone aware apply UTC timezone
|
|
25
|
+
if d.tzinfo is None or d.tzinfo.utcoffset(d) is None:
|
|
26
|
+
d = d.replace(tzinfo=pytz.utc)
|
|
27
|
+
|
|
28
|
+
# return the difference in time
|
|
29
|
+
return int((d - epoch).total_seconds() * 1000.0)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def round_step_size(quantity: Union[float, Decimal], step_size: Union[float, Decimal]) -> float:
|
|
33
|
+
"""Rounds a given quantity to a specific step size
|
|
34
|
+
|
|
35
|
+
:param quantity: required
|
|
36
|
+
:param step_size: required
|
|
37
|
+
|
|
38
|
+
:return: decimal
|
|
39
|
+
"""
|
|
40
|
+
precision: int = int(round(-math.log(step_size, 10), 0))
|
|
41
|
+
return float(round(quantity, precision))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def convert_ts_str(ts_str):
|
|
45
|
+
if ts_str is None:
|
|
46
|
+
return ts_str
|
|
47
|
+
if type(ts_str) == int:
|
|
48
|
+
return ts_str
|
|
49
|
+
return date_to_milliseconds(ts_str)
|
trio_binance/streams.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from contextlib import asynccontextmanager
|
|
2
|
+
from random import randint
|
|
3
|
+
|
|
4
|
+
import trio
|
|
5
|
+
import trio_websocket
|
|
6
|
+
import orjson
|
|
7
|
+
from trio_websocket import open_websocket_url
|
|
8
|
+
|
|
9
|
+
from trio_binance import AsyncClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BinanceSocketManager:
|
|
13
|
+
URLS = {
|
|
14
|
+
"main": {
|
|
15
|
+
"spot": "wss://stream.binance.com:9443",
|
|
16
|
+
"linear": "wss://fstream.binance.com",
|
|
17
|
+
"inverse": "wss://dstream.binance.com",
|
|
18
|
+
"portfolio": "wss://fstream.binance.com/pm",
|
|
19
|
+
},
|
|
20
|
+
"test": {},
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
client: AsyncClient,
|
|
26
|
+
endpoint: str = "spot",
|
|
27
|
+
alternative_net: str = "",
|
|
28
|
+
private=False,
|
|
29
|
+
):
|
|
30
|
+
self.ws: trio_websocket.WebSocketConnection | None = None
|
|
31
|
+
self.endpoint: str = endpoint
|
|
32
|
+
self.alternative_net: str = alternative_net if alternative_net else "main"
|
|
33
|
+
self.client: AsyncClient = client
|
|
34
|
+
self.listen_key: str = ""
|
|
35
|
+
self.user_data_stream = private
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
async def create(
|
|
39
|
+
cls,
|
|
40
|
+
client: AsyncClient,
|
|
41
|
+
endpoint: str = "spot",
|
|
42
|
+
alternative_net: str = "",
|
|
43
|
+
private=False,
|
|
44
|
+
):
|
|
45
|
+
self = cls(client, endpoint, alternative_net, private)
|
|
46
|
+
if self.endpoint == "spot":
|
|
47
|
+
self.listen_key = await self.client.stream_get_listen_key()
|
|
48
|
+
elif self.endpoint == "linear":
|
|
49
|
+
self.listen_key = await self.client.futures_stream_get_listen_key()
|
|
50
|
+
elif self.endpoint == "inverse":
|
|
51
|
+
self.listen_key = await self.client.futures_coin_stream_get_listen_key()
|
|
52
|
+
elif self.endpoint == "portfolio":
|
|
53
|
+
self.listen_key = await self.client.portfolio_margin_stream_get_listen_key()
|
|
54
|
+
return self
|
|
55
|
+
|
|
56
|
+
@asynccontextmanager
|
|
57
|
+
async def connect(self):
|
|
58
|
+
try:
|
|
59
|
+
base_url = self.URLS[self.alternative_net][self.endpoint]
|
|
60
|
+
if self.user_data_stream:
|
|
61
|
+
url = f"{base_url}/ws/{self.listen_key}"
|
|
62
|
+
else:
|
|
63
|
+
url = f"{base_url}/stream"
|
|
64
|
+
except KeyError:
|
|
65
|
+
raise ValueError(f"endpoint {self.endpoint} with net {self.alternative_net} not supported")
|
|
66
|
+
async with open_websocket_url(url) as ws:
|
|
67
|
+
self.ws = ws
|
|
68
|
+
async with trio.open_nursery() as nursery:
|
|
69
|
+
nursery.start_soon(self.keepalive)
|
|
70
|
+
yield self.ws
|
|
71
|
+
nursery.cancel_scope.cancel()
|
|
72
|
+
|
|
73
|
+
async def keepalive(self):
|
|
74
|
+
while True:
|
|
75
|
+
await trio.sleep(59 * 60)
|
|
76
|
+
with trio.fail_after(5):
|
|
77
|
+
if self.endpoint == "spot":
|
|
78
|
+
await self.client.stream_keepalive()
|
|
79
|
+
elif self.endpoint == "linear":
|
|
80
|
+
await self.client.futures_stream_keepalive()
|
|
81
|
+
elif self.endpoint == "inverse":
|
|
82
|
+
await self.client.futures_coin_stream_keepalive()
|
|
83
|
+
elif self.endpoint == "portfolio":
|
|
84
|
+
await self.client.portfolio_margin_stream_keepalive()
|
|
85
|
+
|
|
86
|
+
async def subscribe(self, params: list[str], sub_id: int | None = None):
|
|
87
|
+
if sub_id is None:
|
|
88
|
+
sub_id = randint(1, 2147483647)
|
|
89
|
+
await self.ws.send_message(orjson.dumps({"method": "SUBSCRIBE", "params": params, "id": sub_id}))
|
|
90
|
+
|
|
91
|
+
async def list_subscribe(self, sub_id: int | None = None):
|
|
92
|
+
await self.ws.send_message(orjson.dumps({"method": "LIST_SUBSCRIPTIONS", "id": sub_id}))
|
|
93
|
+
|
|
94
|
+
async def unsubscribe(self, params: list[str], sub_id: int | None = None):
|
|
95
|
+
await self.ws.send_message(orjson.dumps({"method": "UNSUBSCRIBE", "params": params, "id": sub_id}))
|
|
96
|
+
|
|
97
|
+
async def get_next_message(self):
|
|
98
|
+
while True:
|
|
99
|
+
raw_message = await self.ws.get_message()
|
|
100
|
+
message = orjson.loads(raw_message)
|
|
101
|
+
yield message
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Shu Wang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: trio-binance
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: trio based asynchronous binance SDK
|
|
5
|
+
Home-page: https://github.com/halfelf/trio-binance
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: binance,python-trio
|
|
8
|
+
Author: Shu Wang
|
|
9
|
+
Author-email: halfelf.ronin@gmail.com
|
|
10
|
+
Requires-Python: >=3.11,<4.0
|
|
11
|
+
Classifier: Framework :: Trio
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Requires-Dist: dateparser (>=1.1.0,<2.0.0)
|
|
19
|
+
Requires-Dist: h2 (>=4.1.0,<5.0.0)
|
|
20
|
+
Requires-Dist: httpx (>0.20.0)
|
|
21
|
+
Requires-Dist: orjson (>=3.6.0,<4.0.0)
|
|
22
|
+
Requires-Dist: pytz (>=2024.1,<2025.0)
|
|
23
|
+
Requires-Dist: trio (>=0.25.0)
|
|
24
|
+
Requires-Dist: trio-websocket (>=0.11.1,<0.12.0)
|
|
25
|
+
Project-URL: Repository, https://github.com/halfelf/trio-binance
|
|
26
|
+
Description-Content-Type: text/x-rst
|
|
27
|
+
|
|
28
|
+
=================================
|
|
29
|
+
Welcome to trio-binance
|
|
30
|
+
=================================
|
|
31
|
+
|
|
32
|
+
This is an unofficial Python wrapper for the `Binance exchange REST API v3 <https://binance-docs.github.io/apidocs/spot/en>`_. I am in no way affiliated with Binance, use at your own risk.
|
|
33
|
+
|
|
34
|
+
And this repository is forked from `python-binance <https://github.com/sammchardy/python-binance>`_, but has only async client, and works **only** with `trio <https://trio.readthedocs.io/en/stable/index.html>`_ or `trio-compatible <https://trio.readthedocs.io/en/stable/awesome-trio-libraries.html#trio-asyncio-interoperability>`_ asynchronous frameworks.
|
|
35
|
+
|
|
36
|
+
Source code
|
|
37
|
+
https://github.com/halfelf/trio-binance
|
|
38
|
+
|
|
39
|
+
Quick Start
|
|
40
|
+
-----------
|
|
41
|
+
|
|
42
|
+
`Register an account with Binance <https://accounts.binance.com/en/register?ref=10099792>`_.
|
|
43
|
+
|
|
44
|
+
`Generate an API Key <https://www.binance.com/en/my/settings/api-management>`_ and assign relevant permissions.
|
|
45
|
+
|
|
46
|
+
.. code:: bash
|
|
47
|
+
|
|
48
|
+
pip install trio-binance
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
Example
|
|
52
|
+
-------------
|
|
53
|
+
|
|
54
|
+
Check pytest file under ``tests``.
|
|
55
|
+
|
|
56
|
+
Donate
|
|
57
|
+
------
|
|
58
|
+
|
|
59
|
+
If this library helps, feel free to donate.
|
|
60
|
+
|
|
61
|
+
- ETH: 0xf560e5F7F234307A20670ed8A5778F350a8366d1
|
|
62
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE,sha256=h6dW5yRP__7ICaHJi7ZbKAO5Eln9wBs9Yd84flq0VB0,1065
|
|
2
|
+
trio_binance/__init__.py,sha256=8s8wr4KTwy9DmgUNbowHLksHnFLjdshF6bU1Q5neFYw,67
|
|
3
|
+
trio_binance/client.py,sha256=pPqWWsAa6hdLSKMBWDT5UrPsGxFubOLMlZr0hA_FrvE,77725
|
|
4
|
+
trio_binance/enums.py,sha256=YS2NARvK7nMfok_YUqip_Z85ju9eR0FKrHhyMMsk4hY,1891
|
|
5
|
+
trio_binance/exceptions.py,sha256=EVEDajSR3MP-Oa_9O1OW5qe7SLKPv75RI30wH7KH9sg,2260
|
|
6
|
+
trio_binance/helpers.py,sha256=7y6hcFACJnrP4x2Y0yfxBJmks6piy6qWwWHa3Vxop8U,1493
|
|
7
|
+
trio_binance/streams.py,sha256=2xo2SW47lLtPL1mZmA4ZLqxTzLIueg1_mEluXhrWrLs,3780
|
|
8
|
+
trio_binance-0.3.0.dist-info/LICENSE,sha256=h6dW5yRP__7ICaHJi7ZbKAO5Eln9wBs9Yd84flq0VB0,1065
|
|
9
|
+
trio_binance-0.3.0.dist-info/METADATA,sha256=fiAsFBRQIj3JreU-crvlDLnMBM0LGu5OqfFr-7TDSHI,2134
|
|
10
|
+
trio_binance-0.3.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
11
|
+
trio_binance-0.3.0.dist-info/RECORD,,
|