arkindex-client 1.0.14__tar.gz → 1.0.16__tar.gz
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.
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/PKG-INFO +2 -2
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/README.rst +1 -1
- arkindex-client-1.0.16/VERSION +1 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex/client.py +44 -3
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex/pagination.py +4 -3
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex/transports.py +5 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex_client.egg-info/PKG-INFO +2 -2
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex_client.egg-info/requires.txt +1 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/requirements.txt +1 -0
- arkindex-client-1.0.14/VERSION +0 -1
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/MANIFEST.in +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex/__init__.py +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex/auth.py +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex/exceptions.py +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex/mock.py +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex_client.egg-info/SOURCES.txt +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex_client.egg-info/dependency_links.txt +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex_client.egg-info/top_level.txt +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/setup.cfg +0 -0
- {arkindex-client-1.0.14 → arkindex-client-1.0.16}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: arkindex-client
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.16
|
|
4
4
|
Summary: API client for the Arkindex project
|
|
5
5
|
Home-page: https://gitlab.teklia.com/arkindex/api-client
|
|
6
6
|
Author: Teklia <contact@teklia.com>
|
|
@@ -164,7 +164,7 @@ exception's attributes:
|
|
|
164
164
|
except ErrorResponse as e:
|
|
165
165
|
print(e.title) # "400 Bad Request"
|
|
166
166
|
print(e.status_code) # 400
|
|
167
|
-
print(e.
|
|
167
|
+
print(e.content) # Any kind of response body the server might give
|
|
168
168
|
|
|
169
169
|
Note that by default, using ``repr()`` or ``str()`` on APIStar exceptions will
|
|
170
170
|
not give any useful messages; a fix in APIStar is waiting to be merged. In
|
|
@@ -142,7 +142,7 @@ exception's attributes:
|
|
|
142
142
|
except ErrorResponse as e:
|
|
143
143
|
print(e.title) # "400 Bad Request"
|
|
144
144
|
print(e.status_code) # 400
|
|
145
|
-
print(e.
|
|
145
|
+
print(e.content) # Any kind of response body the server might give
|
|
146
146
|
|
|
147
147
|
Note that by default, using ``repr()`` or ``str()`` on APIStar exceptions will
|
|
148
148
|
not give any useful messages; a fix in APIStar is waiting to be merged. In
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.16
|
|
@@ -11,6 +11,14 @@ from urllib.parse import urljoin, urlsplit, urlunsplit
|
|
|
11
11
|
import apistar
|
|
12
12
|
import requests
|
|
13
13
|
import yaml
|
|
14
|
+
from apistar.exceptions import ErrorResponse
|
|
15
|
+
from tenacity import (
|
|
16
|
+
before_sleep_log,
|
|
17
|
+
retry,
|
|
18
|
+
retry_if_exception,
|
|
19
|
+
stop_after_attempt,
|
|
20
|
+
wait_exponential,
|
|
21
|
+
)
|
|
14
22
|
|
|
15
23
|
from arkindex.auth import TokenSessionAuthentication
|
|
16
24
|
from arkindex.exceptions import SchemaError
|
|
@@ -27,6 +35,17 @@ SCHEMA_ENDPOINT = "/api/v1/openapi/?format=json"
|
|
|
27
35
|
logger = logging.getLogger(__name__)
|
|
28
36
|
|
|
29
37
|
|
|
38
|
+
def _is_500_error(exc: Exception) -> bool:
|
|
39
|
+
"""
|
|
40
|
+
Check if an Arkindex API error is a 50x
|
|
41
|
+
This is used to retry most API calls implemented here
|
|
42
|
+
"""
|
|
43
|
+
if not isinstance(exc, ErrorResponse):
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
return 500 <= exc.status_code < 600
|
|
47
|
+
|
|
48
|
+
|
|
30
49
|
def options_from_env():
|
|
31
50
|
"""
|
|
32
51
|
Get API client keyword arguments from environment variables.
|
|
@@ -84,6 +103,7 @@ class ArkindexClient(apistar.Client):
|
|
|
84
103
|
schema_url=None,
|
|
85
104
|
csrf_cookie=None,
|
|
86
105
|
sleep=0,
|
|
106
|
+
verify=True,
|
|
87
107
|
**kwargs,
|
|
88
108
|
):
|
|
89
109
|
r"""
|
|
@@ -103,6 +123,7 @@ class ArkindexClient(apistar.Client):
|
|
|
103
123
|
if not schema_url:
|
|
104
124
|
schema_url = urljoin(base_url, SCHEMA_ENDPOINT)
|
|
105
125
|
|
|
126
|
+
self.verify = verify
|
|
106
127
|
try:
|
|
107
128
|
split = urlsplit(schema_url)
|
|
108
129
|
if split.scheme == "file" or not (split.scheme or split.netloc):
|
|
@@ -110,7 +131,7 @@ class ArkindexClient(apistar.Client):
|
|
|
110
131
|
with open(schema_url) as f:
|
|
111
132
|
schema = yaml.safe_load(f)
|
|
112
133
|
else:
|
|
113
|
-
resp = requests.get(schema_url)
|
|
134
|
+
resp = requests.get(schema_url, verify=self.verify)
|
|
114
135
|
resp.raise_for_status()
|
|
115
136
|
schema = yaml.safe_load(resp.content)
|
|
116
137
|
except Exception as e:
|
|
@@ -173,7 +194,7 @@ class ArkindexClient(apistar.Client):
|
|
|
173
194
|
)
|
|
174
195
|
|
|
175
196
|
def init_transport(self, *args, **kwargs):
|
|
176
|
-
return ArkindexHTTPTransport(*args, **kwargs)
|
|
197
|
+
return ArkindexHTTPTransport(self.verify, *args, **kwargs)
|
|
177
198
|
|
|
178
199
|
def configure(
|
|
179
200
|
self,
|
|
@@ -243,7 +264,7 @@ class ArkindexClient(apistar.Client):
|
|
|
243
264
|
self.transport.session.auth.token = resp["auth_token"]
|
|
244
265
|
return resp
|
|
245
266
|
|
|
246
|
-
def
|
|
267
|
+
def single_request(self, operation_id, *args, **kwargs):
|
|
247
268
|
"""
|
|
248
269
|
Perform an API request.
|
|
249
270
|
:param args: Arguments passed to the APIStar client.
|
|
@@ -272,3 +293,23 @@ class ArkindexClient(apistar.Client):
|
|
|
272
293
|
)
|
|
273
294
|
sleep(self.sleep_duration)
|
|
274
295
|
return super().request(operation_id, *args, **kwargs)
|
|
296
|
+
|
|
297
|
+
@retry(
|
|
298
|
+
retry=retry_if_exception(_is_500_error),
|
|
299
|
+
wait=wait_exponential(multiplier=2, min=3),
|
|
300
|
+
reraise=True,
|
|
301
|
+
stop=stop_after_attempt(5),
|
|
302
|
+
before_sleep=before_sleep_log(logger, logging.INFO),
|
|
303
|
+
)
|
|
304
|
+
def request(self, operation_id, *args, **kwargs):
|
|
305
|
+
"""
|
|
306
|
+
Proxy all Arkindex API requests with a retry mechanism in case of 50X errors.
|
|
307
|
+
The same API call will be retried 5 times, with an exponential sleep time
|
|
308
|
+
going through 3, 4, 8 and 16 seconds of wait between call.
|
|
309
|
+
If the 5th call still gives a 50x, the exception is re-raised and the caller should catch it.
|
|
310
|
+
Log messages are displayed before sleeping (when at least one exception occurred).
|
|
311
|
+
|
|
312
|
+
:param args: Arguments passed to the APIStar client.
|
|
313
|
+
:param kwargs: Keyword arguments passed to the APIStar client.
|
|
314
|
+
"""
|
|
315
|
+
return self.single_request(operation_id, *args, **kwargs)
|
|
@@ -117,13 +117,14 @@ class ResponsePaginator(Sized, Iterator):
|
|
|
117
117
|
if "with_count" in operation_fields:
|
|
118
118
|
extra_kwargs["with_count"] = "true"
|
|
119
119
|
else:
|
|
120
|
+
remaining_count = self.pages_count - self.pages_loaded
|
|
120
121
|
logger.info(
|
|
121
122
|
f"Loading {self.mode.value} {index} on try {self.retries - retry + 1}/{self.retries}"
|
|
122
|
-
f" - remains {
|
|
123
|
+
f" - remains {remaining_count} page{'s' if remaining_count > 1 else ''} to load."
|
|
123
124
|
)
|
|
124
125
|
|
|
125
126
|
# Fetch the next page
|
|
126
|
-
self.data = self.client.
|
|
127
|
+
self.data = self.client.single_request(
|
|
127
128
|
self.operation_id,
|
|
128
129
|
*self.request_args,
|
|
129
130
|
**self.request_kwargs,
|
|
@@ -147,7 +148,7 @@ class ResponsePaginator(Sized, Iterator):
|
|
|
147
148
|
return False
|
|
148
149
|
self.pages_count = math.ceil(self.count / len(self.results))
|
|
149
150
|
logger.info(
|
|
150
|
-
f"Pagination will load a total of {self.pages_count}
|
|
151
|
+
f"Pagination will load a total of {self.pages_count} page{'s' if self.pages_count > 1 else ''}."
|
|
151
152
|
)
|
|
152
153
|
if self.mode == PaginationMode.PageNumber:
|
|
153
154
|
# Initialize all pages once
|
|
@@ -3,7 +3,12 @@ from apistar.client.transports import HTTPTransport
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class ArkindexHTTPTransport(HTTPTransport):
|
|
6
|
+
def __init__(self, verify=True, *args, **kwargs):
|
|
7
|
+
super().__init__(*args, **kwargs)
|
|
8
|
+
self.verify = verify
|
|
9
|
+
|
|
6
10
|
def get_request_options(self, *args, **kwargs):
|
|
7
11
|
options = super().get_request_options(*args, **kwargs)
|
|
8
12
|
options["timeout"] = (30, 60)
|
|
13
|
+
options["verify"] = self.verify
|
|
9
14
|
return options
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: arkindex-client
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.16
|
|
4
4
|
Summary: API client for the Arkindex project
|
|
5
5
|
Home-page: https://gitlab.teklia.com/arkindex/api-client
|
|
6
6
|
Author: Teklia <contact@teklia.com>
|
|
@@ -164,7 +164,7 @@ exception's attributes:
|
|
|
164
164
|
except ErrorResponse as e:
|
|
165
165
|
print(e.title) # "400 Bad Request"
|
|
166
166
|
print(e.status_code) # 400
|
|
167
|
-
print(e.
|
|
167
|
+
print(e.content) # Any kind of response body the server might give
|
|
168
168
|
|
|
169
169
|
Note that by default, using ``repr()`` or ``str()`` on APIStar exceptions will
|
|
170
170
|
not give any useful messages; a fix in APIStar is waiting to be merged. In
|
arkindex-client-1.0.14/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1.0.14
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{arkindex-client-1.0.14 → arkindex-client-1.0.16}/arkindex_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|