supervisely 6.73.314__py3-none-any.whl → 6.73.316__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.
@@ -625,7 +625,8 @@ class ApiField:
625
625
  """"""
626
626
  NON_FINAL_VALUE = "nonFinalValue"
627
627
  """"""
628
-
628
+ HOTKEY = "hotkey"
629
+ """"""
629
630
 
630
631
  def _get_single_item(items):
631
632
  """_get_single_item"""
@@ -201,3 +201,78 @@ class ObjectClassApi(ModuleApi):
201
201
  # response = self._api.post('videos.tags.bulk.add', {ApiField.VIDEO_ID: video_id, ApiField.TAGS: tags_json})
202
202
  # ids = [obj[ApiField.ID] for obj in response.json()]
203
203
  # return ids
204
+
205
+ def update(
206
+ self,
207
+ id: int,
208
+ name: Optional[str] = None,
209
+ description: Optional[str] = None,
210
+ hotkey: Optional[str] = None,
211
+ shape: Optional[str] = None,
212
+ color: Optional[str] = None,
213
+ settings: Optional[dict] = None,
214
+ ) -> NamedTuple:
215
+ """
216
+ Update the class with the given ID on the server.
217
+ Returned object contains updated information about the class except settings.
218
+
219
+ :param id: ID of the class to update.
220
+ :type id: int
221
+ :param name: New name of the class.
222
+ :type name: str, optional
223
+ :param description: New description of the class.
224
+ :type description: str, optional
225
+ :param hotkey: New hotkey of the class (e.g., "K").
226
+ :type hotkey: str, optional
227
+ :param shape: New shape of the class.
228
+ :type shape: str, optional
229
+ :param color: New color of the class in HEX format (e.g., #FFFFFF).
230
+ :type color: str, optional
231
+ :param settings: New settings of the class.
232
+ Do not pass "availableShapes" for shape other than "any".
233
+ Do not pass "availableShapes" that does not contain the current shape.
234
+ :type settings: dict, optional
235
+
236
+ :return: Updated class information
237
+ :rtype: :class:`ObjectClassInfo<ObjectClassInfo>`
238
+
239
+ :Usage example:
240
+
241
+ .. code-block:: python
242
+
243
+ import supervisely as sly
244
+
245
+ api = sly.Api.from_env()
246
+
247
+ obj_class_info = api.object_class.update(
248
+ id=22309,
249
+ shape='any',
250
+ settings={
251
+ "availableShapes": [
252
+ "bitmap",
253
+ "polygon",
254
+ ],
255
+ },
256
+ )
257
+ """
258
+ if all(arg is None for arg in [name, description, hotkey, shape, color, settings]):
259
+ raise ValueError(
260
+ f"To update the class with ID: {id}, you must specify at least one parameter to update; all are currently None"
261
+ )
262
+
263
+ data = {ApiField.ID: id}
264
+ if name is not None:
265
+ data[ApiField.NAME] = name
266
+ if description is not None:
267
+ data[ApiField.DESCRIPTION] = description
268
+ if hotkey is not None:
269
+ data[ApiField.HOTKEY] = hotkey
270
+ if shape is not None:
271
+ data[ApiField.SHAPE] = shape
272
+ if color is not None:
273
+ data[ApiField.COLOR] = color
274
+ if settings is not None:
275
+ data[ApiField.SETTINGS] = settings
276
+
277
+ response = self._api.post("advanced.object_classes.editInfo", data)
278
+ return self._convert_json_info(response.json(), skip_missing=True)
@@ -30,6 +30,7 @@ class VersionInfo(NamedTuple):
30
30
  updated_at: str
31
31
  project_updated_at: str
32
32
  team_id: int
33
+ name: str
33
34
 
34
35
 
35
36
  class DataVersion(ModuleApiBase):
@@ -67,6 +68,7 @@ class DataVersion(ModuleApiBase):
67
68
  ApiField.UPDATED_AT,
68
69
  ApiField.PROJECT_UPDATED_AT,
69
70
  ApiField.TEAM_ID,
71
+ ApiField.NAME,
70
72
  ]
71
73
 
72
74
  @staticmethod
@@ -73,24 +73,64 @@ from supervisely.task.progress import Progress, tqdm_sly
73
73
 
74
74
  class CustomUnpickler(pickle.Unpickler):
75
75
  """
76
- Custom Unpickler to load pickled objects with fields that are not present in the class definition.
77
- Used to load old pickled objects that have been pickled with a class that has been updated.
78
- Supports loading namedtuple objects with missing fields.
76
+ Custom Unpickler for loading pickled objects of the same class with differing definitions.
77
+ Handles cases where a class object is reconstructed using a newer definition with additional fields
78
+ or an outdated definition missing some fields.
79
+ Supports loading namedtuple objects with missing or extra fields.
79
80
  """
