synapse-sdk 1.0.0a81__py3-none-any.whl → 1.0.0a83__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 synapse-sdk might be problematic. Click here for more details.

@@ -1,7 +1,7 @@
1
1
  import json
2
2
  from datetime import datetime
3
3
  from enum import Enum
4
- from typing import Annotated, Any, Dict, List, Optional
4
+ from typing import Annotated, Any, Dict, List, Optional, Tuple
5
5
 
6
6
  import requests
7
7
  from pydantic import AfterValidator, BaseModel, field_validator
@@ -381,14 +381,29 @@ class ToTaskAction(Action):
381
381
  files = data_unit.get('files', {})
382
382
  data_file = files.get(target_specification_name)
383
383
 
384
+ # Extract primary file URL from task data
385
+ primary_file_url, primary_file_original_name = self._extract_primary_file_url(task)
386
+ if not primary_file_url:
387
+ error_msg = 'Primary image URL not found in task data'
388
+ self.run.log_message(f'{error_msg} for task {task_id}')
389
+ self.run.log_annotate_task_data({'task_id': task_id, 'error': error_msg}, AnnotateTaskDataStatus.FAILED)
390
+ return {'success': False, 'error': error_msg}
391
+
384
392
  if not data_file:
385
393
  error_msg = 'File specification not found'
386
394
  self.run.log_message(f'{error_msg} for task {task_id}')
387
395
  self.run.log_annotate_task_data({'task_id': task_id, 'error': error_msg}, AnnotateTaskDataStatus.FAILED)
388
396
  return {'success': False, 'error': error_msg}
389
397
 
390
- url = data_file.get('url')
391
- if not url:
398
+ data_file_url = data_file.get('url')
399
+ data_file_original_name = data_file.get('file_name_original')
400
+ if not data_file_original_name:
401
+ error_msg = 'File original name not found'
402
+ self.run.log_message(f'{error_msg} for task {task_id}')
403
+ self.run.log_annotate_task_data({'task_id': task_id, 'error': error_msg}, AnnotateTaskDataStatus.FAILED)
404
+ return {'success': False, 'error': error_msg}
405
+
406
+ if not data_file_url:
392
407
  error_msg = 'URL not found'
393
408
  self.run.log_message(f'{error_msg} for task {task_id}')
394
409
  self.run.log_annotate_task_data({'task_id': task_id, 'error': error_msg}, AnnotateTaskDataStatus.FAILED)
@@ -396,32 +411,29 @@ class ToTaskAction(Action):
396
411
 
397
412
  # Fetch and process the data
398
413
  try:
399
- response = requests.get(url)
400
- response.raise_for_status()
401
- data = json.loads(response.content)
402
-
403
414
  # Convert data to task object
404
415
  annotation_to_task = self.entrypoint(self.run)
405
- converted_data = annotation_to_task.convert_data_from_file(data)
406
-
407
- # Submit annotation data
408
- client.annotate_task_data(task_id, data={'action': 'submit', 'data': converted_data})
409
-
410
- # Log success
411
- self.run.log_annotate_task_data({'task_id': task_id, 'url': url}, AnnotateTaskDataStatus.SUCCESS)
412
- return {'success': True}
413
-
416
+ converted_data = annotation_to_task.convert_data_from_file(
417
+ primary_file_url, primary_file_original_name, data_file_url, data_file_original_name
418
+ )
414
419
  except requests.RequestException as e:
415
420
  error_msg = f'Failed to fetch data from URL: {str(e)}'
416
421
  self.run.log_message(f'{error_msg} for task {task_id}')
417
422
  self.run.log_annotate_task_data({'task_id': task_id, 'error': error_msg}, AnnotateTaskDataStatus.FAILED)
418
423
  return {'success': False, 'error': error_msg}
419
- except json.JSONDecodeError as e:
420
- error_msg = f'Failed to parse JSON data: {str(e)}'
424
+ except Exception as e:
425
+ error_msg = f'Failed to convert data to task object: {str(e)}'
421
426
  self.run.log_message(f'{error_msg} for task {task_id}')
422
427
  self.run.log_annotate_task_data({'task_id': task_id, 'error': error_msg}, AnnotateTaskDataStatus.FAILED)
423
428
  return {'success': False, 'error': error_msg}
424
429
 
