py-near 1.1.46__py3-none-any.whl → 1.1.47__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.
py_near/providers.py
CHANGED
@@ -5,8 +5,7 @@ import json
|
|
5
5
|
from collections import Counter
|
6
6
|
from typing import Optional
|
7
7
|
|
8
|
-
import
|
9
|
-
from aiohttp import ClientResponseError, ClientConnectorError, ServerDisconnectedError
|
8
|
+
import httpx
|
10
9
|
from loguru import logger
|
11
10
|
|
12
11
|
from py_near.constants import TIMEOUT_WAIT_RPC
|
@@ -61,6 +60,7 @@ class JsonProvider(object):
|
|
61
60
|
self._last_rpc_addr_check = 0
|
62
61
|
self.allow_broadcast = allow_broadcast
|
63
62
|
self._timeout = timeout
|
63
|
+
self._client: httpx.AsyncClient = httpx.AsyncClient()
|
64
64
|
|
65
65
|
async def shutdown(self):
|
66
66
|
pass
|
@@ -94,35 +94,41 @@ class JsonProvider(object):
|
|
94
94
|
"id": 1,
|
95
95
|
}
|
96
96
|
auth_key = "py-near"
|
97
|
+
rpc_addr_url = rpc_addr
|
97
98
|
if "@" in rpc_addr:
|
98
|
-
auth_key =
|
99
|
-
|
100
|
-
|
101
|
-
|
99
|
+
auth_key = rpc_addr_url.split("//")[1].split("@")[0]
|
100
|
+
rpc_addr_url = rpc_addr_url.replace(auth_key + "@", "")
|
101
|
+
|
102
|
+
r = await self._client.post(
|
103
|
+
rpc_addr_url,
|
104
|
+
json=data,
|
105
|
+
headers={
|
102
106
|
"Referer": "https://tgapp.herewallet.app",
|
103
107
|
"Authorization": f"Bearer {auth_key}",
|
104
|
-
}
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
108
|
+
},
|
109
|
+
)
|
110
|
+
if r.status_code == 200:
|
111
|
+
data = json.loads(r.text)["result"]
|
112
|
+
diff = 0
|
113
|
+
if data["sync_info"]["syncing"]:
|
114
|
+
last_block_ts = datetime.datetime.fromisoformat(
|
115
|
+
data["sync_info"]["latest_block_time"]
|
116
|
+
)
|
117
|
+
diff = (
|
118
|
+
datetime.datetime.utcnow().timestamp()
|
119
|
+
- last_block_ts.timestamp()
|
120
|
+
)
|
121
|
+
is_syncing = diff > 60
|
122
|
+
else:
|
123
|
+
is_syncing = False
|
124
|
+
if is_syncing:
|
125
|
+
logger.error(f"Remove async RPC : {rpc_addr} ({diff})")
|
126
|
+
continue
|
127
|
+
available_rpcs.append(rpc_addr)
|
128
|
+
else:
|
129
|
+
logger.error(
|
130
|
+
f"Remove rpc because of error {r.status_code}: {rpc_addr}"
|
131
|
+
)
|
126
132
|
except Exception as e:
|
127
133
|
if rpc_addr in self._available_rpcs:
|
128
134
|
logger.error(f"Remove rpc: {e}")
|
@@ -146,24 +152,26 @@ class JsonProvider(object):
|
|
146
152
|
if "@" in rpc_call_addr:
|
147
153
|
auth_key = rpc_call_addr.split("//")[1].split("@")[0]
|
148
154
|
rpc_call_addr = rpc_call_addr.replace(auth_key + "@", "")
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
"
|
163
|
-
"
|
164
|
-
"
|
165
|
-
}
|
155
|
+
r = await self._client.post(
|
156
|
+
rpc_call_addr,
|
157
|
+
json=j,
|
158
|
+
timeout=self._timeout,
|
159
|
+
headers={
|
160
|
+
"Referer": "https://tgapp.herewallet.app",
|
161
|
+
"Authorization": f"Bearer {auth_key}",
|
162
|
+
},
|
163
|
+
)
|
164
|
+
if r.status_code == 200:
|
165
|
+
return json.loads(r.text)
|
166
|
+
return {
|
167
|
+
"error": {
|
168
|
+
"cause": {
|
169
|
+
"name": "RPC_ERROR",
|
170
|
+
"message": f"Status: {r.status_code}",
|
171
|
+
},
|
172
|
+
"data": r.text,
|
166
173
|
}
|
174
|
+
}
|
167
175
|
|
168
176
|
if broadcast or threshold:
|
169
177
|
pending = [
|
@@ -190,14 +198,18 @@ class JsonProvider(object):
|
|
190
198
|
array = [hash(json.dumps(x)) for x in responses]
|
191
199
|
most_frequent_element = self.most_frequent_by_hash(array)
|
192
200
|
correct_responses = [
|
193
|
-
x
|
201
|
+
x
|
202
|
+
for x in responses
|
203
|
+
if hash(json.dumps(x)) == most_frequent_element
|
194
204
|
]
|
195
205
|
if len(correct_responses) >= threshold:
|
196
206
|
for task in pending:
|
197
207
|
task.cancel()
|
198
|
-
return
|
208
|
+
return correct_responses[0]
|
199
209
|
if threshold and threshold > 0:
|
200
|
-
raise RpcEmptyResponse(
|
210
|
+
raise RpcEmptyResponse(
|
211
|
+
f"Threshold not reached: {len(correct_responses)}/{threshold}"
|
212
|
+
)
|
201
213
|
return result
|
202
214
|
else:
|
203
215
|
res = None
|
@@ -210,7 +222,6 @@ class JsonProvider(object):
|
|
210
222
|
logger.error(f"Rpc error: {e}")
|
211
223
|
continue
|
212
224
|
return res
|
213
|
-
raise RpcEmptyResponse("RPC returned empty response")
|
214
225
|
|
215
226
|
@staticmethod
|
216
227
|
def get_error_from_response(content: dict):
|
@@ -315,7 +326,7 @@ class JsonProvider(object):
|
|
315
326
|
|
316
327
|
async def get_status(self):
|
317
328
|
await self.check_available_rpcs()
|
318
|
-
for rpc_addr in self._available_rpcs:
|
329
|
+
for rpc_addr in self._available_rpcs.copy():
|
319
330
|
try:
|
320
331
|
data = {
|
321
332
|
"jsonrpc": "2.0",
|
@@ -323,16 +334,19 @@ class JsonProvider(object):
|
|
323
334
|
"params": {"finality": "final"},
|
324
335
|
"id": 1,
|
325
336
|
}
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
337
|
+
headers = {
|
338
|
+
"Referer": "https://tgapp.herewallet.app",
|
339
|
+
}
|
340
|
+
if "@" in rpc_addr:
|
341
|
+
auth_key = rpc_addr.split("//")[1].split("@")[0]
|
342
|
+
rpc_addr = rpc_addr.replace(auth_key + "@", "")
|
343
|
+
headers = {
|
344
|
+
"Authorization": f"Bearer {auth_key}"
|
345
|
+
}
|
346
|
+
r = await self._client.post(rpc_addr, json=data, headers=headers)
|
347
|
+
if r.status_code == 200:
|
348
|
+
return json.loads(r.text)["result"]
|
349
|
+
except ConnectionError as e:
|
336
350
|
logger.error(f"Rpc get status error: {e}")
|
337
351
|
except Exception as e:
|
338
352
|
logger.error(e)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: py-near
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.47
|
4
4
|
Summary: Pretty simple and fully asynchronous framework for working with NEAR blockchain
|
5
5
|
Author: pvolnov
|
6
6
|
Author-email: petr@herewallet.app
|
@@ -12,9 +12,9 @@ Classifier: Programming Language :: Python :: 3.9
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
15
|
-
Requires-Dist:
|
16
|
-
Requires-Dist:
|
17
|
-
Requires-Dist: py-near-primitives (
|
15
|
+
Requires-Dist: ed25519 (==1.5)
|
16
|
+
Requires-Dist: httpx (==0.27.0)
|
17
|
+
Requires-Dist: py-near-primitives (==0.2.3)
|
18
18
|
Description-Content-Type: text/markdown
|
19
19
|
|
20
20
|
# py-near
|
@@ -20,10 +20,10 @@ py_near/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
|
|
20
20
|
py_near/exceptions/exceptions.py,sha256=DEFipaAHm0y7oCuN2QKzHsiQvUTUQVl-Ce36Ag7n7hs,5509
|
21
21
|
py_near/exceptions/provider.py,sha256=K-wexgjPJ8sw42JePwaP7R5dJEIn9DoFJRvVcURsx6s,7718
|
22
22
|
py_near/models.py,sha256=GZQD1TKGWlwqsJsKRXrVNBjCdAIpk7GQypU-QOtAPFs,11533
|
23
|
-
py_near/providers.py,sha256=
|
23
|
+
py_near/providers.py,sha256=1eg9MFIYIKA09bZyTdSZ2Umrh0kX1SUFEhY_tN8Cqz4,16722
|
24
24
|
py_near/transactions.py,sha256=QAXegv2JpKISk92NaChtIH6-QPHrcWbrwdKH_lH4TsU,3186
|
25
25
|
py_near/utils.py,sha256=FirRH93ydH1cwjn0-sNrZeIn3BRD6QHedrP2VkAdJ6g,126
|
26
|
-
py_near-1.1.
|
27
|
-
py_near-1.1.
|
28
|
-
py_near-1.1.
|
29
|
-
py_near-1.1.
|
26
|
+
py_near-1.1.47.dist-info/LICENSE,sha256=I_GOA9xJ35FiL-KnYXZJdATkbO2KcV2dK2enRGVxzKM,1023
|
27
|
+
py_near-1.1.47.dist-info/METADATA,sha256=Nd8CpvwjXiIyN9WK4JdCs46PgRUExpRNnSXTW6javYE,4693
|
28
|
+
py_near-1.1.47.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
29
|
+
py_near-1.1.47.dist-info/RECORD,,
|
File without changes
|
File without changes
|