80
81
 
82
+ def __init__(self, file, **kwargs):
83
+ super().__init__(file, **kwargs)
84
+ self.warned_classes = set() # To prevent multiple warnings for the same class
85
+ self.sdk_update_notified = False
86
+
81
87
  def find_class(self, module, name):
88
+ prefix = "Pickled"
82
89
  cls = super().find_class(module, name)
83
- if hasattr(cls, "_fields"):
90
+ if hasattr(cls, "_fields") and "Info" in cls.__name__:
84
91
  orig_new = cls.__new__
85
92
 
86
93
  def new(cls, *args, **kwargs):
94
+ orig_class_name = cls.__name__[len(prefix) :]
95
+ # Case when new definition of class has more fields than the old one
87
96
  if len(args) < len(cls._fields):
97
+ default_values = cls._field_defaults
88
98
  # Set missed attrs to None
89
- args = list(args) + [None] * (len(cls._fields) - len(args))
99
+ num_missing = len(cls._fields) - len(args)
100
+ args = list(args) + [None] * num_missing
101
+ # Replace only the added None values with default values where applicable
102
+ args[-num_missing:] = [
103
+ (
104
+ default_values.get(field, arg)
105
+ if arg is None and field in default_values
106
+ else arg
107
+ )
108
+ for field, arg in zip(cls._fields[-num_missing:], args[-num_missing:])
109
+ ]
110
+ if orig_class_name not in self.warned_classes:
111
+ new_fields = cls._fields[len(cls._fields) - num_missing :]
112
+ logger.warning(
113
+ f"New fields {new_fields} for the '{orig_class_name}' class objects are set to their default values or None due to an updated definition of this class."
114
+ )
115
+ self.warned_classes.add(orig_class_name)
116
+ # Case when the object of new class definition creating within old class definition
117
+ elif len(args) > len(cls._fields):
118
+ end_index = len(args)
119
+ args = args[: len(cls._fields)]
120
+ if orig_class_name not in self.warned_classes:
121
+ logger.warning(
122
+ f"Extra fields idx {list(range(len(cls._fields), end_index))} are ignored for '{orig_class_name}' class objects due to an outdated class definition"
123
+ )
124
+ self.warned_classes.add(orig_class_name)
125
+ if not self.sdk_update_notified:
126
+ logger.warning(
127
+ "It is recommended to update the SDK version to restore the project version correctly."
128
+ )
129
+ self.sdk_update_notified = True
90
130
  return orig_new(cls, *args, **kwargs)
91
131
 
92
- # Create a new class dynamically
93
- NewCls = type(f"Pickled{cls.__name__}", (cls,), {"__new__": new})
132
+ # Create a new subclass dynamically to prevent redefining the current class
133
+ NewCls = type(f"{prefix}{cls.__name__}", (cls,), {"__new__": new})
94
134
  return NewCls
95
135
 
96
136
  return cls
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: supervisely
3
- Version: 6.73.314
3
+ Version: 6.73.316
4
4
  Summary: Supervisely Python SDK.
5
5
  Home-page: https://github.com/supervisely/supervisely
6
6
  Author: Supervisely
@@ -32,9 +32,9 @@ supervisely/api/image_api.py,sha256=WIML_6N1qgOWBm3acexmGSWz4hAaSxlYmUtbytROaP8,
32
32
  supervisely/api/import_storage_api.py,sha256=BDCgmR0Hv6OoiRHLCVPKt3iDxSVlQp1WrnKhAK_Zl84,460
33
33
  supervisely/api/issues_api.py,sha256=BqDJXmNoTzwc3xe6_-mA7FDFC5QQ-ahGbXk_HmpkSeQ,17925
34
34
  supervisely/api/labeling_job_api.py,sha256=EWJh3TGauAOUWuAlK-Ey8s_S4FDMwa6I0snHX6dnhH8,55036
35
- supervisely/api/module_api.py,sha256=NkDU9gZ0hAHFVnbF26fOOx56QGizyQO23E2kMjKrBWM,44513
35
+ supervisely/api/module_api.py,sha256=GSkB9p4Xz9_HeIC9pFm060fOFeGkUK4M7pgryClrAbE,44545
36
36
  supervisely/api/neural_network_api.py,sha256=ktPVRO4Jeulougio8F0mioJJHwRJcX250Djp1wBoQ9c,7620
37
- supervisely/api/object_class_api.py,sha256=-rQcKwhBw3iL9KNH9c1ROgoimgWM1ls6Wi_tb1R-MzY,7683
37
+ supervisely/api/object_class_api.py,sha256=hBcQuKi9ouoiR7f99eot6vXHvqbzmal3IrHjJxuoFXg,10396
38
38
  supervisely/api/plugin_api.py,sha256=TlfrosdRuYG4NUxk92QiQoVaOdztFspPpygyVa3M3zk,5283