430
+ # Submit annotation data
431
+ client.annotate_task_data(task_id, data={'action': 'submit', 'data': converted_data})
432
+
433
+ # Log success
434
+ self.run.log_annotate_task_data({'task_id': task_id}, AnnotateTaskDataStatus.SUCCESS)
435
+ return {'success': True}
436
+
425
437
  def _process_single_task_with_inference(
426
438
  self, client: BackendClient, task_id: int, task: Dict[str, Any]
427
439
  ) -> Dict[str, Any]:
@@ -464,7 +476,7 @@ class ToTaskAction(Action):
464
476
  return pre_processor_status
465
477
 
466
478
  # Extract primary file URL from task data
467
- primary_file_url = self._extract_primary_file_url(task)
479
+ primary_file_url, _ = self._extract_primary_file_url(task)
468
480
  if not primary_file_url:
469
481
  error_msg = 'Primary image URL not found in task data'
470
482
  self.run.log_message(f'{error_msg} for task {task_id}')
@@ -606,23 +618,23 @@ class ToTaskAction(Action):
606
618
  except Exception as e:
607
619
  return {'success': False, 'error': f'Failed to restart pre-processor: {str(e)}'}
608
620
 
609
- def _extract_primary_file_url(self, task: Dict[str, Any]) -> Optional[str]:
621
+ def _extract_primary_file_url(self, task: Dict[str, Any]) -> Tuple[str, str]:
610
622
  """Extract the primary file URL from task data.
611
623
 
612
624
  Args:
613
625
  task (Dict[str, Any]): The task data.
614
626
 
615
627
  Returns:
616
- Optional[str]: The primary file URL if found, None otherwise.
628
+ Tuple[str, str]: The primary file URL and original name.
617
629
  """
618
630
  data_unit = task.get('data_unit', {})
619
631
  files = data_unit.get('files', {})
620
632
 
621
633
  for file_info in files.values():
622
634
  if isinstance(file_info, dict) and file_info.get('is_primary') and file_info.get('url'):
623
- return file_info['url']
635
+ return file_info['url'], file_info['file_name_original']
624
636
 
625
- return None
637
+ return None, None
626
638
 
