-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathconnection.py
More file actions
104 lines (75 loc) · 2.7 KB
/
connection.py
File metadata and controls
104 lines (75 loc) · 2.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from typing import Literal, Optional, TypedDict, Union
import backoff
import requests
from client.exceptions import ArkHTTPException
def giveup_handler(_):
raise ArkHTTPException
# This uses the full_jitter algorithm
retry = backoff.on_exception(backoff.expo,
requests.exceptions.RequestException,
max_tries=3,
on_giveup=giveup_handler)
class ClientHosts(TypedDict):
api: str
transactions: Optional[str]
evm: Optional[str]
class Session(requests.Session):
def __init__(self, *args, **kwargs):
if 'hostname' not in kwargs:
raise ValueError('hostname is required')
self.hostname = kwargs.pop('hostname')
super().__init__(*args, **kwargs)
@retry
def send(self, request, **kwargs):
kwargs.update({
'timeout': (1, 5)
})
return super().send(request, **kwargs)
def prepare_request(self, request):
request.url = f'{self.hostname}/{request.url}'
return super().prepare_request(request)
class Connection(object):
session: Session
hosts: ClientHosts
def __init__(self, hosts: Union[str, ClientHosts]):
if isinstance(hosts, str):
hosts = {
'api': hosts,
'transactions': None,
'evm': None,
}
self.hosts = hosts
# Ensure we have a session
self.with_endpoint('api')
def with_endpoint(self, endpoint: Literal['api', 'transactions', 'evm']):
"""
:param string endpoint: endpoint name
"""
host = self.hosts[endpoint]
if host is None:
host = self.hosts['api']
self.session = Session(hostname=f'{host}')
self.session.headers.update({
'Content-Type': 'application/json',
})
def _handle_response(self, response: requests.Response):
if not response.content:
raise ArkHTTPException('No content in response', response=response)
body = response.json()
if not response.ok:
raise ArkHTTPException(
'{} {} {} - {}'.format(
response.request.method,
response.status_code,
response.request.url,
body.get('error')
),
response=response
)
return body
def get(self, path, params=None):
response = self.session.get(path, params=params)
return self._handle_response(response)
def post(self, path, data=None, params=None):
response = self.session.post(path, json=data, params=params)
return self._handle_response(response)