synapse-sdk 1.0.0a95__py3-none-any.whl → 1.0.0a98__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.
- synapse_sdk/plugins/categories/upload/actions/upload.py +16 -1
- synapse_sdk/utils/converters/pascal/from_dm.py +32 -10
- synapse_sdk/utils/storage/providers/file_system.py +15 -13
- {synapse_sdk-1.0.0a95.dist-info → synapse_sdk-1.0.0a98.dist-info}/METADATA +1 -1
- {synapse_sdk-1.0.0a95.dist-info → synapse_sdk-1.0.0a98.dist-info}/RECORD +9 -9
- {synapse_sdk-1.0.0a95.dist-info → synapse_sdk-1.0.0a98.dist-info}/WHEEL +0 -0
- {synapse_sdk-1.0.0a95.dist-info → synapse_sdk-1.0.0a98.dist-info}/entry_points.txt +0 -0
- {synapse_sdk-1.0.0a95.dist-info → synapse_sdk-1.0.0a98.dist-info}/licenses/LICENSE +0 -0
- {synapse_sdk-1.0.0a95.dist-info → synapse_sdk-1.0.0a98.dist-info}/top_level.txt +0 -0
|
@@ -24,6 +24,20 @@ from synapse_sdk.utils.pydantic.validators import non_blank
|
|
|
24
24
|
from synapse_sdk.utils.storage import get_pathlib
|
|
25
25
|
|
|
26
26
|
|
|
27
|
+
class PathAwareJSONEncoder(json.JSONEncoder):
|
|
28
|
+
"""Custom JSON encoder that handles Path-like objects."""
|
|
29
|
+
|
|
30
|
+
def default(self, obj):
|
|
31
|
+
if hasattr(obj, '__fspath__') or hasattr(obj, 'as_posix'):
|
|
32
|
+
# Handle Path-like objects (including UPath, SFTPPath, pathlib.Path, etc.)
|
|
33
|
+
return str(obj)
|
|
34
|
+
elif hasattr(obj, 'isoformat'):
|
|
35
|
+
# Handle datetime objects
|
|
36
|
+
return obj.isoformat()
|
|
37
|
+
# Let the base class handle other types
|
|
38
|
+
return super().default(obj)
|
|
39
|
+
|
|
40
|
+
|
|
27
41
|
class UploadStatus(str, Enum):
|
|
28
42
|
SUCCESS = 'success'
|
|
29
43
|
FAILED = 'failed'
|
|
@@ -67,7 +81,8 @@ class UploadRun(Run):
|
|
|
67
81
|
status (UploadStatus): The status of the data file.
|
|
68
82
|
"""
|
|
69
83
|
now = datetime.now().isoformat()
|
|
70
|
-
|
|
84
|
+
# Use custom JSON encoder to handle Path-like objects
|
|
85
|
+
data_file_info_str = json.dumps(data_file_info, ensure_ascii=False, cls=PathAwareJSONEncoder)
|
|
71
86
|
self.log(
|
|
72
87
|
'upload_data_file',
|
|
73
88
|
self.DataFileLog(data_file_info=data_file_info_str, status=status.value, created=now).model_dump(),
|
|
@@ -27,7 +27,9 @@ class FromDMToPascalConverter(FromDMConverter):
|
|
|
27
27
|
return img_path
|
|
28
28
|
return None
|
|
29
29
|
|
|
30
|
-
def build_pascal_xml(
|
|
30
|
+
def build_pascal_xml(
|
|
31
|
+
self, img_filename: str, img_size: tuple, objects: List[dict], has_segmentation: bool = None
|
|
32
|
+
) -> ET.ElementTree:
|
|
31
33
|
"""Build a Pascal VOC XML tree from image filename, size, and objects."""
|
|
32
34
|
folder = 'Images'
|
|
33
35
|
width, height, depth = img_size
|
|
@@ -41,7 +43,12 @@ class FromDMToPascalConverter(FromDMConverter):
|
|
|
41
43
|
ET.SubElement(size, 'width').text = str(width)
|
|
42
44
|
ET.SubElement(size, 'height').text = str(height)
|
|
43
45
|
ET.SubElement(size, 'depth').text = str(depth)
|
|
44
|
-
|
|
46
|
+
|
|
47
|
+
# Set segmented to 1 if there are any segmentation objects, 0 otherwise
|
|
48
|
+
if has_segmentation is None:
|
|
49
|
+
has_segmentation = any(obj.get('has_segmentation', False) for obj in objects)
|
|
50
|
+
ET.SubElement(annotation, 'segmented').text = '1' if has_segmentation else '0'
|
|
51
|
+
|
|
45
52
|
for obj in objects:
|
|
46
53
|
obj_elem = ET.SubElement(annotation, 'object')
|
|
47
54
|
ET.SubElement(obj_elem, 'name').text = obj['name']
|
|
@@ -58,6 +65,8 @@ class FromDMToPascalConverter(FromDMConverter):
|
|
|
58
65
|
def parse_dm_annotations(self, annotation: dict):
|
|
59
66
|
"""Parse DM annotations and convert to Pascal VOC format."""
|
|
60
67
|
objects = []
|
|
68
|
+
has_segmentation = 'segmentation' in annotation
|
|
69
|
+
|
|
61
70
|
# Only include bounding_box (Pascal VOC does not support polyline/keypoint by default)
|
|
62
71
|
if 'bounding_box' in annotation:
|
|
63
72
|
for box in annotation['bounding_box']:
|
|
@@ -67,10 +76,18 @@ class FromDMToPascalConverter(FromDMConverter):
|
|
|
67
76
|
ymin = int(round(y))
|
|
68
77
|
xmax = int(round(x + w))
|
|
69
78
|
ymax = int(round(y + h))
|
|
70
|
-
objects.append({
|
|
79
|
+
objects.append({
|
|
80
|
+
'name': class_name,
|
|
81
|
+
'xmin': xmin,
|
|
82
|
+
'ymin': ymin,
|
|
83
|
+
'xmax': xmax,
|
|
84
|
+
'ymax': ymax,
|
|
85
|
+
'has_segmentation': has_segmentation,
|
|
86
|
+
})
|
|
71
87
|
self.class_names.add(class_name)
|
|
88
|
+
|
|
72
89
|
# polyline, keypoint 등은 무시
|
|
73
|
-
return objects
|
|
90
|
+
return objects, has_segmentation
|
|
74
91
|
|
|
75
92
|
def _convert_split_dir(self, split_dir: str, split_name: str):
|
|
76
93
|
"""Convert a split dir (train/valid/test) to list of (xml_tree, xml_filename, img_src, img_name)."""
|
|
@@ -89,8 +106,10 @@ class FromDMToPascalConverter(FromDMConverter):
|
|
|
89
106
|
with Image.open(img_path) as img:
|
|
90
107
|
width, height = img.size
|
|
91
108
|
depth = len(img.getbands())
|
|
92
|
-
objects = self.parse_dm_annotations(img_ann)
|
|
93
|
-
xml_tree = self.build_pascal_xml(
|
|
109
|
+
objects, has_segmentation = self.parse_dm_annotations(img_ann)
|
|
110
|
+
xml_tree = self.build_pascal_xml(
|
|
111
|
+
os.path.basename(img_path), (width, height, depth), objects, has_segmentation
|
|
112
|
+
)
|
|
94
113
|
xml_filename = base + '.xml'
|
|
95
114
|
results.append((xml_tree, xml_filename, img_path, os.path.basename(img_path)))
|
|
96
115
|
return results
|
|
@@ -112,8 +131,10 @@ class FromDMToPascalConverter(FromDMConverter):
|
|
|
112
131
|
with Image.open(img_path) as img:
|
|
113
132
|
width, height = img.size
|
|
114
133
|
depth = len(img.getbands())
|
|
115
|
-
objects = self.parse_dm_annotations(img_ann)
|
|
116
|
-
xml_tree = self.build_pascal_xml(
|
|
134
|
+
objects, has_segmentation = self.parse_dm_annotations(img_ann)
|
|
135
|
+
xml_tree = self.build_pascal_xml(
|
|
136
|
+
os.path.basename(img_path), (width, height, depth), objects, has_segmentation
|
|
137
|
+
)
|
|
117
138
|
xml_filename = base + '.xml'
|
|
118
139
|
results.append((xml_tree, xml_filename, img_path, os.path.basename(img_path)))
|
|
119
140
|
return results
|
|
@@ -202,12 +223,13 @@ class FromDMToPascalConverter(FromDMConverter):
|
|
|
202
223
|
# Process annotations from the first (and only) image in data
|
|
203
224
|
if 'images' in data and len(data['images']) > 0:
|
|
204
225
|
img_ann = data['images'][0]
|
|
205
|
-
objects = self.parse_dm_annotations(img_ann)
|
|
226
|
+
objects, has_segmentation = self.parse_dm_annotations(img_ann)
|
|
206
227
|
else:
|
|
207
228
|
objects = []
|
|
229
|
+
has_segmentation = False
|
|
208
230
|
|
|
209
231
|
# Build Pascal VOC XML
|
|
210
|
-
xml_tree = self.build_pascal_xml(img_filename, (width, height, depth), objects)
|
|
232
|
+
xml_tree = self.build_pascal_xml(img_filename, (width, height, depth), objects, has_segmentation)
|
|
211
233
|
xml_filename = os.path.splitext(img_filename)[0] + '.xml'
|
|
212
234
|
|
|
213
235
|
# Convert XML tree to string for easy viewing
|
|
@@ -23,10 +23,23 @@ class FileSystemStorage(BaseStorage):
|
|
|
23
23
|
>>> storage = FileSystemStorage(config)
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
|
-
def __init__(self,
|
|
27
|
-
super().__init__(
|
|
26
|
+
def __init__(self, connection_params: str | dict):
|
|
27
|
+
super().__init__(connection_params)
|
|
28
28
|
self.base_path = Path(self.query_params['location'])
|
|
29
29
|
|
|
30
|
+
def get_pathlib(self, path):
|
|
31
|
+
"""Get the path as a pathlib object.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
path (str): The path to convert.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
pathlib.Path: The converted path.
|
|
38
|
+
"""
|
|
39
|
+
if path == '/' or path == '':
|
|
40
|
+
return self.base_path
|
|
41
|
+
return self.base_path / path
|
|
42
|
+
|
|
30
43
|
def upload(self, source, target):
|
|
31
44
|
"""Upload a file from source to target location.
|
|
32
45
|
|
|
@@ -72,17 +85,6 @@ class FileSystemStorage(BaseStorage):
|
|
|
72
85
|
target_path = self.base_path / target
|
|
73
86
|
return f'file://{target_path.absolute()}'
|
|
74
87
|
|
|
75
|
-
def get_pathlib(self, path):
|
|
76
|
-
"""Get the path as a pathlib object.
|
|
77
|
-
|
|
78
|
-
Args:
|
|
79
|
-
path (str): The path to convert.
|
|
80
|
-
|
|
81
|
-
Returns:
|
|
82
|
-
pathlib.Path: The converted path.
|
|
83
|
-
"""
|
|
84
|
-
return self.base_path / path
|
|
85
|
-
|
|
86
88
|
def get_path_file_count(self, pathlib_obj):
|
|
87
89
|
"""Get the file count in the path.
|
|
88
90
|
|
|
@@ -165,7 +165,7 @@ synapse_sdk/plugins/categories/smart_tool/templates/plugin/__init__.py,sha256=47
|
|
|
165
165
|
synapse_sdk/plugins/categories/smart_tool/templates/plugin/auto_label.py,sha256=eevNg0nOcYFR4z_L_R-sCvVOYoLWSAH1jwDkAf3YCjY,320
|
|
166
166
|
synapse_sdk/plugins/categories/upload/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
167
167
|
synapse_sdk/plugins/categories/upload/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
168
|
-
synapse_sdk/plugins/categories/upload/actions/upload.py,sha256=
|
|
168
|
+
synapse_sdk/plugins/categories/upload/actions/upload.py,sha256=YATMn9ud8cqWKw4Pq14XhuCPvn5NTq_7RyfZv5hG75w,38279
|
|
169
169
|
synapse_sdk/plugins/categories/upload/templates/config.yaml,sha256=6_dRa0_J2aS8NSUfO4MKbPxZcdPS2FpJzzp51edYAZc,281
|
|
170
170
|
synapse_sdk/plugins/categories/upload/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
171
171
|
synapse_sdk/plugins/categories/upload/templates/plugin/upload.py,sha256=IZU4sdSMSLKPCtlNqF7DP2howTdYR6hr74HCUZsGdPk,1559
|
|
@@ -204,7 +204,7 @@ synapse_sdk/utils/converters/dm/__init__.py,sha256=_B6w814bMPhisNCNlSPEiQOs9RH0E
|
|
|
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
|
-
synapse_sdk/utils/converters/pascal/from_dm.py,sha256=
|
|
207
|
+
synapse_sdk/utils/converters/pascal/from_dm.py,sha256=kyVl1TBsPY-zWNusMNX5kjKD3VUu-HO71-HJ_b0NNec,11119
|
|
208
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
|
|
@@ -216,14 +216,14 @@ synapse_sdk/utils/pydantic/validators.py,sha256=G47P8ObPhsePmd_QZDK8EdPnik2CbaYz
|
|
|
216
216
|
synapse_sdk/utils/storage/__init__.py,sha256=HmZHqvoV-EogV2bE-Sw5XQRlrNuf3gfNL9irAJeRYsA,2195
|
|
217
217
|
synapse_sdk/utils/storage/registry.py,sha256=-VNIM7wERubomcyXMuAlPPRKyy87kVpkRAsdlBRp2ig,589
|
|
218
218
|
synapse_sdk/utils/storage/providers/__init__.py,sha256=crxrRzXXfBAmyR4nZS2RZvlLnr4IP1S-6eYeX_bSnLI,6412
|
|
219
|
-
synapse_sdk/utils/storage/providers/file_system.py,sha256=
|
|
219
|
+
synapse_sdk/utils/storage/providers/file_system.py,sha256=kJJmVPOsDpRwZQ-Sh4VvOP1cfknJ2tiqPp6WnB93iqM,3329
|
|
220
220
|
synapse_sdk/utils/storage/providers/gcp.py,sha256=i2BQCu1Kej1If9SuNr2_lEyTcr5M_ncGITZrL0u5wEA,363
|
|
221
221
|
synapse_sdk/utils/storage/providers/http.py,sha256=2DhIulND47JOnS5ZY7MZUex7Su3peAPksGo1Wwg07L4,5828
|
|
222
222
|
synapse_sdk/utils/storage/providers/s3.py,sha256=ZmqekAvIgcQBdRU-QVJYv1Rlp6VHfXwtbtjTSphua94,2573
|
|
223
223
|
synapse_sdk/utils/storage/providers/sftp.py,sha256=_8s9hf0JXIO21gvm-JVS00FbLsbtvly4c-ETLRax68A,1426
|
|
224
|
-
synapse_sdk-1.0.
|
|
225
|
-
synapse_sdk-1.0.
|
|
226
|
-
synapse_sdk-1.0.
|
|
227
|
-
synapse_sdk-1.0.
|
|
228
|
-
synapse_sdk-1.0.
|
|
229
|
-
synapse_sdk-1.0.
|
|
224
|
+
synapse_sdk-1.0.0a98.dist-info/licenses/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
|
|
225
|
+
synapse_sdk-1.0.0a98.dist-info/METADATA,sha256=nCN-bJ6izW6M1RD2PEtcHLcWA5QpjGmhncI29PNERrg,3837
|
|
226
|
+
synapse_sdk-1.0.0a98.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
227
|
+
synapse_sdk-1.0.0a98.dist-info/entry_points.txt,sha256=VNptJoGoNJI8yLXfBmhgUefMsmGI0m3-0YoMvrOgbxo,48
|
|
228
|
+
synapse_sdk-1.0.0a98.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
|
|
229
|
+
synapse_sdk-1.0.0a98.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|