627
639
  def _run_inference(
628
640
  self, client: BackendClient, pre_processor_code: str, pre_processor_version: str, primary_file_url: str
@@ -7,18 +7,34 @@ class AnnotationToTask:
7
7
  """
8
8
  self.run = run
9
9
 
10
- def convert_data_from_file(self, data: dict):
10
+ def convert_data_from_file(
11
+ self,
12
+ primary_file_url: str,
13
+ primary_file_original_name: str,
14
+ data_file_url: str,
15
+ data_file_original_name: str,
16
+ ) -> dict:
11
17
  """Convert the data from a file to a task object.
12
18
 
13
19
  Args:
14
- data: Converted data.
20
+ primary_file_url (str): primary file url.
21
+ primary_file_original_name (str): primary file original name.
22
+ data_file_url (str): data file url.
23
+ data_file_original_name (str): data file original name.
24
+
25
+ Returns:
26
+ dict: The converted data.
15
27
  """
16
- return data
28
+ converted_data = {}
29
+ return converted_data
17
30
 
18
- def convert_data_from_inference(self, data: dict):
31
+ def convert_data_from_inference(self, data: dict) -> dict:
19
32
  """Convert the data from inference result to a task object.
20
33
 
21
34
  Args:
22
35
  data: Converted data.
36
+
37
+ Returns:
38
+ dict: The converted data.
23
39
  """
24
40
  return data
@@ -116,12 +116,13 @@ class COCOToDMConverter(ToDMConverter):
116
116
  result[img_filename] = (dm_json, img_path)
117
117
  return result
118
118
 
119
- def convert_single_file(self, data: Dict[str, Any], original_file: IO) -> Dict[str, Any]:
119
+ def convert_single_file(self, data: Dict[str, Any], original_file: IO, original_image_name: str) -> Dict[str, Any]:
120
120
  """Convert a single COCO annotation data and corresponding image to DM format.
121
121
 
122
122
  Args:
123
123
  data: COCO format data dictionary (JSON content)
124
124
  original_file: File object for the corresponding original image
125
+ original_image_name: Original image name
125
126
 
126
127
  Returns:
127
128
  Dictionary containing DM format data for the single file
@@ -147,7 +148,7 @@ class COCOToDMConverter(ToDMConverter):
147
148
  matched_img = None
148
149
  for img in images:
149
150
  for key in ['file_name', 'filename', 'name']:
150
- if key in img and os.path.basename(img[key]) == img_basename:
151
+ if key in img and os.path.basename(img[key]) == original_image_name:
151
152
  matched_img = img
152
153
  break
153
154
  if matched_img:
@@ -157,7 +158,6 @@ class COCOToDMConverter(ToDMConverter):
157
158
  raise ValueError(f'No matching image found in COCO data for file: {img_basename}')
158
159
 
159
160
  img_id = matched_img['id']
160
- print('img_id : ', img_id)
161
161
  cat_map = {cat['id']: cat for cat in categories}
162
162
  anns = [ann for ann in annotations if ann['image_id'] == img_id]
163
163
 
@@ -1,6 +1,6 @@
1
1
  import os
2
2
  import xml.etree.ElementTree as ET
3
- from typing import Any, Dict, IO, List, Optional, Tuple
3
+ from typing import IO, Any, Dict, List, Optional, Tuple
4
4
 
5
5
  from PIL import Image
6
6
 
@@ -11,10 +11,29 @@ class YOLOToDMConverter(ToDMConverter):
11
11
  """Convert YOLO formatted datasets to DM format."""
12
12
 
13
13
  IMG_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.bmp']
14
-
15
- def __init__(self, root_dir: str = None, is_categorized_dataset: bool = False, is_single_conversion: bool = False):
14
+ CLASS_NAMES = []
15
+
16
+ def __init__(
17
+ self,
18
+ root_dir: str = None,
19
+ is_categorized_dataset: bool = False,
20
+ is_single_conversion: bool = False,
21
+ class_names: List[str] = None,
22
+ ):
16
23
  super().__init__(root_dir, is_categorized_dataset, is_single_conversion)
17
24
 
25
+ # Set class names
26
+ self.CLASS_NAMES = class_names
27
+
28
+ # Get class names from dataset.yaml if not provided
29
+ if not class_names:
30
+ dataset_yaml_path = os.path.join(self.root_dir, 'dataset.yaml')
31
+ if not os.path.exists(dataset_yaml_path):
32
+ raise FileNotFoundError(f'No dataset.yaml file found in {self.root_dir}.')
33
+ with open(dataset_yaml_path, 'r', encoding='utf-8') as f:
34
+ dataset_yaml = yaml.safe_load(f)
35
+ self.CLASS_NAMES = dataset_yaml.get('names', [])
36
+
18
37
  def convert(self):
19
38
  """Convert YOLO dataset to DM format."""
20
39
  if self.is_categorized_dataset:
@@ -122,15 +141,6 @@ class YOLOToDMConverter(ToDMConverter):
122
141
  if not os.path.isdir(labels_dir):
123
142
  raise FileNotFoundError(f"No labels directory found in {split_dir} (expected 'labels').")
124
143
 
125
- # Load dataset.yaml
126
-
127
- dataset_yaml_path = os.path.join(self.root_dir, 'dataset.yaml')
128
- if not os.path.exists(dataset_yaml_path):
129
- raise FileNotFoundError(f'No dataset.yaml file found in {split_dir}.')
130
- with open(dataset_yaml_path, 'r', encoding='utf-8') as f:
131
- dataset_yaml = yaml.safe_load(f)
132
- class_names = dataset_yaml.get('names', [])
133
-
134
144
  # Build DM data
135
145
  result = {}
136
146
  for label_filename in os.listdir(labels_dir):
@@ -156,7 +166,7 @@ class YOLOToDMConverter(ToDMConverter):
156
166
  }
157
167
 
158
168
  for line in label_lines:
159
- ann = self._parse_yolo_line(line, class_names, img_size)
169
+ ann = self._parse_yolo_line(line, self.CLASS_NAMES, img_size)
160
170
  if ann is None:
161
171
  continue
162
172
 
@@ -187,13 +197,12 @@ class YOLOToDMConverter(ToDMConverter):
187
197
  result[os.path.basename(img_path)] = (dm_json, img_path)
188
198
  return result
189
199
 
