synapse-sdk 1.0.0b5__py3-none-any.whl → 2025.12.3__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.
- synapse_sdk/__init__.py +24 -0
- synapse_sdk/cli/code_server.py +305 -33
- synapse_sdk/clients/agent/__init__.py +2 -1
- synapse_sdk/clients/agent/container.py +143 -0
- synapse_sdk/clients/agent/ray.py +296 -38
- synapse_sdk/clients/backend/annotation.py +1 -1
- synapse_sdk/clients/backend/core.py +31 -4
- synapse_sdk/clients/backend/data_collection.py +82 -7
- synapse_sdk/clients/backend/hitl.py +1 -1
- synapse_sdk/clients/backend/ml.py +1 -1
- synapse_sdk/clients/base.py +211 -61
- synapse_sdk/loggers.py +46 -0
- synapse_sdk/plugins/README.md +1340 -0
- synapse_sdk/plugins/categories/base.py +59 -9
- synapse_sdk/plugins/categories/export/actions/__init__.py +3 -0
- synapse_sdk/plugins/categories/export/actions/export/__init__.py +28 -0
- synapse_sdk/plugins/categories/export/actions/export/action.py +165 -0
- synapse_sdk/plugins/categories/export/actions/export/enums.py +113 -0
- synapse_sdk/plugins/categories/export/actions/export/exceptions.py +53 -0
- synapse_sdk/plugins/categories/export/actions/export/models.py +74 -0
- synapse_sdk/plugins/categories/export/actions/export/run.py +195 -0
- synapse_sdk/plugins/categories/export/actions/export/utils.py +187 -0
- synapse_sdk/plugins/categories/export/templates/config.yaml +19 -1
- synapse_sdk/plugins/categories/export/templates/plugin/__init__.py +390 -0
- synapse_sdk/plugins/categories/export/templates/plugin/export.py +153 -177
- synapse_sdk/plugins/categories/neural_net/actions/train.py +1130 -32
- synapse_sdk/plugins/categories/neural_net/actions/tune.py +157 -4
- synapse_sdk/plugins/categories/neural_net/templates/config.yaml +7 -4
- synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py +4 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation/__init__.py +3 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation/action.py +10 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/__init__.py +28 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/action.py +148 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/enums.py +269 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/exceptions.py +14 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/factory.py +76 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/models.py +100 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/orchestrator.py +248 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/run.py +64 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/__init__.py +17 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/annotation.py +265 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/base.py +170 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/extraction.py +83 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/metrics.py +92 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/preprocessor.py +243 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/validation.py +143 -0
- synapse_sdk/plugins/categories/upload/actions/upload/__init__.py +19 -0
- synapse_sdk/plugins/categories/upload/actions/upload/action.py +236 -0
- synapse_sdk/plugins/categories/upload/actions/upload/context.py +185 -0
- synapse_sdk/plugins/categories/upload/actions/upload/enums.py +493 -0
- synapse_sdk/plugins/categories/upload/actions/upload/exceptions.py +36 -0
- synapse_sdk/plugins/categories/upload/actions/upload/factory.py +138 -0
- synapse_sdk/plugins/categories/upload/actions/upload/models.py +214 -0
- synapse_sdk/plugins/categories/upload/actions/upload/orchestrator.py +183 -0
- synapse_sdk/plugins/categories/upload/actions/upload/registry.py +113 -0
- synapse_sdk/plugins/categories/upload/actions/upload/run.py +179 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/__init__.py +1 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/base.py +107 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/cleanup.py +62 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/collection.py +63 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/generate.py +91 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/initialize.py +82 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/metadata.py +235 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/organize.py +201 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/upload.py +104 -0
- synapse_sdk/plugins/categories/upload/actions/upload/steps/validate.py +71 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/__init__.py +1 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/base.py +82 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/__init__.py +1 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/batch.py +39 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/single.py +29 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/__init__.py +1 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/flat.py +300 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/recursive.py +287 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/__init__.py +1 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/excel.py +174 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/none.py +16 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/upload/__init__.py +1 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/upload/sync.py +84 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/validation/__init__.py +1 -0
- synapse_sdk/plugins/categories/upload/actions/upload/strategies/validation/default.py +60 -0
- synapse_sdk/plugins/categories/upload/actions/upload/utils.py +250 -0
- synapse_sdk/plugins/categories/upload/templates/README.md +470 -0
- synapse_sdk/plugins/categories/upload/templates/config.yaml +28 -2
- synapse_sdk/plugins/categories/upload/templates/plugin/__init__.py +310 -0
- synapse_sdk/plugins/categories/upload/templates/plugin/upload.py +82 -20
- synapse_sdk/plugins/models.py +111 -9
- synapse_sdk/plugins/templates/plugin-config-schema.json +7 -0
- synapse_sdk/plugins/templates/schema.json +7 -0
- synapse_sdk/plugins/utils/__init__.py +3 -0
- synapse_sdk/plugins/utils/ray_gcs.py +66 -0
- synapse_sdk/shared/__init__.py +25 -0
- synapse_sdk/utils/converters/dm/__init__.py +42 -41
- synapse_sdk/utils/converters/dm/base.py +137 -0
- synapse_sdk/utils/converters/dm/from_v1.py +208 -562
- synapse_sdk/utils/converters/dm/to_v1.py +258 -304
- synapse_sdk/utils/converters/dm/tools/__init__.py +214 -0
- synapse_sdk/utils/converters/dm/tools/answer.py +95 -0
- synapse_sdk/utils/converters/dm/tools/bounding_box.py +132 -0
- synapse_sdk/utils/converters/dm/tools/bounding_box_3d.py +121 -0
- synapse_sdk/utils/converters/dm/tools/classification.py +75 -0
- synapse_sdk/utils/converters/dm/tools/keypoint.py +117 -0
- synapse_sdk/utils/converters/dm/tools/named_entity.py +111 -0
- synapse_sdk/utils/converters/dm/tools/polygon.py +122 -0
- synapse_sdk/utils/converters/dm/tools/polyline.py +124 -0
- synapse_sdk/utils/converters/dm/tools/prompt.py +94 -0
- synapse_sdk/utils/converters/dm/tools/relation.py +86 -0
- synapse_sdk/utils/converters/dm/tools/segmentation.py +141 -0
- synapse_sdk/utils/converters/dm/tools/segmentation_3d.py +83 -0
- synapse_sdk/utils/converters/dm/types.py +168 -0
- synapse_sdk/utils/converters/dm/utils.py +162 -0
- synapse_sdk/utils/converters/dm_legacy/__init__.py +56 -0
- synapse_sdk/utils/converters/dm_legacy/from_v1.py +627 -0
- synapse_sdk/utils/converters/dm_legacy/to_v1.py +367 -0
- synapse_sdk/utils/file/__init__.py +58 -0
- synapse_sdk/utils/file/archive.py +32 -0
- synapse_sdk/utils/file/checksum.py +56 -0
- synapse_sdk/utils/file/chunking.py +31 -0
- synapse_sdk/utils/file/download.py +385 -0
- synapse_sdk/utils/file/encoding.py +40 -0
- synapse_sdk/utils/file/io.py +22 -0
- synapse_sdk/utils/file/upload.py +165 -0
- synapse_sdk/utils/file/video/__init__.py +29 -0
- synapse_sdk/utils/file/video/transcode.py +307 -0
- synapse_sdk/utils/{file.py → file.py.backup} +77 -0
- synapse_sdk/utils/network.py +272 -0
- synapse_sdk/utils/storage/__init__.py +6 -2
- synapse_sdk/utils/storage/providers/file_system.py +6 -0
- {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/METADATA +19 -2
- {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/RECORD +134 -74
- synapse_sdk/devtools/docs/.gitignore +0 -20
- synapse_sdk/devtools/docs/README.md +0 -41
- synapse_sdk/devtools/docs/blog/2019-05-28-first-blog-post.md +0 -12
- synapse_sdk/devtools/docs/blog/2019-05-29-long-blog-post.md +0 -44
- synapse_sdk/devtools/docs/blog/2021-08-01-mdx-blog-post.mdx +0 -24
- synapse_sdk/devtools/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
- synapse_sdk/devtools/docs/blog/2021-08-26-welcome/index.md +0 -29
- synapse_sdk/devtools/docs/blog/authors.yml +0 -25
- synapse_sdk/devtools/docs/blog/tags.yml +0 -19
- synapse_sdk/devtools/docs/docusaurus.config.ts +0 -138
- synapse_sdk/devtools/docs/package-lock.json +0 -17455
- synapse_sdk/devtools/docs/package.json +0 -47
- synapse_sdk/devtools/docs/sidebars.ts +0 -44
- synapse_sdk/devtools/docs/src/components/HomepageFeatures/index.tsx +0 -71
- synapse_sdk/devtools/docs/src/components/HomepageFeatures/styles.module.css +0 -11
- synapse_sdk/devtools/docs/src/css/custom.css +0 -30
- synapse_sdk/devtools/docs/src/pages/index.module.css +0 -23
- synapse_sdk/devtools/docs/src/pages/index.tsx +0 -21
- synapse_sdk/devtools/docs/src/pages/markdown-page.md +0 -7
- synapse_sdk/devtools/docs/static/.nojekyll +0 -0
- synapse_sdk/devtools/docs/static/img/docusaurus-social-card.jpg +0 -0
- synapse_sdk/devtools/docs/static/img/docusaurus.png +0 -0
- synapse_sdk/devtools/docs/static/img/favicon.ico +0 -0
- synapse_sdk/devtools/docs/static/img/logo.png +0 -0
- synapse_sdk/devtools/docs/static/img/undraw_docusaurus_mountain.svg +0 -171
- synapse_sdk/devtools/docs/static/img/undraw_docusaurus_react.svg +0 -170
- synapse_sdk/devtools/docs/static/img/undraw_docusaurus_tree.svg +0 -40
- synapse_sdk/devtools/docs/tsconfig.json +0 -8
- synapse_sdk/plugins/categories/export/actions/export.py +0 -346
- synapse_sdk/plugins/categories/export/enums.py +0 -7
- synapse_sdk/plugins/categories/neural_net/actions/gradio.py +0 -151
- synapse_sdk/plugins/categories/pre_annotation/actions/to_task.py +0 -943
- synapse_sdk/plugins/categories/upload/actions/upload.py +0 -954
- {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/WHEEL +0 -0
- {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/entry_points.txt +0 -0
- {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/licenses/LICENSE +0 -0
- {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from synapse_sdk.plugins.models import Run
|
|
8
|
+
from synapse_sdk.shared.enums import Context
|
|
9
|
+
|
|
10
|
+
from .enums import LOG_MESSAGES, ExportStatus, LogCode
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ExportRun(Run):
|
|
14
|
+
"""Export-specific run management class.
|
|
15
|
+
|
|
16
|
+
Extends the base Run class with export-specific logging capabilities
|
|
17
|
+
and event tracking. Provides type-safe logging using LogCode enums
|
|
18
|
+
and specialized methods for tracking export progress.
|
|
19
|
+
|
|
20
|
+
Manages logging for export events, data files, and export targets
|
|
21
|
+
throughout the export lifecycle. Each log entry includes status,
|
|
22
|
+
timestamps, and relevant metadata.
|
|
23
|
+
|
|
24
|
+
Attributes:
|
|
25
|
+
Inherits all attributes from base Run class plus export-specific
|
|
26
|
+
logging methods and nested model classes for structured logging.
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
>>> run = ExportRun(job_id, context)
|
|
30
|
+
>>> run.log_message_with_code(LogCode.EXPORT_STARTED)
|
|
31
|
+
>>> run.log_export_event(LogCode.RESULTS_RETRIEVED, target_id, count)
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
class ExportEventLog(BaseModel):
|
|
35
|
+
"""Model for export event log entries.
|
|
36
|
+
|
|
37
|
+
Records significant events during export processing with
|
|
38
|
+
target identification and status information.
|
|
39
|
+
|
|
40
|
+
Attributes:
|
|
41
|
+
target_id (int): The ID of the export target
|
|
42
|
+
info (str | None): Optional additional information
|
|
43
|
+
status (Context): Event status/severity level
|
|
44
|
+
created (str): Timestamp when event occurred
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
target_id: int
|
|
48
|
+
info: str | None = None
|
|
49
|
+
status: Context
|
|
50
|
+
created: str
|
|
51
|
+
|
|
52
|
+
class DataFileLog(BaseModel):
|
|
53
|
+
"""Model for data file export log entries.
|
|
54
|
+
|
|
55
|
+
Tracks the export status of individual data files during
|
|
56
|
+
export operations.
|
|
57
|
+
|
|
58
|
+
Attributes:
|
|
59
|
+
target_id (int): The ID of the target being exported
|
|
60
|
+
data_file_info (str | None): JSON information about the data file
|
|
61
|
+
status (ExportStatus): Export status (SUCCESS/FAILED/STAND_BY)
|
|
62
|
+
error (str | None): Error message if export failed
|
|
63
|
+
created (str): Timestamp when log entry was created
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
target_id: int
|
|
67
|
+
data_file_info: str | None
|
|
68
|
+
status: ExportStatus
|
|
69
|
+
error: str | None = None
|
|
70
|
+
created: str
|
|
71
|
+
|
|
72
|
+
class MetricsRecord(BaseModel):
|
|
73
|
+
"""Model for export metrics tracking.
|
|
74
|
+
|
|
75
|
+
Records count-based metrics for monitoring export
|
|
76
|
+
progress and success rates.
|
|
77
|
+
|
|
78
|
+
Attributes:
|
|
79
|
+
stand_by (int): Number of items waiting to be processed
|
|
80
|
+
failed (int): Number of items that failed processing
|
|
81
|
+
success (int): Number of items successfully processed
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
stand_by: int
|
|
85
|
+
failed: int
|
|
86
|
+
success: int
|
|
87
|
+
|
|
88
|
+
def log_message_with_code(self, code: LogCode, *args, level: Optional[Context] = None):
|
|
89
|
+
"""Log message using predefined code with type safety.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
code (LogCode): The log message code
|
|
93
|
+
*args: Arguments to format the message
|
|
94
|
+
level (Context | None): Optional context level override
|
|
95
|
+
"""
|
|
96
|
+
if code not in LOG_MESSAGES:
|
|
97
|
+
self.log_message(f'Unknown log code: {code}')
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
log_config = LOG_MESSAGES[code]
|
|
101
|
+
message = log_config['message'].format(*args) if args else log_config['message']
|
|
102
|
+
log_level = level or log_config['level'] or Context.INFO
|
|
103
|
+
|
|
104
|
+
# Always call log_message for basic logging
|
|
105
|
+
if log_level:
|
|
106
|
+
self.log_message(message, context=log_level.value)
|
|
107
|
+
else:
|
|
108
|
+
self.log_message(message)
|
|
109
|
+
|
|
110
|
+
def log_file(
|
|
111
|
+
self, log_type: str, target_id: int, data_file_info: dict, status: ExportStatus, error: str | None = None
|
|
112
|
+
):
|
|
113
|
+
"""Log export file information.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
log_type (str): The type of log ('export_data_file' or 'export_original_file').
|
|
117
|
+
target_id (int): The ID of the data file.
|
|
118
|
+
data_file_info (dict): The JSON info of the data file.
|
|
119
|
+
status (ExportStatus): The status of the data file.
|
|
120
|
+
error (str | None): The error message, if any.
|
|
121
|
+
"""
|
|
122
|
+
now = datetime.now().isoformat()
|
|
123
|
+
self.log(
|
|
124
|
+
log_type,
|
|
125
|
+
self.DataFileLog(
|
|
126
|
+
target_id=target_id,
|
|
127
|
+
data_file_info=json.dumps(data_file_info),
|
|
128
|
+
status=status.value,
|
|
129
|
+
error=error,
|
|
130
|
+
created=now,
|
|
131
|
+
).model_dump(),
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def log_export_event(self, code: LogCode, target_id: int, *args, level: Context | None = None):
|
|
135
|
+
"""Log export event using predefined code.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
code (str): The log message code.
|
|
139
|
+
target_id (int): The ID of the export target.
|
|
140
|
+
*args: Arguments to format the message.
|
|
141
|
+
level (Context | None): Optional context level override.
|
|
142
|
+
"""
|
|
143
|
+
# Call log_message_with_code to handle the basic logging
|
|
144
|
+
self.log_message_with_code(code, *args, level=level)
|
|
145
|
+
|
|
146
|
+
# Also log the event for export-specific tracking
|
|
147
|
+
if code not in LOG_MESSAGES:
|
|
148
|
+
now = datetime.now().isoformat()
|
|
149
|
+
self.log(
|
|
150
|
+
'export_event',
|
|
151
|
+
self.ExportEventLog(
|
|
152
|
+
target_id=target_id, info=f'Unknown log code: {code}', status=Context.DANGER, created=now
|
|
153
|
+
).model_dump(),
|
|
154
|
+
)
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
log_config = LOG_MESSAGES[code]
|
|
158
|
+
message = log_config['message'].format(*args) if args else log_config['message']
|
|
159
|
+
log_level = level or log_config['level'] or Context.INFO
|
|
160
|
+
|
|
161
|
+
now = datetime.now().isoformat()
|
|
162
|
+
self.log(
|
|
163
|
+
'export_event',
|
|
164
|
+
self.ExportEventLog(info=message, status=log_level, target_id=target_id, created=now).model_dump(),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def log_metrics(self, record: MetricsRecord, category: str):
|
|
168
|
+
"""Log export metrics.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
record (MetricsRecord): The metrics record to log.
|
|
172
|
+
category (str): The category of the metrics.
|
|
173
|
+
"""
|
|
174
|
+
record = self.MetricsRecord.model_validate(record)
|
|
175
|
+
self.set_metrics(value=record.model_dump(), category=category)
|
|
176
|
+
|
|
177
|
+
def export_log_json_file(
|
|
178
|
+
self,
|
|
179
|
+
target_id: int,
|
|
180
|
+
data_file_info: dict,
|
|
181
|
+
status: ExportStatus = ExportStatus.STAND_BY,
|
|
182
|
+
error: str | None = None,
|
|
183
|
+
):
|
|
184
|
+
"""Log export json data file."""
|
|
185
|
+
self.log_file('export_data_file', target_id, data_file_info, status, error)
|
|
186
|
+
|
|
187
|
+
def export_log_original_file(
|
|
188
|
+
self,
|
|
189
|
+
target_id: int,
|
|
190
|
+
data_file_info: dict,
|
|
191
|
+
status: ExportStatus = ExportStatus.STAND_BY,
|
|
192
|
+
error: str | None = None,
|
|
193
|
+
):
|
|
194
|
+
"""Log export origin data file."""
|
|
195
|
+
self.log_file('export_original_file', target_id, data_file_info, status, error)
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pydantic_core import PydanticCustomError
|
|
5
|
+
|
|
6
|
+
from synapse_sdk.clients.exceptions import ClientError
|
|
7
|
+
from synapse_sdk.i18n import gettext as _
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ExportTargetHandler(ABC):
|
|
11
|
+
"""
|
|
12
|
+
Abstract base class for handling export targets.
|
|
13
|
+
|
|
14
|
+
This class defines the blueprint for export target handlers, requiring the implementation
|
|
15
|
+
of methods to validate filters, retrieve results, and process collections of results.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
@abstractmethod
|
|
19
|
+
def validate_filter(self, value: dict, client: Any):
|
|
20
|
+
"""
|
|
21
|
+
Validate filter query params to request original data from api.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
value (dict): The filter criteria to validate.
|
|
25
|
+
client (Any): The client used to validate the filter.
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
PydanticCustomError: If the filter criteria are invalid.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
dict: The validated filter criteria.
|
|
32
|
+
"""
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def get_results(self, client: Any, filters: dict):
|
|
37
|
+
"""
|
|
38
|
+
Retrieve original data from target sources.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
client (Any): The client used to retrieve the results.
|
|
42
|
+
filters (dict): The filter criteria to apply.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
tuple: A tuple containing the results and the total count of results.
|
|
46
|
+
"""
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
@abstractmethod
|
|
50
|
+
def get_export_item(self, results):
|
|
51
|
+
"""
|
|
52
|
+
Providing elements to build export data.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
results (list): The results to process.
|
|
56
|
+
|
|
57
|
+
Yields:
|
|
58
|
+
generator: A generator that yields processed data items.
|
|
59
|
+
"""
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class AssignmentExportTargetHandler(ExportTargetHandler):
|
|
64
|
+
"""Handler for assignment target exports.
|
|
65
|
+
|
|
66
|
+
Implements ExportTargetHandler interface for assignment-specific
|
|
67
|
+
export operations including validation, data retrieval, and processing.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
def validate_filter(self, value: dict, client: Any):
|
|
71
|
+
if 'project' not in value:
|
|
72
|
+
raise PydanticCustomError('missing_field', _('Project is required for Assignment.'))
|
|
73
|
+
try:
|
|
74
|
+
client.list_assignments(params=value)
|
|
75
|
+
except ClientError:
|
|
76
|
+
raise PydanticCustomError('client_error', _('Unable to get Assignment.'))
|
|
77
|
+
return value
|
|
78
|
+
|
|
79
|
+
def get_results(self, client: Any, filters: dict):
|
|
80
|
+
return client.list_assignments(params=filters, list_all=True)
|
|
81
|
+
|
|
82
|
+
def get_export_item(self, results):
|
|
83
|
+
for result in results:
|
|
84
|
+
yield {
|
|
85
|
+
'data': result['data'],
|
|
86
|
+
'files': result['file'],
|
|
87
|
+
'id': result['id'],
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class GroundTruthExportTargetHandler(ExportTargetHandler):
|
|
92
|
+
"""Handler for ground truth target exports.
|
|
93
|
+
|
|
94
|
+
Implements ExportTargetHandler interface for ground truth dataset
|
|
95
|
+
export operations including validation, data retrieval, and processing.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
def validate_filter(self, value: dict, client: Any):
|
|
99
|
+
if 'ground_truth_dataset_version' not in value:
|
|
100
|
+
raise PydanticCustomError('missing_field', _('Ground Truth dataset version is required.'))
|
|
101
|
+
try:
|
|
102
|
+
client.get_ground_truth_version(value['ground_truth_dataset_version'])
|
|
103
|
+
except ClientError:
|
|
104
|
+
raise PydanticCustomError('client_error', _('Unable to get Ground Truth dataset version.'))
|
|
105
|
+
return value
|
|
106
|
+
|
|
107
|
+
def get_results(self, client: Any, filters: dict):
|
|
108
|
+
filters['ground_truth_dataset_versions'] = filters.pop('ground_truth_dataset_version')
|
|
109
|
+
return client.list_ground_truth_events(params=filters, list_all=True)
|
|
110
|
+
|
|
111
|
+
def get_export_item(self, results):
|
|
112
|
+
for result in results:
|
|
113
|
+
files_key = next(iter(result['data_unit']['files']))
|
|
114
|
+
yield {
|
|
115
|
+
'data': result['data'],
|
|
116
|
+
'files': result['data_unit']['files'][files_key],
|
|
117
|
+
'id': result['id'],
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class TaskExportTargetHandler(ExportTargetHandler):
|
|
122
|
+
"""Handler for task target exports.
|
|
123
|
+
|
|
124
|
+
Implements ExportTargetHandler interface for task-specific
|
|
125
|
+
export operations including validation, data retrieval, and processing.
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
def validate_filter(self, value: dict, client: Any):
|
|
129
|
+
if 'project' not in value:
|
|
130
|
+
raise PydanticCustomError('missing_field', _('Project is required for Task.'))
|
|
131
|
+
try:
|
|
132
|
+
client.list_tasks(params=value)
|
|
133
|
+
except ClientError:
|
|
134
|
+
raise PydanticCustomError('client_error', _('Unable to get Task.'))
|
|
135
|
+
return value
|
|
136
|
+
|
|
137
|
+
def get_results(self, client: Any, filters: dict):
|
|
138
|
+
filters['expand'] = ['data_unit', 'assignment', 'workshop']
|
|
139
|
+
return client.list_tasks(params=filters, list_all=True)
|
|
140
|
+
|
|
141
|
+
def get_export_item(self, results):
|
|
142
|
+
for result in results:
|
|
143
|
+
files_key = next(iter(result['data_unit']['files']))
|
|
144
|
+
yield {
|
|
145
|
+
'data': result['data'],
|
|
146
|
+
'files': result['data_unit']['files'][files_key],
|
|
147
|
+
'id': result['id'],
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class TargetHandlerFactory:
|
|
152
|
+
"""Factory class for creating export target handlers.
|
|
153
|
+
|
|
154
|
+
Provides a centralized way to create appropriate target handlers
|
|
155
|
+
based on the target type. Supports assignment, ground_truth, and task targets.
|
|
156
|
+
|
|
157
|
+
Example:
|
|
158
|
+
>>> handler = TargetHandlerFactory.get_handler('assignment')
|
|
159
|
+
>>> isinstance(handler, AssignmentExportTargetHandler)
|
|
160
|
+
True
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
@staticmethod
|
|
164
|
+
def get_handler(target: str) -> ExportTargetHandler:
|
|
165
|
+
"""Get the appropriate target handler for the given target type.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
target (str): The target type ('assignment', 'ground_truth', 'task')
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
ExportTargetHandler: The appropriate handler instance
|
|
172
|
+
|
|
173
|
+
Raises:
|
|
174
|
+
ValueError: If the target type is not supported
|
|
175
|
+
|
|
176
|
+
Example:
|
|
177
|
+
>>> handler = TargetHandlerFactory.get_handler('assignment')
|
|
178
|
+
>>> handler.validate_filter({'project': 123}, client)
|
|
179
|
+
"""
|
|
180
|
+
if target == 'assignment':
|
|
181
|
+
return AssignmentExportTargetHandler()
|
|
182
|
+
elif target == 'ground_truth':
|
|
183
|
+
return GroundTruthExportTargetHandler()
|
|
184
|
+
elif target == 'task':
|
|
185
|
+
return TaskExportTargetHandler()
|
|
186
|
+
else:
|
|
187
|
+
raise ValueError(f'Unknown target: {target}')
|
|
@@ -1,3 +1,21 @@
|
|
|
1
1
|
actions:
|
|
2
2
|
export:
|
|
3
|
-
entrypoint: plugin.export.
|
|
3
|
+
entrypoint: plugin.export.Exporter
|
|
4
|
+
# Filter to only export action specific annotation types (e.g., only export image annotations project)
|
|
5
|
+
# Supported types: image, video, audio, text, pcd, prompt
|
|
6
|
+
annotation_types:
|
|
7
|
+
- image
|
|
8
|
+
- video
|
|
9
|
+
- audio
|
|
10
|
+
- text
|
|
11
|
+
- pcd
|
|
12
|
+
- prompt
|
|
13
|
+
|
|
14
|
+
# Filter to only export specific data types (e.g., only export image data)
|
|
15
|
+
# Supported types: image, video, audio, text, pcd
|
|
16
|
+
data_types:
|
|
17
|
+
- image
|
|
18
|
+
- video
|
|
19
|
+
- audio
|
|
20
|
+
- text
|
|
21
|
+
- pcd
|