supervisely 6.73.213__py3-none-any.whl → 6.73.214__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.
Potentially problematic release.
This version of supervisely might be problematic. Click here for more details.
- supervisely/io/network_exceptions.py +89 -32
- supervisely/nn/inference/cache.py +8 -5
- {supervisely-6.73.213.dist-info → supervisely-6.73.214.dist-info}/METADATA +5 -5
- {supervisely-6.73.213.dist-info → supervisely-6.73.214.dist-info}/RECORD +8 -8
- {supervisely-6.73.213.dist-info → supervisely-6.73.214.dist-info}/LICENSE +0 -0
- {supervisely-6.73.213.dist-info → supervisely-6.73.214.dist-info}/WHEEL +0 -0
- {supervisely-6.73.213.dist-info → supervisely-6.73.214.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.213.dist-info → supervisely-6.73.214.dist-info}/top_level.txt +0 -0
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
# coding: utf-8
|
|
2
2
|
|
|
3
|
+
import time
|
|
3
4
|
import traceback
|
|
5
|
+
|
|
4
6
|
import requests
|
|
5
|
-
import time
|
|
6
7
|
|
|
7
|
-
CONNECTION_ERROR =
|
|
8
|
-
AGENT_CONNECTION_ERROR =
|
|
8
|
+
CONNECTION_ERROR = "Temporary connection error, please wait ..."
|
|
9
|
+
AGENT_CONNECTION_ERROR = "Temporary connection error (agent ping), please wait ..."
|
|
9
10
|
|
|
10
|
-
REQUEST_FAILED =
|
|
11
|
-
SPECIAL_RECONNECT_ERROR =
|
|
11
|
+
REQUEST_FAILED = "Request has failed. This may be due to connection problems or invalid requests. "
|
|
12
|
+
SPECIAL_RECONNECT_ERROR = (
|
|
13
|
+
"Agent should call AgentConnected or AgentPing before attempting any other request"
|
|
14
|
+
)
|
|
12
15
|
RETRY_STATUS_CODES = {
|
|
13
16
|
408, # Request Timeout
|
|
14
17
|
429, # Too Many Requests
|
|
@@ -19,51 +22,100 @@ RETRY_STATUS_CODES = {
|
|
|
19
22
|
504, # Gateway Timeout
|
|
20
23
|
509, # Bandwidth Limit Exceeded (Apache)
|
|
21
24
|
598, # Network read timeout error
|
|
22
|
-
599
|
|
25
|
+
599, # Network connect timeout error
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
|
|
26
|
-
def process_requests_exception(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
def process_requests_exception(
|
|
30
|
+
external_logger,
|
|
31
|
+
exc,
|
|
32
|
+
api_method_name,
|
|
33
|
+
url,
|
|
34
|
+
verbose=True,
|
|
35
|
+
swallow_exc=False,
|
|
36
|
+
sleep_sec=None,
|
|
37
|
+
response=None,
|
|
38
|
+
retry_info=None,
|
|
39
|
+
):
|
|
40
|
+
is_connection_error = isinstance(
|
|
41
|
+
exc,
|
|
42
|
+
(
|
|
43
|
+
requests.exceptions.ConnectionError,
|
|
44
|
+
requests.exceptions.Timeout,
|
|
45
|
+
requests.exceptions.TooManyRedirects,
|
|
46
|
+
requests.exceptions.ChunkedEncodingError,
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
is_server_retryable_error = (
|
|
51
|
+
isinstance(exc, requests.exceptions.HTTPError)
|
|
52
|
+
and hasattr(exc, "response")
|
|
53
|
+
and (exc.response.status_code in RETRY_STATUS_CODES)
|
|
54
|
+
)
|
|
36
55
|
|
|
37
56
|
is_need_ping_error = False
|
|
38
|
-
if
|
|
57
|
+
if (
|
|
58
|
+
isinstance(exc, requests.exceptions.HTTPError)
|
|
59
|
+
and hasattr(exc, "response")
|
|
60
|
+
and (exc.response.status_code == 400)
|
|
61
|
+
):
|
|
39
62
|
try:
|
|
40
63
|
server_explanation = exc.response.json()
|
|
41
|
-
is_need_ping_error =
|
|
64
|
+
is_need_ping_error = server_explanation.get("error", None) == SPECIAL_RECONNECT_ERROR
|
|
42
65
|
except (AttributeError, ValueError):
|
|
43
66
|
pass
|
|
44
67
|
|
|
45
68
|
if is_connection_error or is_server_retryable_error:
|
|
46
|
-
process_retryable_request(
|
|
47
|
-
|
|
48
|
-
|
|
69
|
+
process_retryable_request(
|
|
70
|
+
external_logger,
|
|
71
|
+
exc,
|
|
72
|
+
api_method_name,
|
|
73
|
+
url,
|
|
74
|
+
CONNECTION_ERROR,
|
|
75
|
+
verbose=verbose,
|
|
76
|
+
swallow_exc=swallow_exc,
|
|
77
|
+
sleep_sec=sleep_sec,
|
|
78
|
+
retry_info=retry_info,
|
|
79
|
+
)
|
|
49
80
|
elif is_need_ping_error:
|
|
50
|
-
process_retryable_request(
|
|
51
|
-
|
|
52
|
-
|
|
81
|
+
process_retryable_request(
|
|
82
|
+
external_logger,
|
|
83
|
+
exc,
|
|
84
|
+
api_method_name,
|
|
85
|
+
url,
|
|
86
|
+
AGENT_CONNECTION_ERROR,
|
|
87
|
+
verbose=verbose,
|
|
88
|
+
swallow_exc=swallow_exc,
|
|
89
|
+
sleep_sec=sleep_sec,
|
|
90
|
+
retry_info=retry_info,
|
|
91
|
+
)
|
|
92
|
+
elif response is None:
|
|
93
|
+
process_unhandled_request(external_logger, exc)
|
|
53
94
|
elif isinstance(exc, requests.exceptions.HTTPError):
|
|
54
95
|
process_invalid_request(external_logger, exc, response, verbose)
|
|
55
96
|
else:
|
|
56
97
|
process_unhandled_request(external_logger, exc)
|
|
57
98
|
|
|
58
99
|
|
|
59
|
-
def process_retryable_request(
|
|
60
|
-
|
|
100
|
+
def process_retryable_request(
|
|
101
|
+
external_logger,
|
|
102
|
+
exc,
|
|
103
|
+
api_method_name,
|
|
104
|
+
url,
|
|
105
|
+
user_message,
|
|
106
|
+
verbose=True,
|
|
107
|
+
swallow_exc=False,
|
|
108
|
+
sleep_sec=None,
|
|
109
|
+
retry_info=None,
|
|
110
|
+
):
|
|
61
111
|
if retry_info is not None:
|
|
62
112
|
retry_idx = retry_info["retry_idx"]
|
|
63
113
|
retry_limit = retry_info["retry_limit"]
|
|
64
114
|
user_message = "{}: Retrying ({}/{}).".format(user_message, retry_idx, retry_limit)
|
|
65
115
|
if verbose:
|
|
66
|
-
external_logger.warn(
|
|
116
|
+
external_logger.warn(
|
|
117
|
+
user_message, extra={"method": api_method_name, "url": url, "details": str(exc)}
|
|
118
|
+
)
|
|
67
119
|
|
|
68
120
|
if sleep_sec is not None:
|
|
69
121
|
time.sleep(sleep_sec)
|
|
@@ -74,13 +126,18 @@ def process_retryable_request(external_logger, exc, api_method_name, url, user_m
|
|
|
74
126
|
|
|
75
127
|
def process_invalid_request(external_logger, exc, response, verbose=True):
|
|
76
128
|
if verbose:
|
|
77
|
-
external_logger.warn(
|
|
78
|
-
|
|
79
|
-
|
|
129
|
+
external_logger.warn(
|
|
130
|
+
REQUEST_FAILED,
|
|
131
|
+
extra={
|
|
132
|
+
"reason": response.content.decode("utf-8"),
|
|
133
|
+
"status_code": response.status_code,
|
|
134
|
+
"url": response.url,
|
|
135
|
+
},
|
|
136
|
+
)
|
|
80
137
|
raise exc
|
|
81
138
|
|
|
82
139
|
|
|
83
140
|
def process_unhandled_request(external_logger, exc):
|
|
84
141
|
exc_str = str(exc)
|
|
85
|
-
external_logger.error(traceback.format_exc(), exc_info=True, extra={
|
|
86
|
-
raise RuntimeError(REQUEST_FAILED +
|
|
142
|
+
external_logger.error(traceback.format_exc(), exc_info=True, extra={"exc_str": exc_str})
|
|
143
|
+
raise RuntimeError(REQUEST_FAILED + "Last failure: {!r}".format(exc_str))
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
import shutil
|
|
4
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
4
5
|
from enum import Enum
|
|
5
6
|
from logging import Logger
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from threading import Lock, Thread
|
|
8
|
-
from concurrent.futures import ThreadPoolExecutor
|
|
9
9
|
from time import sleep
|
|
10
10
|
from typing import Any, Callable, Generator, List, Optional, Tuple, Union
|
|
11
11
|
|
|
12
12
|
import cv2
|
|
13
13
|
import numpy as np
|
|
14
14
|
from cacheout import Cache as CacheOut
|
|
15
|
-
from cachetools import Cache, LRUCache, TTLCache
|
|
15
|
+
from cachetools import Cache, LRUCache, TTLCache
|
|
16
16
|
from fastapi import BackgroundTasks, FastAPI, Form, Request, UploadFile
|
|
17
17
|
|
|
18
18
|
import supervisely as sly
|
|
@@ -83,7 +83,10 @@ class PersistentImageTTLCache(TTLCache):
|
|
|
83
83
|
# pylint: disable=no-member
|
|
84
84
|
link = self._TTLCache__getlink(key)
|
|
85
85
|
# pylint: disable=no-member
|
|
86
|
-
link
|
|
86
|
+
if hasattr(link, "expire"):
|
|
87
|
+
link.expire = self.timer() + self._TTLCache__ttl
|
|
88
|
+
else:
|
|
89
|
+
link.expires = self.timer() + self._TTLCache__ttl
|
|
87
90
|
except KeyError:
|
|
88
91
|
return
|
|
89
92
|
|
|
@@ -626,11 +629,11 @@ class InferenceImageCache:
|
|
|
626
629
|
pos_by_name[name] = pos
|
|
627
630
|
elif return_images is True:
|
|
628
631
|
items.append((pos, name))
|
|
629
|
-
|
|
632
|
+
|
|
630
633
|
def get_one_image(item):
|
|
631
634
|
pos, name = item
|
|
632
635
|
return pos, self._cache.get_image(name)
|
|
633
|
-
|
|
636
|
+
|
|
634
637
|
if len(items) > 0:
|
|
635
638
|
with ThreadPoolExecutor(min(64, len(items))) as executor:
|
|
636
639
|
for pos, image in executor.map(get_one_image, items):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: supervisely
|
|
3
|
-
Version: 6.73.
|
|
3
|
+
Version: 6.73.214
|
|
4
4
|
Summary: Supervisely Python SDK.
|
|
5
5
|
Home-page: https://github.com/supervisely/supervisely
|
|
6
6
|
Author: Supervisely
|
|
@@ -20,7 +20,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
20
20
|
Requires-Python: >=3.8
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: cachetools
|
|
23
|
+
Requires-Dist: cachetools<=5.5.0,>=4.2.3
|
|
24
24
|
Requires-Dist: numpy<2.0.0,>=1.19
|
|
25
25
|
Requires-Dist: opencv-python<5.0.0.0,>=4.5.5.62
|
|
26
26
|
Requires-Dist: PTable<1.0.0,>=0.9.2
|
|
@@ -38,12 +38,12 @@ Requires-Dist: SimpleITK<3.0.0.0,>=2.1.1.2
|
|
|
38
38
|
Requires-Dist: pydicom<3.0.0,>=2.3.0
|
|
39
39
|
Requires-Dist: stringcase<2.0.0,>=1.2.0
|
|
40
40
|
Requires-Dist: python-magic<1.0.0,>=0.4.25
|
|
41
|
-
Requires-Dist: trimesh
|
|
41
|
+
Requires-Dist: trimesh<=4.5.0,>=3.11.2
|
|
42
42
|
Requires-Dist: uvicorn[standard]<1.0.0,>=0.18.2
|
|
43
43
|
Requires-Dist: pydantic<=2.8.2,>=1.7.4
|
|
44
44
|
Requires-Dist: anyio<=4.2.0,>=3.7.1
|
|
45
45
|
Requires-Dist: fastapi<=0.109.0,>=0.79.0
|
|
46
|
-
Requires-Dist: websockets
|
|
46
|
+
Requires-Dist: websockets<=13.1,>=10.3
|
|
47
47
|
Requires-Dist: jinja2<4.0.0,>=3.0.3
|
|
48
48
|
Requires-Dist: psutil<6.0.0,>=5.9.0
|
|
49
49
|
Requires-Dist: jsonpatch<2.0,>=1.32
|
|
@@ -71,7 +71,7 @@ Requires-Dist: zstd
|
|
|
71
71
|
Provides-Extra: apps
|
|
72
72
|
Requires-Dist: uvicorn[standard]<1.0.0,>=0.18.2; extra == "apps"
|
|
73
73
|
Requires-Dist: fastapi<1.0.0,>=0.79.0; extra == "apps"
|
|
74
|
-
Requires-Dist: websockets
|
|
74
|
+
Requires-Dist: websockets<=13.1,>=10.3; extra == "apps"
|
|
75
75
|
Requires-Dist: jinja2<4.0.0,>=3.0.3; extra == "apps"
|
|
76
76
|
Requires-Dist: psutil<6.0.0,>=5.9.0; extra == "apps"
|
|
77
77
|
Requires-Dist: jsonpatch<2.0,>=1.32; extra == "apps"
|
|
@@ -689,7 +689,7 @@ supervisely/io/fs_cache.py,sha256=UvG27YGuLHOahY-cVchYXciTZNEM2aJfh0TAnP_xeeQ,57
|
|
|
689
689
|
supervisely/io/github_utils.py,sha256=jGmvQJ5bjtACuSFABzrxL0jJdh14SezovrHp8T-9y8g,1779
|
|
690
690
|
supervisely/io/json.py,sha256=7RGAk72FpPtlHYcyo7-uWZf5IAvQJg_nM09RpXBpaNo,7588
|
|
691
691
|
supervisely/io/multipart_stream_decoder.py,sha256=rCheeSCAGdw2tNyaWEYa4dvoIDuldXOxH86RVB82c78,14417
|
|
692
|
-
supervisely/io/network_exceptions.py,sha256=
|
|
692
|
+
supervisely/io/network_exceptions.py,sha256=ka5ce-L4brzqnzARFpma5zmVZaq1ojgVZcfxzWQPTJ8,4126
|
|
693
693
|
supervisely/labeling_jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
694
694
|
supervisely/labeling_jobs/constants.py,sha256=GF_pwF9fC9_DGbpD3cAk3llifskAxpDmyuXwxM1f3Hw,104
|
|
695
695
|
supervisely/labeling_jobs/utils.py,sha256=XOGF2cbnTGbXFdT5jGL1LIPQfiCEJgRkmKNIjTlFois,22656
|
|
@@ -776,7 +776,7 @@ supervisely/nn/benchmark/visualization/vis_metrics/recall_vs_precision.py,sha256
|
|
|
776
776
|
supervisely/nn/benchmark/visualization/vis_metrics/reliability_diagram.py,sha256=Vxta2s0RTTcV0GCcMiF8CykCtZYryLTwGjW9vVUrK3I,3107
|
|
777
777
|
supervisely/nn/benchmark/visualization/vis_metrics/what_is.py,sha256=MDnYR-o7Mj-YE1Jwu9EcLUEPcu6rLknRx7LvV4nnUBo,842
|
|
778
778
|
supervisely/nn/inference/__init__.py,sha256=mtEci4Puu-fRXDnGn8RP47o97rv3VTE0hjbYO34Zwqg,1622
|
|
779
|
-
supervisely/nn/inference/cache.py,sha256=
|
|
779
|
+
supervisely/nn/inference/cache.py,sha256=WylgHgPQRIoA_RDks8FyKgHqeZZ_YFoyddxkVvOX2YQ,25713
|
|
780
780
|
supervisely/nn/inference/inference.py,sha256=pwTh6_EQ-sJNXTBD08eUMdOH8VoNF2uJUTr_P1-BuN0,114983
|
|
781
781
|
supervisely/nn/inference/session.py,sha256=jmkkxbe2kH-lEgUU6Afh62jP68dxfhF5v6OGDfLU62E,35757
|
|
782
782
|
supervisely/nn/inference/video_inference.py,sha256=8Bshjr6rDyLay5Za8IB8Dr6FURMO2R_v7aELasO8pR4,5746
|
|
@@ -957,9 +957,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
957
957
|
supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
|
|
958
958
|
supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
|
|
959
959
|
supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
|
|
960
|
-
supervisely-6.73.
|
|
961
|
-
supervisely-6.73.
|
|
962
|
-
supervisely-6.73.
|
|
963
|
-
supervisely-6.73.
|
|
964
|
-
supervisely-6.73.
|
|
965
|
-
supervisely-6.73.
|
|
960
|
+
supervisely-6.73.214.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
961
|
+
supervisely-6.73.214.dist-info/METADATA,sha256=eiPzbAzdjKq2Ni6e1iFqKqPdKouyzo9fONMZqs_Rx2A,33090
|
|
962
|
+
supervisely-6.73.214.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
|
|
963
|
+
supervisely-6.73.214.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
|
|
964
|
+
supervisely-6.73.214.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
|
|
965
|
+
supervisely-6.73.214.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|