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.
Files changed (167) hide show
  1. synapse_sdk/__init__.py +24 -0
  2. synapse_sdk/cli/code_server.py +305 -33
  3. synapse_sdk/clients/agent/__init__.py +2 -1
  4. synapse_sdk/clients/agent/container.py +143 -0
  5. synapse_sdk/clients/agent/ray.py +296 -38
  6. synapse_sdk/clients/backend/annotation.py +1 -1
  7. synapse_sdk/clients/backend/core.py +31 -4
  8. synapse_sdk/clients/backend/data_collection.py +82 -7
  9. synapse_sdk/clients/backend/hitl.py +1 -1
  10. synapse_sdk/clients/backend/ml.py +1 -1
  11. synapse_sdk/clients/base.py +211 -61
  12. synapse_sdk/loggers.py +46 -0
  13. synapse_sdk/plugins/README.md +1340 -0
  14. synapse_sdk/plugins/categories/base.py +59 -9
  15. synapse_sdk/plugins/categories/export/actions/__init__.py +3 -0
  16. synapse_sdk/plugins/categories/export/actions/export/__init__.py +28 -0
  17. synapse_sdk/plugins/categories/export/actions/export/action.py +165 -0
  18. synapse_sdk/plugins/categories/export/actions/export/enums.py +113 -0
  19. synapse_sdk/plugins/categories/export/actions/export/exceptions.py +53 -0
  20. synapse_sdk/plugins/categories/export/actions/export/models.py +74 -0
  21. synapse_sdk/plugins/categories/export/actions/export/run.py +195 -0
  22. synapse_sdk/plugins/categories/export/actions/export/utils.py +187 -0
  23. synapse_sdk/plugins/categories/export/templates/config.yaml +19 -1
  24. synapse_sdk/plugins/categories/export/templates/plugin/__init__.py +390 -0
  25. synapse_sdk/plugins/categories/export/templates/plugin/export.py +153 -177
  26. synapse_sdk/plugins/categories/neural_net/actions/train.py +1130 -32
  27. synapse_sdk/plugins/categories/neural_net/actions/tune.py +157 -4
  28. synapse_sdk/plugins/categories/neural_net/templates/config.yaml +7 -4
  29. synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py +4 -0
  30. synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation/__init__.py +3 -0
  31. synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation/action.py +10 -0
  32. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/__init__.py +28 -0
  33. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/action.py +148 -0
  34. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/enums.py +269 -0
  35. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/exceptions.py +14 -0
  36. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/factory.py +76 -0
  37. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/models.py +100 -0
  38. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/orchestrator.py +248 -0
  39. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/run.py +64 -0
  40. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/__init__.py +17 -0
  41. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/annotation.py +265 -0
  42. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/base.py +170 -0
  43. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/extraction.py +83 -0
  44. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/metrics.py +92 -0
  45. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/preprocessor.py +243 -0
  46. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/validation.py +143 -0
  47. synapse_sdk/plugins/categories/upload/actions/upload/__init__.py +19 -0
  48. synapse_sdk/plugins/categories/upload/actions/upload/action.py +236 -0
  49. synapse_sdk/plugins/categories/upload/actions/upload/context.py +185 -0
  50. synapse_sdk/plugins/categories/upload/actions/upload/enums.py +493 -0
  51. synapse_sdk/plugins/categories/upload/actions/upload/exceptions.py +36 -0
  52. synapse_sdk/plugins/categories/upload/actions/upload/factory.py +138 -0
  53. synapse_sdk/plugins/categories/upload/actions/upload/models.py +214 -0
  54. synapse_sdk/plugins/categories/upload/actions/upload/orchestrator.py +183 -0
  55. synapse_sdk/plugins/categories/upload/actions/upload/registry.py +113 -0
  56. synapse_sdk/plugins/categories/upload/actions/upload/run.py +179 -0
  57. synapse_sdk/plugins/categories/upload/actions/upload/steps/__init__.py +1 -0
  58. synapse_sdk/plugins/categories/upload/actions/upload/steps/base.py +107 -0
  59. synapse_sdk/plugins/categories/upload/actions/upload/steps/cleanup.py +62 -0
  60. synapse_sdk/plugins/categories/upload/actions/upload/steps/collection.py +63 -0
  61. synapse_sdk/plugins/categories/upload/actions/upload/steps/generate.py +91 -0
  62. synapse_sdk/plugins/categories/upload/actions/upload/steps/initialize.py +82 -0
  63. synapse_sdk/plugins/categories/upload/actions/upload/steps/metadata.py +235 -0
  64. synapse_sdk/plugins/categories/upload/actions/upload/steps/organize.py +201 -0
  65. synapse_sdk/plugins/categories/upload/actions/upload/steps/upload.py +104 -0
  66. synapse_sdk/plugins/categories/upload/actions/upload/steps/validate.py +71 -0
  67. synapse_sdk/plugins/categories/upload/actions/upload/strategies/__init__.py +1 -0
  68. synapse_sdk/plugins/categories/upload/actions/upload/strategies/base.py +82 -0
  69. synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/__init__.py +1 -0
  70. synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/batch.py +39 -0
  71. synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/single.py +29 -0
  72. synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/__init__.py +1 -0
  73. synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/flat.py +300 -0
  74. synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/recursive.py +287 -0
  75. synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/__init__.py +1 -0
  76. synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/excel.py +174 -0
  77. synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/none.py +16 -0
  78. synapse_sdk/plugins/categories/upload/actions/upload/strategies/upload/__init__.py +1 -0
  79. synapse_sdk/plugins/categories/upload/actions/upload/strategies/upload/sync.py +84 -0
  80. synapse_sdk/plugins/categories/upload/actions/upload/strategies/validation/__init__.py +1 -0
  81. synapse_sdk/plugins/categories/upload/actions/upload/strategies/validation/default.py +60 -0
  82. synapse_sdk/plugins/categories/upload/actions/upload/utils.py +250 -0
  83. synapse_sdk/plugins/categories/upload/templates/README.md +470 -0
  84. synapse_sdk/plugins/categories/upload/templates/config.yaml +28 -2
  85. synapse_sdk/plugins/categories/upload/templates/plugin/__init__.py +310 -0
  86. synapse_sdk/plugins/categories/upload/templates/plugin/upload.py +82 -20
  87. synapse_sdk/plugins/models.py +111 -9
  88. synapse_sdk/plugins/templates/plugin-config-schema.json +7 -0
  89. synapse_sdk/plugins/templates/schema.json +7 -0
  90. synapse_sdk/plugins/utils/__init__.py +3 -0
  91. synapse_sdk/plugins/utils/ray_gcs.py +66 -0
  92. synapse_sdk/shared/__init__.py +25 -0
  93. synapse_sdk/utils/converters/dm/__init__.py +42 -41
  94. synapse_sdk/utils/converters/dm/base.py +137 -0
  95. synapse_sdk/utils/converters/dm/from_v1.py +208 -562
  96. synapse_sdk/utils/converters/dm/to_v1.py +258 -304
  97. synapse_sdk/utils/converters/dm/tools/__init__.py +214 -0
  98. synapse_sdk/utils/converters/dm/tools/answer.py +95 -0
  99. synapse_sdk/utils/converters/dm/tools/bounding_box.py +132 -0
  100. synapse_sdk/utils/converters/dm/tools/bounding_box_3d.py +121 -0
  101. synapse_sdk/utils/converters/dm/tools/classification.py +75 -0
  102. synapse_sdk/utils/converters/dm/tools/keypoint.py +117 -0
  103. synapse_sdk/utils/converters/dm/tools/named_entity.py +111 -0
  104. synapse_sdk/utils/converters/dm/tools/polygon.py +122 -0
  105. synapse_sdk/utils/converters/dm/tools/polyline.py +124 -0
  106. synapse_sdk/utils/converters/dm/tools/prompt.py +94 -0
  107. synapse_sdk/utils/converters/dm/tools/relation.py +86 -0
  108. synapse_sdk/utils/converters/dm/tools/segmentation.py +141 -0
  109. synapse_sdk/utils/converters/dm/tools/segmentation_3d.py +83 -0
  110. synapse_sdk/utils/converters/dm/types.py +168 -0
  111. synapse_sdk/utils/converters/dm/utils.py +162 -0
  112. synapse_sdk/utils/converters/dm_legacy/__init__.py +56 -0
  113. synapse_sdk/utils/converters/dm_legacy/from_v1.py +627 -0
  114. synapse_sdk/utils/converters/dm_legacy/to_v1.py +367 -0
  115. synapse_sdk/utils/file/__init__.py +58 -0
  116. synapse_sdk/utils/file/archive.py +32 -0
  117. synapse_sdk/utils/file/checksum.py +56 -0
  118. synapse_sdk/utils/file/chunking.py +31 -0
  119. synapse_sdk/utils/file/download.py +385 -0
  120. synapse_sdk/utils/file/encoding.py +40 -0
  121. synapse_sdk/utils/file/io.py +22 -0
  122. synapse_sdk/utils/file/upload.py +165 -0
  123. synapse_sdk/utils/file/video/__init__.py +29 -0
  124. synapse_sdk/utils/file/video/transcode.py +307 -0
  125. synapse_sdk/utils/{file.py → file.py.backup} +77 -0
  126. synapse_sdk/utils/network.py +272 -0
  127. synapse_sdk/utils/storage/__init__.py +6 -2
  128. synapse_sdk/utils/storage/providers/file_system.py +6 -0
  129. {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/METADATA +19 -2
  130. {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/RECORD +134 -74
  131. synapse_sdk/devtools/docs/.gitignore +0 -20
  132. synapse_sdk/devtools/docs/README.md +0 -41
  133. synapse_sdk/devtools/docs/blog/2019-05-28-first-blog-post.md +0 -12
  134. synapse_sdk/devtools/docs/blog/2019-05-29-long-blog-post.md +0 -44
  135. synapse_sdk/devtools/docs/blog/2021-08-01-mdx-blog-post.mdx +0 -24
  136. synapse_sdk/devtools/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
  137. synapse_sdk/devtools/docs/blog/2021-08-26-welcome/index.md +0 -29
  138. synapse_sdk/devtools/docs/blog/authors.yml +0 -25
  139. synapse_sdk/devtools/docs/blog/tags.yml +0 -19
  140. synapse_sdk/devtools/docs/docusaurus.config.ts +0 -138
  141. synapse_sdk/devtools/docs/package-lock.json +0 -17455
  142. synapse_sdk/devtools/docs/package.json +0 -47
  143. synapse_sdk/devtools/docs/sidebars.ts +0 -44
  144. synapse_sdk/devtools/docs/src/components/HomepageFeatures/index.tsx +0 -71
  145. synapse_sdk/devtools/docs/src/components/HomepageFeatures/styles.module.css +0 -11
  146. synapse_sdk/devtools/docs/src/css/custom.css +0 -30
  147. synapse_sdk/devtools/docs/src/pages/index.module.css +0 -23
  148. synapse_sdk/devtools/docs/src/pages/index.tsx +0 -21
  149. synapse_sdk/devtools/docs/src/pages/markdown-page.md +0 -7
  150. synapse_sdk/devtools/docs/static/.nojekyll +0 -0
  151. synapse_sdk/devtools/docs/static/img/docusaurus-social-card.jpg +0 -0
  152. synapse_sdk/devtools/docs/static/img/docusaurus.png +0 -0
  153. synapse_sdk/devtools/docs/static/img/favicon.ico +0 -0
  154. synapse_sdk/devtools/docs/static/img/logo.png +0 -0
  155. synapse_sdk/devtools/docs/static/img/undraw_docusaurus_mountain.svg +0 -171
  156. synapse_sdk/devtools/docs/static/img/undraw_docusaurus_react.svg +0 -170
  157. synapse_sdk/devtools/docs/static/img/undraw_docusaurus_tree.svg +0 -40
  158. synapse_sdk/devtools/docs/tsconfig.json +0 -8
  159. synapse_sdk/plugins/categories/export/actions/export.py +0 -346
  160. synapse_sdk/plugins/categories/export/enums.py +0 -7
  161. synapse_sdk/plugins/categories/neural_net/actions/gradio.py +0 -151
  162. synapse_sdk/plugins/categories/pre_annotation/actions/to_task.py +0 -943
  163. synapse_sdk/plugins/categories/upload/actions/upload.py +0 -954
  164. {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/WHEEL +0 -0
  165. {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/entry_points.txt +0 -0
  166. {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/licenses/LICENSE +0 -0
  167. {synapse_sdk-1.0.0b5.dist-info → synapse_sdk-2025.12.3.dist-info}/top_level.txt +0 -0
@@ -1,346 +0,0 @@
1
- import json
2
- from abc import ABC, abstractmethod
3
- from datetime import datetime
4
- from typing import Annotated, Any, Literal
5
-
6
- from pydantic import AfterValidator, BaseModel, field_validator
7
- from pydantic_core import PydanticCustomError
8
-
9
- from synapse_sdk.clients.exceptions import ClientError
10
- from synapse_sdk.i18n import gettext as _
11
- from synapse_sdk.plugins.categories.base import Action
12
- from synapse_sdk.plugins.categories.decorators import register_action
13
- from synapse_sdk.plugins.categories.export.enums import ExportStatus
14
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
15
- from synapse_sdk.plugins.models import Run
16
- from synapse_sdk.utils.pydantic.validators import non_blank
17
- from synapse_sdk.utils.storage import get_pathlib
18
-
19
-
20
- class ExportRun(Run):
21
- class DataFileLog(BaseModel):
22
- """Data file log model."""
23
-
24
- target_id: int
25
- data_file_info: str | None
26
- status: ExportStatus
27
- error: str | None = None
28
- created: str
29
-
30
- class MetricsRecord(BaseModel):
31
- """Metrics record model."""
32
-
33
- stand_by: int
34
- failed: int
35
- success: int
36
-
37
- def log_file(
38
- self, log_type: str, target_id: int, data_file_info: dict, status: ExportStatus, error: str | None = None
39
- ):
40
- """Log export file information.
41
-
42
- Args:
43
- log_type (str): The type of log ('export_data_file' or 'export_original_file' or 'etc').
44
- target_id (int): The ID of the data file.
45
- data_file_info (dict): The JSON info of the data file.
46
- status (ExportStatus): The status of the data file.
47
- error (str | None): The error message, if any.
48
- """
49
- now = datetime.now().isoformat()
50
- self.log(
51
- log_type,
52
- self.DataFileLog(
53
- target_id=target_id,
54
- data_file_info=json.dumps(data_file_info),
55
- status=status.value,
56
- error=error,
57
- created=now,
58
- ).model_dump(),
59
- )
60
-
61
- def log_metrics(self, record: MetricsRecord, category: str):
62
- """Log export metrics.
63
-
64
- Args:
65
- record (MetricsRecord): The metrics record to log.
66
- category (str): The category of the metrics.
67
- """
68
- record = self.MetricsRecord.model_validate(record)
69
- self.set_metrics(value=record.dict(), category=category)
70
-
71
- def export_log_json_file(
72
- self,
73
- target_id: int,
74
- data_file_info: dict,
75
- status: ExportStatus = ExportStatus.STAND_BY,
76
- error: str | None = None,
77
- ):
78
- """Log export json data file."""
79
- self.log_file('export_data_file', target_id, data_file_info, status, error)
80
-
81
- def export_log_original_file(
82
- self,
83
- target_id: int,
84
- data_file_info: dict,
85
- status: ExportStatus = ExportStatus.STAND_BY,
86
- error: str | None = None,
87
- ):
88
- """Log export origin data file."""
89
- self.log_file('export_original_file', target_id, data_file_info, status, error)
90
-
91
- def export_log_etc_file(
92
- self,
93
- target_id: int,
94
- data_file_info: dict,
95
- status: ExportStatus = ExportStatus.STAND_BY,
96
- error: str | None = None,
97
- ):
98
- """Log export etc file."""
99
- self.log_file('etc', target_id, data_file_info, status, error)
100
-
101
-
102
- class ExportTargetHandler(ABC):
103
- """
104
- Abstract base class for handling export targets.
105
-
106
- This class defines the blueprint for export target handlers, requiring the implementation
107
- of methods to validate filters, retrieve results, and process collections of results.
108
- """
109
-
110
- @abstractmethod
111
- def validate_filter(self, value: dict, client: Any):
112
- """
113
- Validate filter query params to request original data from api.
114
-
115
- Args:
116
- value (dict): The filter criteria to validate.
117
- client (Any): The client used to validate the filter.
118
-
119
- Raises:
120
- PydanticCustomError: If the filter criteria are invalid.
121
-
122
- Returns:
123
- dict: The validated filter criteria.
124
- """
125
- pass
126
-
127
- @abstractmethod
128
- def get_results(self, client: Any, filters: dict):
129
- """
130
- Retrieve original data from target sources.
131
-
132
- Args:
133
- client (Any): The client used to retrieve the results.
134
- filters (dict): The filter criteria to apply.
135
-
136
- Returns:
137
- tuple: A tuple containing the results and the total count of results.
138
- """
139
- pass
140
-
141
- @abstractmethod
142
- def get_export_item(self, results):
143
- """
144
- Providing elements to build export data.
145
-
146
- Args:
147
- results (list): The results to process.
148
-
149
- Yields:
150
- generator: A generator that yields processed data items.
151
- """
152
- pass
153
-
154
-
155
- class AssignmentExportTargetHandler(ExportTargetHandler):
156
- def validate_filter(self, value: dict, client: Any):
157
- if 'project' not in value:
158
- raise PydanticCustomError('missing_field', _('Project is required for Assignment.'))
159
- try:
160
- client.list_assignments(params=value)
161
- except ClientError:
162
- raise PydanticCustomError('client_error', _('Unable to get Assignment.'))
163
- return value
164
-
165
- def get_results(self, client: Any, filters: dict):
166
- return client.list_assignments(params=filters, list_all=True)
167
-
168
- def get_export_item(self, results):
169
- for result in results:
170
- yield {
171
- 'data': result['data'],
172
- 'files': result['file'],
173
- 'id': result['id'],
174
- }
175
-
176
-
177
- class GroundTruthExportTargetHandler(ExportTargetHandler):
178
- def validate_filter(self, value: dict, client: Any):
179
- if 'ground_truth_dataset_version' not in value:
180
- raise PydanticCustomError('missing_field', _('Ground Truth dataset version is required.'))
181
- try:
182
- client.get_ground_truth_version(value['ground_truth_dataset_version'])
183
- except ClientError:
184
- raise PydanticCustomError('client_error', _('Unable to get Ground Truth dataset version.'))
185
- return value
186
-
187
- def get_results(self, client: Any, filters: dict):
188
- filters['ground_truth_dataset_versions'] = filters.pop('ground_truth_dataset_version')
189
- return client.list_ground_truth_events(params=filters, list_all=True)
190
-
191
- def get_export_item(self, results):
192
- for result in results:
193
- files_key = next(iter(result['data_unit']['files']))
194
- yield {
195
- 'data': result['data'],
196
- 'files': result['data_unit']['files'][files_key],
197
- 'id': result['ground_truth'],
198
- }
199
-
200
-
201
- class TaskExportTargetHandler(ExportTargetHandler):
202
- def validate_filter(self, value: dict, client: Any):
203
- if 'project' not in value:
204
- raise PydanticCustomError('missing_field', _('Project is required for Task.'))
205
- try:
206
- client.list_tasks(params=value)
207
- except ClientError:
208
- raise PydanticCustomError('client_error', _('Unable to get Task.'))
209
- return value
210
-
211
- def get_results(self, client: Any, filters: dict):
212
- filters['expand'] = 'data_unit'
213
- return client.list_tasks(params=filters, list_all=True)
214
-
215
- def get_export_item(self, results):
216
- for result in results:
217
- files_key = next(iter(result['data_unit']['files']))
218
- yield {
219
- 'data': result['data'],
220
- 'files': result['data_unit']['files'][files_key],
221
- 'id': result['id'],
222
- }
223
-
224
-
225
- class TargetHandlerFactory:
226
- @staticmethod
227
- def get_handler(target: str) -> ExportTargetHandler:
228
- if target == 'assignment':
229
- return AssignmentExportTargetHandler()
230
- elif target == 'ground_truth':
231
- return GroundTruthExportTargetHandler()
232
- elif target == 'task':
233
- return TaskExportTargetHandler()
234
- else:
235
- raise ValueError(f'Unknown target: {target}')
236
-
237
-
238
- class ExportParams(BaseModel):
239
- """
240
- Parameters for the export action.
241
-
242
- Attributes:
243
- name (str): The name of the action.
244
- description (str | None): The description of the action.
245
- storage (int): The storage ID to save the exported data.
246
- save_original_file (bool): Whether to save the original file.
247
- path (str): The path to save the exported data.
248
- target (str): The target source to export data from. (ex. ground_truth, assignment, task)
249
- filter (dict): The filter criteria to apply.
250
- """
251
-
252
- name: Annotated[str, AfterValidator(non_blank)]
253
- description: str | None = None
254
- storage: int
255
- save_original_file: bool = True
256
- path: str
257
- target: Literal['assignment', 'ground_truth', 'task']
258
- filter: dict
259
-
260
- @field_validator('storage')
261
- @staticmethod
262
- def check_storage_exists(value, info):
263
- action = info.context['action']
264
- client = action.client
265
- try:
266
- client.get_storage(value)
267
- except ClientError:
268
- raise PydanticCustomError('client_error', _('Unable to get storage from Synapse backend.'))
269
- return value
270
-
271
- @field_validator('filter')
272
- @staticmethod
273
- def check_filter_by_target(value, info):
274
- action = info.context['action']
275
- client = action.client
276
- target = action.params['target']
277
- handler = TargetHandlerFactory.get_handler(target)
278
- return handler.validate_filter(value, client)
279
-
280
-
281
- @register_action
282
- class ExportAction(Action):
283
- name = 'export'
284
- category = PluginCategory.EXPORT
285
- method = RunMethod.JOB
286
- params_model = ExportParams
287
- run_class = ExportRun
288
- progress_categories = {
289
- 'dataset_conversion': {
290
- 'proportion': 100,
291
- }
292
- }
293
- metrics_categories = {
294
- 'data_file': {
295
- 'stand_by': 0,
296
- 'failed': 0,
297
- 'success': 0,
298
- },
299
- 'original_file': {
300
- 'stand_by': 0,
301
- 'failed': 0,
302
- 'success': 0,
303
- },
304
- 'etc': {
305
- 'stand_by': 0,
306
- 'failed': 0,
307
- 'success': 0,
308
- },
309
- }
310
-
311
- def get_filtered_results(self, filters, handler):
312
- """Get filtered target results."""
313
- try:
314
- result_list = handler.get_results(self.client, filters)
315
- results = result_list[0]
316
- count = result_list[1]
317
- except ClientError:
318
- raise PydanticCustomError('client_error', _('Unable to get Ground Truth dataset.'))
319
- return results, count
320
-
321
- def start(self):
322
- filters = {'expand': 'data', **self.params['filter']}
323
- target = self.params['target']
324
- handler = TargetHandlerFactory.get_handler(target)
325
-
326
- self.params['results'], self.params['count'] = self.get_filtered_results(filters, handler)
327
- export_items = handler.get_export_item(self.params['results'])
328
-
329
- # For the 'ground_truth' target, retrieve project information from the first result and add configuration
330
- if target == 'ground_truth':
331
- try:
332
- first_result = next(iter(self.params['results']))
333
- project_pk = first_result['project']
334
- project_info = self.client.get_project(project_pk)
335
- self.params['configuration'] = project_info.get('configuration', {})
336
- except StopIteration:
337
- self.params['configuration'] = {}
338
- # For the 'assignment' and 'task' targets, retrieve the project from the filter as before
339
- elif target in ['assignment', 'task'] and 'project' in self.params['filter']:
340
- project_pk = self.params['filter']['project']
341
- project_info = self.client.get_project(project_pk)
342
- self.params['configuration'] = project_info.get('configuration', {})
343
-
344
- storage = self.client.get_storage(self.params['storage'])
345
- pathlib_cwd = get_pathlib(storage, self.params['path'])
346
- return self.entrypoint(self.run, export_items, pathlib_cwd, **self.params)
@@ -1,7 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class ExportStatus(str, Enum):
5
- SUCCESS = 'success'
6
- FAILED = 'failed'
7
- STAND_BY = 'stand_by'
@@ -1,151 +0,0 @@
1
- import contextlib
2
- import subprocess
3
- from functools import cached_property
4
- from pathlib import Path
5
-
6
- from synapse_sdk.plugins.categories.base import Action
7
- from synapse_sdk.plugins.categories.decorators import register_action
8
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
9
- from synapse_sdk.utils.network import get_available_ports_host
10
-
11
-
12
- @register_action
13
- class GradioAction(Action):
14
- name = 'gradio'
15
- category = PluginCategory.NEURAL_NET
16
- method = RunMethod.JOB
17
-
18
- @property
19
- def working_directory(self):
20
- dir = Path.cwd() / self.config['directory'].replace('.', '/')
21
- assert dir.is_dir(), f'Working directory {dir} does not exist.'
22
- return dir
23
-
24
- @property
25
- def requirements_file(self):
26
- requirements_file = self.working_directory / 'requirements.txt'
27
- if requirements_file.exists():
28
- return requirements_file
29
-
30
- @property
31
- def tag(self):
32
- _tag = f'{self.plugin_release.code}-{self.plugin_release.checksum}'
33
- return _tag.replace('@', '-')
34
-
35
- @cached_property
36
- def deploy_port(self):
37
- return get_available_ports_host()
38
-
39
- def deploy(self):
40
- self.run.log('deploy', 'Start deploying')
41
-
42
- try:
43
- # Write Dockerfile and requirements.txt
44
- path_dockerfile = self.write_dockerfile_template()
45
- self.check_requirements()
46
-
47
- # Build docker image
48
- self.build_docker_image(path_dockerfile)
49
-
50
- # Run docker image
51
- self.run_docker_image()
52
- except Exception as e:
53
- self.run.log('deploy', f'Error: {e}')
54
- raise e
55
-
56
- def start(self):
57
- self.deploy()
58
- return {'endpoint': f'http://localhost:{self.deploy_port}'}
59
-
60
- def write_dockerfile_template(self):
61
- dockerfile_path = self.working_directory / 'Dockerfile'
62
-
63
- with open(dockerfile_path, 'w') as f:
64
- f.write("""FROM python:3.12-slim
65
- WORKDIR /home/user/app
66
-
67
- RUN pip install --no-cache-dir pip -U && \\
68
- pip install --no-cache-dir uvicorn
69
-
70
- RUN apt-get update && \\
71
- apt-get install -y git nmap ffmpeg libsm6 libxext6 libgl1-mesa-glx && \\
72
- rm -rf /var/lib/apt/lists/*
73
-
74
- RUN apt-get update && \\
75
- apt-get install -y curl && \\
76
- curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \\
77
- apt-get install -y nodejs && \\
78
- rm -rf /var/lib/apt/lists/* && \\
79
- apt-get clean
80
-
81
- COPY requirements_default.txt .
82
-
83
- COPY requirements.txt .
84
-
85
- RUN pip install --no-cache-dir -r requirements_default.txt
86
-
87
- RUN pip install --no-cache-dir -U -r requirements.txt
88
-
89
- COPY . .
90
-
91
- EXPOSE 7860
92
-
93
- CMD ["python", "app.py"]
94
- """)
95
- return dockerfile_path
96
-
97
- def check_requirements(self):
98
- default_packages = ['gradio', 'synapse-sdk', 'python-nmap']
99
- with open(self.working_directory / 'requirements_default.txt', 'a') as f:
100
- f.write('\n' + '\n'.join(default_packages))
101
-
102
- if self.requirements_file is None:
103
- with open(self.working_directory / 'requirements.txt', 'a'):
104
- pass
105
-
106
- def build_docker_image(self, path_dockerfile):
107
- self.run.log('deploy', 'Start building docker image')
108
- result = subprocess.run(
109
- ['docker', 'build', '-t', self.tag, '-f', str(path_dockerfile), '.'],
110
- cwd=self.working_directory,
111
- check=True,
112
- )
113
- print(result)
114
-
115
- def run_docker_image(self):
116
- self.run.log('deploy', 'Start running docker image')
117
-
118
- # Check for existing container
119
- self.run.log('deploy', 'Check for existing container')
120
- with contextlib.suppress(subprocess.CalledProcessError):
121
- subprocess.run(['docker', 'stop', self.tag], check=True)
122
- subprocess.run(['docker', 'rm', self.tag], check=True)
123
-
124
- # Run docker image
125
- command = [
126
- 'docker',
127
- 'run',
128
- '-d',
129
- '--name',
130
- self.tag,
131
- '-p',
132
- f'{self.deploy_port}:7860',
133
- '-p',
134
- '8991-8999:8991-8999',
135
- '--add-host',
136
- 'host.docker.internal:host-gateway',
137
- '-e',
138
- 'GRADIO_SERVER_NAME=0.0.0.0',
139
- ]
140
-
141
- # extend synapse env vars
142
- for key, value in self.envs.items():
143
- command.extend(['-e', f'{key}={value}'])
144
- command.append(self.tag)
145
-
146
- self.run.log('deploy', f'Starting docker container with command: {" ".join(command)}')
147
-
148
- subprocess.run(
149
- command,
150
- check=True,
151
- )