Skip to content

Commit 8e4ecb4

Browse files
Narek MkhitaryanNarek Mkhitaryan
authored andcommitted
change assets_provider version
1 parent 873cd88 commit 8e4ecb4

File tree

3 files changed

+47
-36
lines changed

3 files changed

+47
-36
lines changed

src/superannotate/lib/infrastructure/services/annotation.py

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
from lib.core.serviceproviders import BaseAnnotationService
2020
from lib.infrastructure.stream_data_handler import StreamedAnnotations
2121
from pydantic import parse_obj_as
22+
from superannotate.lib.infrastructure.services.http_client import AIOHttpSession
2223

2324
logger = logging.getLogger("sa")
2425

2526

2627
class AnnotationService(BaseAnnotationService):
27-
ASSETS_PROVIDER_VERSION = "v2.01"
28+
ASSETS_PROVIDER_VERSION = "v3.01"
2829
DEFAULT_CHUNK_SIZE = 5000
2930

3031
URL_GET_ANNOTATIONS = "items/annotations/download"
@@ -71,13 +72,12 @@ async def _sync_large_annotation(self, team_id, project_id, item_id):
7172
self.assets_provider_url,
7273
self.URL_START_FILE_SYNC.format(item_id=item_id),
7374
)
74-
async with aiohttp.ClientSession(
75+
async with AIOHttpSession(
7576
connector=aiohttp.TCPConnector(ssl=False),
7677
headers=self.client.default_headers,
77-
raise_for_status=True,
7878
) as session:
79-
await session.post(sync_url, params=sync_params)
80-
79+
_response = await session.request("post", sync_url, params=sync_params)
80+
_response.raise_for_status()
8181
sync_params.pop("current_source")
8282
sync_params.pop("desired_source")
8383

@@ -115,12 +115,12 @@ async def get_big_annotation(
115115
team_id=project.team_id, project_id=project.id, item_id=item.id
116116
)
117117

118-
async with aiohttp.ClientSession(
118+
async with AIOHttpSession(
119119
connector=aiohttp.TCPConnector(ssl=False),
120120
headers=self.client.default_headers,
121-
raise_for_status=True,
122121
) as session:
123-
start_response = await session.post(url, params=query_params)
122+
start_response = await session.request("post", url, params=query_params)
123+
start_response.raise_for_status()
124124
large_annotation = await start_response.json()
125125

126126
reporter.update_progress()
@@ -198,12 +198,12 @@ async def download_big_annotation(
198198
team_id=project.team_id, project_id=project.id, item_id=item_id
199199
)
200200

201-
async with aiohttp.ClientSession(
201+
async with AIOHttpSession(
202202
connector=aiohttp.TCPConnector(ssl=False),
203203
headers=self.client.default_headers,
204-
raise_for_status=True,
205204
) as session:
206-
start_response = await session.post(url, params=query_params)
205+
start_response = await session.request("post", url, params=query_params)
206+
start_response.raise_for_status()
207207
res = await start_response.json()
208208
Path(download_path).mkdir(exist_ok=True, parents=True)
209209

@@ -257,10 +257,9 @@ async def upload_small_annotations(
257257

258258
headers = copy.copy(self.client.default_headers)
259259
del headers["Content-Type"]
260-
async with aiohttp.ClientSession(
260+
async with AIOHttpSession(
261261
headers=headers,
262262
connector=aiohttp.TCPConnector(ssl=False),
263-
raise_for_status=True,
264263
) as session:
265264
data = aiohttp.FormData(quote_fields=False)
266265
for key, file in items_name_file_map.items():
@@ -272,15 +271,12 @@ async def upload_small_annotations(
272271
content_type="application/json",
273272
)
274273

275-
_response = await session.post(
276-
url,
277-
params={
278-
"team_id": project.team_id,
279-
"project_id": project.id,
280-
"folder_id": folder.id,
281-
},
282-
data=data,
283-
)
274+
params = {
275+
"team_id": project.team_id,
276+
"project_id": project.id,
277+
"folder_id": folder.id,
278+
}
279+
_response = await session.request("post", url, params=params, data=data)
284280
if not _response.ok:
285281
logger.debug(f"Status code {str(_response.status)}")
286282
logger.debug(await _response.text())
@@ -301,23 +297,20 @@ async def upload_big_annotation(
301297
data: io.StringIO,
302298
chunk_size: int,
303299
) -> bool:
304-
async with aiohttp.ClientSession(
300+
async with AIOHttpSession(
305301
connector=aiohttp.TCPConnector(ssl=False),
306302
headers=self.client.default_headers,
307-
raise_for_status=True,
308303
) as session:
309304
params = {
310305
"team_id": project.team_id,
311306
"project_id": project.id,
312307
"folder_id": folder.id,
313308
}
314-
start_response = await session.post(
315-
urljoin(
316-
self.assets_provider_url,
317-
self.URL_START_FILE_UPLOAD_PROCESS.format(item_id=item_id),
318-
),
319-
params=params,
309+
url = urljoin(
310+
self.assets_provider_url,
311+
self.URL_START_FILE_UPLOAD_PROCESS.format(item_id=item_id),
320312
)
313+
start_response = await session.request("post", url, params=params)
321314
if not start_response.ok:
322315
raise AppException(str(await start_response.text()))
323316
process_info = await start_response.json()

src/superannotate/lib/infrastructure/services/http_client.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import json
23
import logging
34
import platform
@@ -10,6 +11,7 @@
1011
from typing import Dict
1112
from typing import List
1213

14+
import aiohttp
1315
import pydantic
1416
import requests
1517
from lib.core.exceptions import AppException
@@ -213,3 +215,20 @@ def serialize_response(
213215
data["res_error"] = response.content
214216
data["reason"] = response.reason
215217
return content_type(**data)
218+
219+
220+
class AIOHttpSession(aiohttp.ClientSession):
221+
RETRY_STATUS_CODES = [401, 403, 502, 503, 504]
222+
RETRY_LIMIT = 3
223+
BACKOFF_FACTOR = 0.3
224+
225+
async def request(self, *args, **kwargs) -> aiohttp.ClientResponse:
226+
attempts = self.RETRY_LIMIT
227+
delay = 0
228+
for _ in range(attempts):
229+
delay += self.BACKOFF_FACTOR
230+
attempts -= 1
231+
response = await super()._request(*args, **kwargs)
232+
if response.status not in self.RETRY_STATUS_CODES or not attempts:
233+
return response
234+
await asyncio.sleep(delay)

src/superannotate/lib/infrastructure/stream_data_handler.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import aiohttp
88
from lib.core.reporter import Reporter
9+
from superannotate.lib.infrastructure.services.http_client import AIOHttpSession
910

1011
_seconds = 2**10
1112
TIMEOUT = aiohttp.ClientTimeout(
@@ -39,17 +40,15 @@ def get_json(self, data: bytes):
3940
async def fetch(
4041
self,
4142
method: str,
42-
session: aiohttp.ClientSession,
43+
session: AIOHttpSession,
4344
url: str,
4445
data: dict = None,
4546
params: dict = None,
4647
):
4748
kwargs = {"params": params, "json": {"folder_id": params.pop("folder_id")}}
4849
if data:
4950
kwargs["json"].update(data)
50-
response = await session._request( # noqa
51-
method, url, **kwargs, timeout=TIMEOUT
52-
)
51+
response = await session.request(method, url, **kwargs, timeout=TIMEOUT) # noqa
5352
buffer = b""
5453
async for line in response.content.iter_any():
5554
slices = (buffer + line).split(self.DELIMITER)
@@ -71,7 +70,7 @@ async def list_annotations(
7170
params = copy.copy(params)
7271
params["limit"] = len(data)
7372
annotations = []
74-
async with aiohttp.ClientSession(
73+
async with AIOHttpSession(
7574
headers=self._headers,
7675
timeout=TIMEOUT,
7776
connector=aiohttp.TCPConnector(ssl=verify_ssl, keepalive_timeout=2**32),
@@ -100,7 +99,7 @@ async def download_annotations(
10099
):
101100
params = copy.copy(params)
102101
params["limit"] = len(data)
103-
async with aiohttp.ClientSession(
102+
async with AIOHttpSession(
104103
headers=self._headers,
105104
timeout=TIMEOUT,
106105
connector=aiohttp.TCPConnector(ssl=False, keepalive_timeout=2**32),

0 commit comments

Comments
 (0)