190
- def convert_single_file(self, data: List[str], original_file: IO, class_names: List[str]) -> Dict[str, Any]:
200
+ def convert_single_file(self, data: List[str], original_file: IO) -> Dict[str, Any]:
191
201
  """Convert a single YOLO label data and corresponding image to DM format.
192
202
 
193
203
  Args:
194
204
  data: List of YOLO label lines (strings from .txt file content)
195
205
  original_file: File object for the corresponding original image
196
- class_names: List of class names corresponding to indices in the label data
197
206
 
198
207
  Returns:
199
208
  Dictionary containing DM format data for the single file
@@ -206,7 +215,7 @@ class YOLOToDMConverter(ToDMConverter):
206
215
  raise ValueError('original_file must have a "name" attribute representing its path or filename.')
207
216
 
208
217
  if hasattr(self, '_get_image_size'):
209
- img_size = self._get_image_size(original_file)
218
+ img_size = self._get_image_size(img_path)
210
219
  else:
211
220
  raise AttributeError('Converter missing _get_image_size method for file objects.')
212
221
 
@@ -223,7 +232,7 @@ class YOLOToDMConverter(ToDMConverter):
223
232
  }
224
233
 
225
234
  for line in label_lines:
226
- ann = self._parse_yolo_line(line, class_names, img_size)
235
+ ann = self._parse_yolo_line(line, self.CLASS_NAMES, img_size)
227
236
  if ann is None:
228
237
  continue
229
238
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synapse-sdk
3
- Version: 1.0.0a81
3
+ Version: 1.0.0a83
4
4
  Summary: synapse sdk
5
5
  Author-email: datamaker <developer@datamaker.io>
6
6
  License: MIT
@@ -152,11 +152,11 @@ synapse_sdk/plugins/categories/post_annotation/templates/plugin/post_annotation.
152
152
  synapse_sdk/plugins/categories/pre_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
153
  synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
154
  synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py,sha256=6ib3RmnGrjpsQ0e_G-mRH1lfFunQ3gh2M831vuDn7HU,344
155
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task.py,sha256=EkKRId4zWVvqMFa2KxdAb3FaLtt3n5wz3rGkcVBltWY,31229
155
+ synapse_sdk/plugins/categories/pre_annotation/actions/to_task.py,sha256=otUpG2TfDPMyigFFe0GuqPc2myh9hZC1iBzx-L7QMio,32138
156
156
  synapse_sdk/plugins/categories/pre_annotation/templates/config.yaml,sha256=VREoCp9wsvZ8T2E1d_MEKlR8TC_herDJGVQtu3ezAYU,589
157
157
  synapse_sdk/plugins/categories/pre_annotation/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
158
  synapse_sdk/plugins/categories/pre_annotation/templates/plugin/pre_annotation.py,sha256=HBHxHuv2gMBzDB2alFfrzI_SZ1Ztk6mo7eFbR5GqHKw,106
159
- synapse_sdk/plugins/categories/pre_annotation/templates/plugin/to_task.py,sha256=0j01vFZYkaAw8mtf6HYfun3IUDlryTexqvss_JZtc-Y,618
159
+ synapse_sdk/plugins/categories/pre_annotation/templates/plugin/to_task.py,sha256=LfM3pWfBYZfTJjpCDq89eo--uAKi-sgs8PWkilj31tI,1135
160
160
  synapse_sdk/plugins/categories/smart_tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
161
  synapse_sdk/plugins/categories/smart_tool/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
162
162
  synapse_sdk/plugins/categories/smart_tool/actions/auto_label.py,sha256=fHiqA8ntmzjs2GMVMuByR7Clh2zhLie8OPF9B8OmwxM,1279
@@ -199,16 +199,16 @@ synapse_sdk/utils/string.py,sha256=rEwuZ9SAaZLcQ8TYiwNKr1h2u4CfnrQx7SUL8NWmChg,2
199
199
  synapse_sdk/utils/converters/__init__.py,sha256=xQi_n7xS9BNyDiolsxH2jw1CtD6avxMPj2cHnwvidi8,11311
200
200
  synapse_sdk/utils/converters/coco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  synapse_sdk/utils/converters/coco/from_dm.py,sha256=B9zvb8Kph9haYLVIZhzneWiHCImFbuWqAaE7g6Nk0lI,11365
202
- synapse_sdk/utils/converters/coco/to_dm.py,sha256=YmD_NHKSUL8RZbzWX52FgDaJG0uX4I8f8Omp7ilhSec,9054
202
+ synapse_sdk/utils/converters/coco/to_dm.py,sha256=SOzzACYlK0vJE6SIpmFwMUV1ZbdmsQ_t5mceG0SQahE,9105
203
203
  synapse_sdk/utils/converters/dm/__init__.py,sha256=_B6w814bMPhisNCNlSPEiQOs9RH0EZHQqd89LnVhD1U,1983
204
204
  synapse_sdk/utils/converters/dm/from_v1.py,sha256=4BG_NA_7YdW5rI1F8LCFg39M-IJZVfRgi2b9FBxTAmw,26059
205
205
  synapse_sdk/utils/converters/dm/to_v1.py,sha256=A123zAR_dLqEW83BgAl5_J1ACstjZWTHivlW5qvOu_E,13432
206
206
  synapse_sdk/utils/converters/pascal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
207
207
  synapse_sdk/utils/converters/pascal/from_dm.py,sha256=AKOeQoyeSbSOawf-ya9dLx-pZP_MomNcDaCW5ka5_8Y,10378
208
- synapse_sdk/utils/converters/pascal/to_dm.py,sha256=JkA_OI_IR1ealZPe2uo4hFBcFyOh_VfeyIY43-R4IBA,8614
208
+ synapse_sdk/utils/converters/pascal/to_dm.py,sha256=bQNUepahOCot4J23LCPOlFOhIZJ8cAK-pge23eJZETM,8614
209
209
  synapse_sdk/utils/converters/yolo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
210
210
  synapse_sdk/utils/converters/yolo/from_dm.py,sha256=-JDCQLk4g1_FIVoOwZ1Tcs2kWFkhXRCAPVLKLXz6sLU,16180
211
- synapse_sdk/utils/converters/yolo/to_dm.py,sha256=UUGTbBNeG5Ao8PSJbizrZRQJfeAMuSDfZs8SGOyr-YU,10464
211
+ synapse_sdk/utils/converters/yolo/to_dm.py,sha256=XcSkyPickvdPR2JZ-PMMPEf1-uWQL76_pO78-4aPYcQ,10614
212
212
  synapse_sdk/utils/pydantic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
213
213
  synapse_sdk/utils/pydantic/config.py,sha256=1vYOcUI35GslfD1rrqhFkNXXJOXt4IDqOPSx9VWGfNE,123
214
214
  synapse_sdk/utils/pydantic/errors.py,sha256=0v0T12eQBr1KrFiEOBu6KMaPK4aPEGEC6etPJGoR5b4,1061
@@ -220,9 +220,9 @@ synapse_sdk/utils/storage/providers/gcp.py,sha256=i2BQCu1Kej1If9SuNr2_lEyTcr5M_n
220
220
  synapse_sdk/utils/storage/providers/http.py,sha256=2DhIulND47JOnS5ZY7MZUex7Su3peAPksGo1Wwg07L4,5828
221
221
  synapse_sdk/utils/storage/providers/s3.py,sha256=ZmqekAvIgcQBdRU-QVJYv1Rlp6VHfXwtbtjTSphua94,2573
222
222
  synapse_sdk/utils/storage/providers/sftp.py,sha256=_8s9hf0JXIO21gvm-JVS00FbLsbtvly4c-ETLRax68A,1426
223
- synapse_sdk-1.0.0a81.dist-info/licenses/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
224
- synapse_sdk-1.0.0a81.dist-info/METADATA,sha256=iAK5lypAXDJzvZjjqFOX0lyvyYyx3rYQvlOOkzXEbKg,3805
225
- synapse_sdk-1.0.0a81.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
226
- synapse_sdk-1.0.0a81.dist-info/entry_points.txt,sha256=VNptJoGoNJI8yLXfBmhgUefMsmGI0m3-0YoMvrOgbxo,48
227
- synapse_sdk-1.0.0a81.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
228
- synapse_sdk-1.0.0a81.dist-info/RECORD,,
223
+ synapse_sdk-1.0.0a83.dist-info/licenses/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
224
+ synapse_sdk-1.0.0a83.dist-info/METADATA,sha256=JFd43LG4HIkMQZECtk_O7CBHF3vBdNHd2LWH9W5VtjQ,3805
225
+ synapse_sdk-1.0.0a83.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
226
+ synapse_sdk-1.0.0a83.dist-info/entry_points.txt,sha256=VNptJoGoNJI8yLXfBmhgUefMsmGI0m3-0YoMvrOgbxo,48
227
+ synapse_sdk-1.0.0a83.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
228
+ synapse_sdk-1.0.0a83.dist-info/RECORD,,