supervisely 6.73.213__py3-none-any.whl → 6.73.215__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/app/widgets/report_thumbnail/report_thumbnail.py +17 -5
- supervisely/app/widgets/team_files_selector/team_files_selector.py +3 -0
- supervisely/io/network_exceptions.py +89 -32
- supervisely/nn/benchmark/comparison/__init__.py +0 -0
- supervisely/nn/benchmark/comparison/detection_visualization/__init__.py +0 -0
- supervisely/nn/benchmark/comparison/detection_visualization/text_templates.py +437 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/__init__.py +27 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/avg_precision_by_class.py +125 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/calibration_score.py +224 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/explore_predicttions.py +112 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/localization_accuracy.py +161 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/outcome_counts.py +336 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/overview.py +249 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/pr_curve.py +142 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/precision_recal_f1.py +300 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/speedtest.py +308 -0
- supervisely/nn/benchmark/comparison/detection_visualization/vis_metrics/vis_metric.py +19 -0
- supervisely/nn/benchmark/comparison/detection_visualization/visualizer.py +298 -0
- supervisely/nn/benchmark/comparison/model_comparison.py +84 -0
- supervisely/nn/benchmark/evaluation/coco/metric_provider.py +9 -7
- supervisely/nn/benchmark/visualization/evaluation_result.py +266 -0
- supervisely/nn/benchmark/visualization/renderer.py +100 -0
- supervisely/nn/benchmark/visualization/report_template.html +46 -0
- supervisely/nn/benchmark/visualization/visualizer.py +1 -1
- supervisely/nn/benchmark/visualization/widgets/__init__.py +17 -0
- supervisely/nn/benchmark/visualization/widgets/chart/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/chart/chart.py +72 -0
- supervisely/nn/benchmark/visualization/widgets/chart/template.html +16 -0
- supervisely/nn/benchmark/visualization/widgets/collapse/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/collapse/collapse.py +33 -0
- supervisely/nn/benchmark/visualization/widgets/container/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/container/container.py +54 -0
- supervisely/nn/benchmark/visualization/widgets/gallery/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/gallery/gallery.py +125 -0
- supervisely/nn/benchmark/visualization/widgets/gallery/template.html +49 -0
- supervisely/nn/benchmark/visualization/widgets/markdown/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/markdown/markdown.py +53 -0
- supervisely/nn/benchmark/visualization/widgets/notification/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/notification/notification.py +38 -0
- supervisely/nn/benchmark/visualization/widgets/sidebar/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/sidebar/sidebar.py +67 -0
- supervisely/nn/benchmark/visualization/widgets/table/__init__.py +0 -0
- supervisely/nn/benchmark/visualization/widgets/table/table.py +116 -0
- supervisely/nn/benchmark/visualization/widgets/widget.py +22 -0
- supervisely/nn/inference/cache.py +8 -5
- {supervisely-6.73.213.dist-info → supervisely-6.73.215.dist-info}/METADATA +5 -5
- {supervisely-6.73.213.dist-info → supervisely-6.73.215.dist-info}/RECORD +51 -12
- {supervisely-6.73.213.dist-info → supervisely-6.73.215.dist-info}/LICENSE +0 -0
- {supervisely-6.73.213.dist-info → supervisely-6.73.215.dist-info}/WHEEL +0 -0
- {supervisely-6.73.213.dist-info → supervisely-6.73.215.dist-info}/entry_points.txt +0 -0
- {supervisely-6.73.213.dist-info → supervisely-6.73.215.dist-info}/top_level.txt +0 -0
|
@@ -1,32 +1,44 @@
|
|
|
1
|
-
import
|
|
1
|
+
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from supervisely._utils import abs_url, is_debug_with_sly_net, is_development
|
|
4
4
|
from supervisely.api.file_api import FileInfo
|
|
5
5
|
from supervisely.app import DataJson
|
|
6
6
|
from supervisely.app.widgets import Widget
|
|
7
|
+
from supervisely.imaging.color import _validate_hex_color
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class ReportThumbnail(Widget):
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
info: Optional[FileInfo] = None,
|
|
15
|
+
widget_id: Optional[str] = None,
|
|
16
|
+
title: Optional[str] = None,
|
|
17
|
+
color: Optional[str] = "#dcb0ff",
|
|
18
|
+
bg_color: Optional[str] = "#faebff",
|
|
19
|
+
):
|
|
11
20
|
self._id: int = None
|
|
12
21
|
self._info: FileInfo = None
|
|
13
22
|
self._description: str = None
|
|
14
23
|
self._url: str = None
|
|
15
24
|
self._set_info(info)
|
|
25
|
+
self._title = title
|
|
26
|
+
self._color = color if _validate_hex_color(color) else "#dcb0ff"
|
|
27
|
+
self._bg_color = bg_color if _validate_hex_color(bg_color) else "#faebff"
|
|
16
28
|
|
|
17
29
|
super().__init__(widget_id=widget_id, file_path=__file__)
|
|
18
30
|
|
|
19
31
|
def get_json_data(self):
|
|
20
32
|
return {
|
|
21
33
|
"id": self._id,
|
|
22
|
-
"name": "Evaluation Report",
|
|
34
|
+
"name": self._title or "Evaluation Report",
|
|
23
35
|
"description": self._description,
|
|
24
36
|
"url": self._url,
|
|
25
37
|
"description": self._description,
|
|
26
38
|
"icon": {
|
|
27
39
|
"className": "zmdi zmdi-assignment",
|
|
28
|
-
"color":
|
|
29
|
-
"bgColor":
|
|
40
|
+
"color": self._color,
|
|
41
|
+
"bgColor": self._bg_color,
|
|
30
42
|
},
|
|
31
43
|
}
|
|
32
44
|
|
|
@@ -23,6 +23,7 @@ class TeamFilesSelector(Widget):
|
|
|
23
23
|
Literal["id", "createdAt", "updatedAt", "type", "size", "mimeType"]
|
|
24
24
|
] = [],
|
|
25
25
|
widget_id: str = None,
|
|
26
|
+
initial_folder: str = None,
|
|
26
27
|
):
|
|
27
28
|
self._api = Api()
|
|
28
29
|
self._team_id = team_id
|
|
@@ -42,6 +43,7 @@ class TeamFilesSelector(Widget):
|
|
|
42
43
|
|
|
43
44
|
self._additional_fields = additional_fields
|
|
44
45
|
self._selected = []
|
|
46
|
+
self._initial_folder = initial_folder or "/"
|
|
45
47
|
|
|
46
48
|
super().__init__(widget_id=widget_id, file_path=__file__)
|
|
47
49
|
|
|
@@ -55,6 +57,7 @@ class TeamFilesSelector(Widget):
|
|
|
55
57
|
"hideHeader": self._hide_header,
|
|
56
58
|
"hideEmptyTable": self._hide_empty_table,
|
|
57
59
|
"additionalFields": self._additional_fields,
|
|
60
|
+
"initialFolder": {"path": self._initial_folder},
|
|
58
61
|
},
|
|
59
62
|
}
|
|
60
63
|
|
|
@@ -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))
|
|
File without changes
|
|
File without changes
|