39
39
  supervisely/api/project_api.py,sha256=WwpwzsQjue2276Rn_wkcPxJAM4OaQr6haf81ZmCGpBI,79992
40
40
  supervisely/api/project_class_api.py,sha256=5cyjdGPPb2tpttu5WmYoOxUNiDxqiojschkhZumF0KM,1426
@@ -1009,11 +1009,11 @@ supervisely/pointcloud_annotation/pointcloud_tag_collection.py,sha256=j_TAN23GkT
1009
1009
  supervisely/pointcloud_episodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1010
1010
  supervisely/pointcloud_episodes/pointcloud_episodes.py,sha256=cRXdtw7bMsbsdVQjxfWxFSESrO-LGiqqsZyyExl2Mbg,3430
1011
1011
  supervisely/project/__init__.py,sha256=hlzdj9Pgy53Q3qdP8LMtGTChvZHQuuShdtui2eRUQeE,2601
1012
- supervisely/project/data_version.py,sha256=nknaWJSUCwoDyNG9_d1KA-GjzidhV9zd9Cn8cg15DOU,19270
1012
+ supervisely/project/data_version.py,sha256=6vOz5ovBeCIiMAKUG7lGQ5IXvQnU1GbcnrWxdOvaVlo,19311
1013
1013
  supervisely/project/download.py,sha256=zb8sb4XZ6Qi3CP7fmtLRUAYzaxs_W0WnOfe2x3ZVRMs,24639
1014
1014
  supervisely/project/pointcloud_episode_project.py,sha256=yiWdNBQiI6f1O9sr1pg8JHW6O-w3XUB1rikJNn3Oung,41866
1015
1015
  supervisely/project/pointcloud_project.py,sha256=Kx1Vaes-krwG3BiRRtHRLQxb9G5m5bTHPN9IzRqmNWo,49399
1016
- supervisely/project/project.py,sha256=LHsrMBbMxdMynhuS0RhjiRFxnzikj6esyKFfR8kEZ9Q,203388
1016
+ supervisely/project/project.py,sha256=nKnnYVrSx_MWh5G_fObaAegkRxLFJg_J074SaduEYGo,205871
1017
1017
  supervisely/project/project_meta.py,sha256=26s8IiHC5Pg8B1AQi6_CrsWteioJP2in00cRNe8QlW0,51423
1018
1018
  supervisely/project/project_settings.py,sha256=NLThzU_DCynOK6hkHhVdFyezwprn9UqlnrLDe_3qhkY,9347
1019
1019
  supervisely/project/project_type.py,sha256=EZDJFRi4MmC_5epYexBgML5WMZsWdEVk_CjqDQy5m3c,572
@@ -1075,9 +1075,9 @@ supervisely/worker_proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
1075
1075
  supervisely/worker_proto/worker_api_pb2.py,sha256=VQfi5JRBHs2pFCK1snec3JECgGnua3Xjqw_-b3aFxuM,59142
1076
1076
  supervisely/worker_proto/worker_api_pb2_grpc.py,sha256=3BwQXOaP9qpdi0Dt9EKG--Lm8KGN0C5AgmUfRv77_Jk,28940
1077
1077
  supervisely_lib/__init__.py,sha256=7-3QnN8Zf0wj8NCr2oJmqoQWMKKPKTECvjH9pd2S5vY,159
1078
- supervisely-6.73.314.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1079
- supervisely-6.73.314.dist-info/METADATA,sha256=tkFe5LFrkVUYUTeEIxFSOeaMTKdD2Yd5d5ELJNV7ONo,33596
1080
- supervisely-6.73.314.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1081
- supervisely-6.73.314.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1082
- supervisely-6.73.314.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1083
- supervisely-6.73.314.dist-info/RECORD,,
1078
+ supervisely-6.73.316.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1079
+ supervisely-6.73.316.dist-info/METADATA,sha256=1Bzkm7rcu6QQawRicf_xyPpgsgcqefhLyRDC4Kd6zXw,33596
1080
+ supervisely-6.73.316.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
1081
+ supervisely-6.73.316.dist-info/entry_points.txt,sha256=U96-5Hxrp2ApRjnCoUiUhWMqijqh8zLR03sEhWtAcms,102
1082
+ supervisely-6.73.316.dist-info/top_level.txt,sha256=kcFVwb7SXtfqZifrZaSE3owHExX4gcNYe7Q2uoby084,28
1083
+ supervisely-6.73.316.dist-info/RECORD,,