synapse-sdk 1.0.0a13__py3-none-any.whl → 2025.11.7__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.

Files changed (339) hide show
  1. synapse_sdk/__init__.py +24 -0
  2. synapse_sdk/cli/__init__.py +310 -5
  3. synapse_sdk/cli/alias/__init__.py +22 -0
  4. synapse_sdk/cli/alias/create.py +36 -0
  5. synapse_sdk/cli/alias/dataclass.py +31 -0
  6. synapse_sdk/cli/alias/default.py +16 -0
  7. synapse_sdk/cli/alias/delete.py +15 -0
  8. synapse_sdk/cli/alias/list.py +19 -0
  9. synapse_sdk/cli/alias/read.py +15 -0
  10. synapse_sdk/cli/alias/update.py +17 -0
  11. synapse_sdk/cli/alias/utils.py +61 -0
  12. synapse_sdk/cli/code_server.py +687 -0
  13. synapse_sdk/cli/config.py +440 -0
  14. synapse_sdk/cli/devtools.py +90 -0
  15. synapse_sdk/cli/plugin/__init__.py +33 -0
  16. synapse_sdk/cli/{create_plugin.py → plugin/create.py} +2 -2
  17. synapse_sdk/cli/plugin/publish.py +45 -0
  18. synapse_sdk/{plugins/cli → cli/plugin}/run.py +12 -5
  19. synapse_sdk/clients/agent/__init__.py +9 -3
  20. synapse_sdk/clients/agent/container.py +133 -0
  21. synapse_sdk/clients/agent/core.py +19 -0
  22. synapse_sdk/clients/agent/ray.py +298 -9
  23. synapse_sdk/clients/backend/__init__.py +41 -12
  24. synapse_sdk/clients/backend/annotation.py +13 -5
  25. synapse_sdk/clients/backend/core.py +59 -0
  26. synapse_sdk/clients/backend/data_collection.py +186 -0
  27. synapse_sdk/clients/backend/hitl.py +17 -0
  28. synapse_sdk/clients/backend/integration.py +19 -4
  29. synapse_sdk/clients/backend/ml.py +10 -7
  30. synapse_sdk/clients/backend/models.py +78 -0
  31. synapse_sdk/clients/base.py +381 -34
  32. synapse_sdk/clients/ray/serve.py +2 -0
  33. synapse_sdk/clients/validators/collections.py +31 -0
  34. synapse_sdk/devtools/config.py +94 -0
  35. synapse_sdk/devtools/docs/.gitignore +20 -0
  36. synapse_sdk/devtools/docs/README.md +41 -0
  37. synapse_sdk/devtools/docs/blog/2019-05-28-first-blog-post.md +12 -0
  38. synapse_sdk/devtools/docs/blog/2019-05-29-long-blog-post.md +44 -0
  39. synapse_sdk/devtools/docs/blog/2021-08-01-mdx-blog-post.mdx +24 -0
  40. synapse_sdk/devtools/docs/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
  41. synapse_sdk/devtools/docs/blog/2021-08-26-welcome/index.md +29 -0
  42. synapse_sdk/devtools/docs/blog/authors.yml +25 -0
  43. synapse_sdk/devtools/docs/blog/tags.yml +19 -0
  44. synapse_sdk/devtools/docs/docs/api/clients/agent.md +43 -0
  45. synapse_sdk/devtools/docs/docs/api/clients/annotation-mixin.md +378 -0
  46. synapse_sdk/devtools/docs/docs/api/clients/backend.md +420 -0
  47. synapse_sdk/devtools/docs/docs/api/clients/base.md +257 -0
  48. synapse_sdk/devtools/docs/docs/api/clients/core-mixin.md +477 -0
  49. synapse_sdk/devtools/docs/docs/api/clients/data-collection-mixin.md +422 -0
  50. synapse_sdk/devtools/docs/docs/api/clients/hitl-mixin.md +554 -0
  51. synapse_sdk/devtools/docs/docs/api/clients/index.md +391 -0
  52. synapse_sdk/devtools/docs/docs/api/clients/integration-mixin.md +571 -0
  53. synapse_sdk/devtools/docs/docs/api/clients/ml-mixin.md +578 -0
  54. synapse_sdk/devtools/docs/docs/api/clients/ray.md +342 -0
  55. synapse_sdk/devtools/docs/docs/api/index.md +52 -0
  56. synapse_sdk/devtools/docs/docs/api/plugins/categories.md +43 -0
  57. synapse_sdk/devtools/docs/docs/api/plugins/models.md +114 -0
  58. synapse_sdk/devtools/docs/docs/api/plugins/utils.md +328 -0
  59. synapse_sdk/devtools/docs/docs/categories.md +0 -0
  60. synapse_sdk/devtools/docs/docs/cli-usage.md +280 -0
  61. synapse_sdk/devtools/docs/docs/concepts/index.md +38 -0
  62. synapse_sdk/devtools/docs/docs/configuration.md +83 -0
  63. synapse_sdk/devtools/docs/docs/contributing.md +306 -0
  64. synapse_sdk/devtools/docs/docs/examples/index.md +29 -0
  65. synapse_sdk/devtools/docs/docs/faq.md +179 -0
  66. synapse_sdk/devtools/docs/docs/features/converters/index.md +455 -0
  67. synapse_sdk/devtools/docs/docs/features/index.md +24 -0
  68. synapse_sdk/devtools/docs/docs/features/utils/file.md +415 -0
  69. synapse_sdk/devtools/docs/docs/features/utils/network.md +378 -0
  70. synapse_sdk/devtools/docs/docs/features/utils/storage.md +57 -0
  71. synapse_sdk/devtools/docs/docs/features/utils/types.md +51 -0
  72. synapse_sdk/devtools/docs/docs/installation.md +94 -0
  73. synapse_sdk/devtools/docs/docs/introduction.md +47 -0
  74. synapse_sdk/devtools/docs/docs/plugins/categories/neural-net-plugins/train-action-overview.md +814 -0
  75. synapse_sdk/devtools/docs/docs/plugins/categories/pre-annotation-plugins/pre-annotation-plugin-overview.md +198 -0
  76. synapse_sdk/devtools/docs/docs/plugins/categories/pre-annotation-plugins/to-task-action-development.md +1645 -0
  77. synapse_sdk/devtools/docs/docs/plugins/categories/pre-annotation-plugins/to-task-overview.md +717 -0
  78. synapse_sdk/devtools/docs/docs/plugins/categories/pre-annotation-plugins/to-task-template-development.md +1380 -0
  79. synapse_sdk/devtools/docs/docs/plugins/categories/upload-plugins/upload-plugin-action.md +948 -0
  80. synapse_sdk/devtools/docs/docs/plugins/categories/upload-plugins/upload-plugin-overview.md +544 -0
  81. synapse_sdk/devtools/docs/docs/plugins/categories/upload-plugins/upload-plugin-template.md +766 -0
  82. synapse_sdk/devtools/docs/docs/plugins/export-plugins.md +1092 -0
  83. synapse_sdk/devtools/docs/docs/plugins/plugins.md +852 -0
  84. synapse_sdk/devtools/docs/docs/quickstart.md +78 -0
  85. synapse_sdk/devtools/docs/docs/troubleshooting.md +519 -0
  86. synapse_sdk/devtools/docs/docs/tutorial-basics/_category_.json +8 -0
  87. synapse_sdk/devtools/docs/docs/tutorial-basics/congratulations.md +23 -0
  88. synapse_sdk/devtools/docs/docs/tutorial-basics/create-a-blog-post.md +34 -0
  89. synapse_sdk/devtools/docs/docs/tutorial-basics/create-a-document.md +57 -0
  90. synapse_sdk/devtools/docs/docs/tutorial-basics/create-a-page.md +43 -0
  91. synapse_sdk/devtools/docs/docs/tutorial-basics/deploy-your-site.md +31 -0
  92. synapse_sdk/devtools/docs/docs/tutorial-basics/markdown-features.mdx +152 -0
  93. synapse_sdk/devtools/docs/docs/tutorial-extras/_category_.json +7 -0
  94. synapse_sdk/devtools/docs/docs/tutorial-extras/img/docsVersionDropdown.png +0 -0
  95. synapse_sdk/devtools/docs/docs/tutorial-extras/img/localeDropdown.png +0 -0
  96. synapse_sdk/devtools/docs/docs/tutorial-extras/manage-docs-versions.md +55 -0
  97. synapse_sdk/devtools/docs/docs/tutorial-extras/translate-your-site.md +88 -0
  98. synapse_sdk/devtools/docs/docusaurus.config.ts +148 -0
  99. synapse_sdk/devtools/docs/i18n/ko/code.json +325 -0
  100. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/agent.md +43 -0
  101. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/annotation-mixin.md +289 -0
  102. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/backend.md +420 -0
  103. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/base.md +257 -0
  104. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/core-mixin.md +417 -0
  105. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/data-collection-mixin.md +356 -0
  106. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/hitl-mixin.md +192 -0
  107. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/index.md +391 -0
  108. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/integration-mixin.md +479 -0
  109. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/ml-mixin.md +284 -0
  110. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/ray.md +342 -0
  111. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/index.md +52 -0
  112. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/plugins/models.md +114 -0
  113. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/categories.md +0 -0
  114. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/cli-usage.md +280 -0
  115. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/concepts/index.md +38 -0
  116. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/configuration.md +83 -0
  117. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/contributing.md +306 -0
  118. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/examples/index.md +29 -0
  119. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/faq.md +179 -0
  120. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/converters/index.md +30 -0
  121. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/index.md +24 -0
  122. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/utils/file.md +415 -0
  123. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/utils/network.md +378 -0
  124. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/utils/storage.md +60 -0
  125. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/utils/types.md +51 -0
  126. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/installation.md +94 -0
  127. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/introduction.md +47 -0
  128. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/neural-net-plugins/train-action-overview.md +815 -0
  129. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/pre-annotation-plugins/pre-annotation-plugin-overview.md +198 -0
  130. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/pre-annotation-plugins/to-task-action-development.md +1645 -0
  131. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/pre-annotation-plugins/to-task-overview.md +717 -0
  132. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/pre-annotation-plugins/to-task-template-development.md +1380 -0
  133. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/upload-plugins/upload-plugin-action.md +948 -0
  134. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/upload-plugins/upload-plugin-overview.md +544 -0
  135. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/categories/upload-plugins/upload-plugin-template.md +766 -0
  136. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/export-plugins.md +1092 -0
  137. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/plugins.md +117 -0
  138. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/quickstart.md +78 -0
  139. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/troubleshooting.md +519 -0
  140. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current.json +34 -0
  141. synapse_sdk/devtools/docs/i18n/ko/docusaurus-theme-classic/footer.json +42 -0
  142. synapse_sdk/devtools/docs/i18n/ko/docusaurus-theme-classic/navbar.json +18 -0
  143. synapse_sdk/devtools/docs/package-lock.json +18784 -0
  144. synapse_sdk/devtools/docs/package.json +48 -0
  145. synapse_sdk/devtools/docs/sidebars.ts +122 -0
  146. synapse_sdk/devtools/docs/src/components/HomepageFeatures/index.tsx +71 -0
  147. synapse_sdk/devtools/docs/src/components/HomepageFeatures/styles.module.css +11 -0
  148. synapse_sdk/devtools/docs/src/css/custom.css +30 -0
  149. synapse_sdk/devtools/docs/src/pages/index.module.css +23 -0
  150. synapse_sdk/devtools/docs/src/pages/index.tsx +21 -0
  151. synapse_sdk/devtools/docs/src/pages/markdown-page.md +7 -0
  152. synapse_sdk/devtools/docs/static/.nojekyll +0 -0
  153. synapse_sdk/devtools/docs/static/img/docusaurus-social-card.jpg +0 -0
  154. synapse_sdk/devtools/docs/static/img/docusaurus.png +0 -0
  155. synapse_sdk/devtools/docs/static/img/favicon.ico +0 -0
  156. synapse_sdk/devtools/docs/static/img/logo.png +0 -0
  157. synapse_sdk/devtools/docs/static/img/undraw_docusaurus_mountain.svg +171 -0
  158. synapse_sdk/devtools/docs/static/img/undraw_docusaurus_react.svg +170 -0
  159. synapse_sdk/devtools/docs/static/img/undraw_docusaurus_tree.svg +40 -0
  160. synapse_sdk/devtools/docs/tsconfig.json +8 -0
  161. synapse_sdk/devtools/server.py +41 -0
  162. synapse_sdk/devtools/streamlit_app/__init__.py +5 -0
  163. synapse_sdk/devtools/streamlit_app/app.py +128 -0
  164. synapse_sdk/devtools/streamlit_app/services/__init__.py +11 -0
  165. synapse_sdk/devtools/streamlit_app/services/job_service.py +233 -0
  166. synapse_sdk/devtools/streamlit_app/services/plugin_service.py +236 -0
  167. synapse_sdk/devtools/streamlit_app/services/serve_service.py +95 -0
  168. synapse_sdk/devtools/streamlit_app/ui/__init__.py +15 -0
  169. synapse_sdk/devtools/streamlit_app/ui/config_tab.py +76 -0
  170. synapse_sdk/devtools/streamlit_app/ui/deployment_tab.py +66 -0
  171. synapse_sdk/devtools/streamlit_app/ui/http_tab.py +125 -0
  172. synapse_sdk/devtools/streamlit_app/ui/jobs_tab.py +573 -0
  173. synapse_sdk/devtools/streamlit_app/ui/serve_tab.py +346 -0
  174. synapse_sdk/devtools/streamlit_app/ui/status_bar.py +118 -0
  175. synapse_sdk/devtools/streamlit_app/utils/__init__.py +40 -0
  176. synapse_sdk/devtools/streamlit_app/utils/json_viewer.py +197 -0
  177. synapse_sdk/devtools/streamlit_app/utils/log_formatter.py +38 -0
  178. synapse_sdk/devtools/streamlit_app/utils/styles.py +241 -0
  179. synapse_sdk/devtools/streamlit_app/utils/ui_components.py +289 -0
  180. synapse_sdk/devtools/streamlit_app.py +10 -0
  181. synapse_sdk/loggers.py +74 -9
  182. synapse_sdk/plugins/README.md +1340 -0
  183. synapse_sdk/plugins/__init__.py +0 -13
  184. synapse_sdk/plugins/categories/base.py +145 -30
  185. synapse_sdk/plugins/categories/data_validation/actions/validation.py +72 -0
  186. synapse_sdk/plugins/categories/data_validation/templates/plugin/validation.py +33 -5
  187. synapse_sdk/plugins/categories/export/actions/__init__.py +3 -0
  188. synapse_sdk/plugins/categories/export/actions/export/__init__.py +28 -0
  189. synapse_sdk/plugins/categories/export/actions/export/action.py +165 -0
  190. synapse_sdk/plugins/categories/export/actions/export/enums.py +113 -0
  191. synapse_sdk/plugins/categories/export/actions/export/exceptions.py +53 -0
  192. synapse_sdk/plugins/categories/export/actions/export/models.py +74 -0
  193. synapse_sdk/plugins/categories/export/actions/export/run.py +195 -0
  194. synapse_sdk/plugins/categories/export/actions/export/utils.py +187 -0
  195. synapse_sdk/plugins/categories/export/templates/config.yaml +21 -0
  196. synapse_sdk/plugins/categories/export/templates/plugin/__init__.py +390 -0
  197. synapse_sdk/plugins/categories/export/templates/plugin/export.py +160 -0
  198. synapse_sdk/plugins/categories/neural_net/actions/deployment.py +29 -14
  199. synapse_sdk/plugins/categories/neural_net/actions/inference.py +13 -1
  200. synapse_sdk/plugins/categories/neural_net/actions/train.py +1084 -38
  201. synapse_sdk/plugins/categories/neural_net/actions/tune.py +534 -0
  202. synapse_sdk/plugins/categories/neural_net/base/__init__.py +0 -0
  203. synapse_sdk/plugins/categories/neural_net/base/inference.py +37 -0
  204. synapse_sdk/plugins/categories/neural_net/templates/config.yaml +30 -5
  205. synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py +26 -10
  206. synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py +4 -0
  207. synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation/__init__.py +3 -0
  208. synapse_sdk/plugins/categories/{export/actions/export.py → pre_annotation/actions/pre_annotation/action.py} +4 -4
  209. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/__init__.py +28 -0
  210. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/action.py +145 -0
  211. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/enums.py +269 -0
  212. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/exceptions.py +14 -0
  213. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/factory.py +76 -0
  214. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/models.py +97 -0
  215. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/orchestrator.py +250 -0
  216. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/run.py +64 -0
  217. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/__init__.py +17 -0
  218. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/annotation.py +287 -0
  219. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/base.py +170 -0
  220. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/extraction.py +83 -0
  221. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/metrics.py +87 -0
  222. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/preprocessor.py +127 -0
  223. synapse_sdk/plugins/categories/pre_annotation/actions/to_task/strategies/validation.py +143 -0
  224. synapse_sdk/plugins/categories/pre_annotation/actions/to_task.py +966 -0
  225. synapse_sdk/plugins/categories/pre_annotation/templates/config.yaml +19 -0
  226. synapse_sdk/plugins/categories/pre_annotation/templates/plugin/to_task.py +40 -0
  227. synapse_sdk/plugins/categories/smart_tool/templates/config.yaml +5 -2
  228. synapse_sdk/plugins/categories/upload/__init__.py +0 -0
  229. synapse_sdk/plugins/categories/upload/actions/__init__.py +0 -0
  230. synapse_sdk/plugins/categories/upload/actions/upload/__init__.py +19 -0
  231. synapse_sdk/plugins/categories/upload/actions/upload/action.py +232 -0
  232. synapse_sdk/plugins/categories/upload/actions/upload/context.py +185 -0
  233. synapse_sdk/plugins/categories/upload/actions/upload/enums.py +471 -0
  234. synapse_sdk/plugins/categories/upload/actions/upload/exceptions.py +36 -0
  235. synapse_sdk/plugins/categories/upload/actions/upload/factory.py +138 -0
  236. synapse_sdk/plugins/categories/upload/actions/upload/models.py +203 -0
  237. synapse_sdk/plugins/categories/upload/actions/upload/orchestrator.py +183 -0
  238. synapse_sdk/plugins/categories/upload/actions/upload/registry.py +113 -0
  239. synapse_sdk/plugins/categories/upload/actions/upload/run.py +179 -0
  240. synapse_sdk/plugins/categories/upload/actions/upload/steps/__init__.py +1 -0
  241. synapse_sdk/plugins/categories/upload/actions/upload/steps/base.py +107 -0
  242. synapse_sdk/plugins/categories/upload/actions/upload/steps/cleanup.py +62 -0
  243. synapse_sdk/plugins/categories/upload/actions/upload/steps/collection.py +63 -0
  244. synapse_sdk/plugins/categories/upload/actions/upload/steps/generate.py +84 -0
  245. synapse_sdk/plugins/categories/upload/actions/upload/steps/initialize.py +82 -0
  246. synapse_sdk/plugins/categories/upload/actions/upload/steps/metadata.py +235 -0
  247. synapse_sdk/plugins/categories/upload/actions/upload/steps/organize.py +203 -0
  248. synapse_sdk/plugins/categories/upload/actions/upload/steps/upload.py +97 -0
  249. synapse_sdk/plugins/categories/upload/actions/upload/steps/validate.py +71 -0
  250. synapse_sdk/plugins/categories/upload/actions/upload/strategies/__init__.py +1 -0
  251. synapse_sdk/plugins/categories/upload/actions/upload/strategies/base.py +82 -0
  252. synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/__init__.py +1 -0
  253. synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/batch.py +39 -0
  254. synapse_sdk/plugins/categories/upload/actions/upload/strategies/data_unit/single.py +29 -0
  255. synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/__init__.py +1 -0
  256. synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/flat.py +258 -0
  257. synapse_sdk/plugins/categories/upload/actions/upload/strategies/file_discovery/recursive.py +281 -0
  258. synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/__init__.py +1 -0
  259. synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/excel.py +174 -0
  260. synapse_sdk/plugins/categories/upload/actions/upload/strategies/metadata/none.py +16 -0
  261. synapse_sdk/plugins/categories/upload/actions/upload/strategies/upload/__init__.py +1 -0
  262. synapse_sdk/plugins/categories/upload/actions/upload/strategies/upload/sync.py +84 -0
  263. synapse_sdk/plugins/categories/upload/actions/upload/strategies/validation/__init__.py +1 -0
  264. synapse_sdk/plugins/categories/upload/actions/upload/strategies/validation/default.py +60 -0
  265. synapse_sdk/plugins/categories/upload/actions/upload/utils.py +250 -0
  266. synapse_sdk/plugins/categories/upload/templates/README.md +470 -0
  267. synapse_sdk/plugins/categories/upload/templates/config.yaml +33 -0
  268. synapse_sdk/plugins/categories/upload/templates/plugin/__init__.py +294 -0
  269. synapse_sdk/plugins/categories/upload/templates/plugin/upload.py +102 -0
  270. synapse_sdk/plugins/enums.py +3 -1
  271. synapse_sdk/plugins/models.py +140 -16
  272. synapse_sdk/plugins/templates/plugin-config-schema.json +406 -0
  273. synapse_sdk/plugins/templates/schema.json +491 -0
  274. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml +1 -0
  275. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/requirements.txt +1 -1
  276. synapse_sdk/plugins/utils/__init__.py +46 -0
  277. synapse_sdk/plugins/utils/actions.py +119 -0
  278. synapse_sdk/plugins/utils/config.py +203 -0
  279. synapse_sdk/plugins/utils/legacy.py +95 -0
  280. synapse_sdk/plugins/utils/ray_gcs.py +66 -0
  281. synapse_sdk/plugins/utils/registry.py +58 -0
  282. synapse_sdk/shared/__init__.py +25 -0
  283. synapse_sdk/shared/enums.py +93 -0
  284. synapse_sdk/types.py +19 -0
  285. synapse_sdk/utils/converters/__init__.py +240 -0
  286. synapse_sdk/utils/converters/coco/__init__.py +0 -0
  287. synapse_sdk/utils/converters/coco/from_dm.py +322 -0
  288. synapse_sdk/utils/converters/coco/to_dm.py +215 -0
  289. synapse_sdk/utils/converters/dm/__init__.py +56 -0
  290. synapse_sdk/utils/converters/dm/from_v1.py +627 -0
  291. synapse_sdk/utils/converters/dm/to_v1.py +367 -0
  292. synapse_sdk/utils/converters/pascal/__init__.py +0 -0
  293. synapse_sdk/utils/converters/pascal/from_dm.py +244 -0
  294. synapse_sdk/utils/converters/pascal/to_dm.py +214 -0
  295. synapse_sdk/utils/converters/yolo/__init__.py +0 -0
  296. synapse_sdk/utils/converters/yolo/from_dm.py +384 -0
  297. synapse_sdk/utils/converters/yolo/to_dm.py +267 -0
  298. synapse_sdk/utils/dataset.py +46 -0
  299. synapse_sdk/utils/encryption.py +158 -0
  300. synapse_sdk/utils/file/__init__.py +39 -0
  301. synapse_sdk/utils/file/archive.py +32 -0
  302. synapse_sdk/utils/file/checksum.py +56 -0
  303. synapse_sdk/utils/file/chunking.py +31 -0
  304. synapse_sdk/utils/file/download.py +385 -0
  305. synapse_sdk/utils/file/encoding.py +40 -0
  306. synapse_sdk/utils/file/io.py +22 -0
  307. synapse_sdk/utils/file/video/__init__.py +29 -0
  308. synapse_sdk/utils/file/video/transcode.py +307 -0
  309. synapse_sdk/utils/file.py.backup +301 -0
  310. synapse_sdk/utils/http.py +138 -0
  311. synapse_sdk/utils/network.py +309 -0
  312. synapse_sdk/utils/storage/__init__.py +72 -0
  313. synapse_sdk/utils/storage/providers/__init__.py +183 -0
  314. synapse_sdk/utils/storage/providers/file_system.py +134 -0
  315. synapse_sdk/utils/storage/providers/gcp.py +13 -0
  316. synapse_sdk/utils/storage/providers/http.py +190 -0
  317. synapse_sdk/utils/storage/providers/s3.py +91 -0
  318. synapse_sdk/utils/storage/providers/sftp.py +47 -0
  319. synapse_sdk/utils/storage/registry.py +17 -0
  320. synapse_sdk-2025.11.7.dist-info/METADATA +122 -0
  321. synapse_sdk-2025.11.7.dist-info/RECORD +386 -0
  322. {synapse_sdk-1.0.0a13.dist-info → synapse_sdk-2025.11.7.dist-info}/WHEEL +1 -1
  323. synapse_sdk/clients/backend/dataset.py +0 -51
  324. synapse_sdk/plugins/categories/import/actions/import.py +0 -10
  325. synapse_sdk/plugins/cli/__init__.py +0 -21
  326. synapse_sdk/plugins/cli/publish.py +0 -37
  327. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.env +0 -24
  328. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.env.dist +0 -24
  329. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/main.py +0 -4
  330. synapse_sdk/plugins/utils.py +0 -50
  331. synapse_sdk/utils/file.py +0 -87
  332. synapse_sdk/utils/storage.py +0 -91
  333. synapse_sdk-1.0.0a13.dist-info/METADATA +0 -43
  334. synapse_sdk-1.0.0a13.dist-info/RECORD +0 -111
  335. /synapse_sdk/{plugins/categories/import → clients/validators}/__init__.py +0 -0
  336. /synapse_sdk/{plugins/categories/import/actions → devtools}/__init__.py +0 -0
  337. {synapse_sdk-1.0.0a13.dist-info → synapse_sdk-2025.11.7.dist-info}/entry_points.txt +0 -0
  338. {synapse_sdk-1.0.0a13.dist-info → synapse_sdk-2025.11.7.dist-info/licenses}/LICENSE +0 -0
  339. {synapse_sdk-1.0.0a13.dist-info → synapse_sdk-2025.11.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,1092 @@
1
+ ---
2
+ id: export-plugins
3
+ title: Export Plugins
4
+ sidebar_position: 2
5
+ ---
6
+
7
+ # Export Plugins
8
+
9
+ Export plugins provide data export and transformation operations for exporting annotated data, ground truth datasets, assignments, and tasks from the Synapse platform.
10
+
11
+ ## Overview
12
+
13
+ **Available Actions:**
14
+
15
+ - `export` - Export data from various sources (assignments, ground truth, tasks) with customizable processing
16
+
17
+ **Use Cases:**
18
+
19
+ - Exporting annotated datasets for training
20
+ - Converting ground truth data to custom formats
21
+ - Creating data packages for distribution
22
+ - Batch processing of assignment results
23
+ - Transforming annotation data for external tools
24
+
25
+ **Supported Export Targets:**
26
+
27
+ - `assignment` - Export assignment data with annotations
28
+ - `ground_truth` - Export ground truth dataset versions
29
+ - `task` - Export task data with associated annotations
30
+
31
+ ## BaseExporter and Exporter Class Architecture
32
+
33
+ The following diagrams illustrate the relationship between BaseExporter and Exporter classes and their method implementations:
34
+
35
+ ```mermaid
36
+ classDiagram
37
+ %% Light/Dark mode compatible colors using CSS variables
38
+ classDef baseClass fill:#f0f8ff,stroke:#4169e1,stroke-width:2px,color:#000
39
+ classDef childClass fill:#f0fff0,stroke:#228b22,stroke-width:2px,color:#000
40
+ classDef method fill:#fff8dc,stroke:#daa520,stroke-width:1px,color:#000
41
+ classDef abstractMethod fill:#ffe4e1,stroke:#dc143c,stroke-width:1px,color:#000
42
+ classDef helperMethod fill:#f5f5f5,stroke:#696969,stroke-width:1px,color:#000
43
+
44
+ class BaseExporter {
45
+ %% Core attributes
46
+ +run: object
47
+ +export_items: Generator
48
+ +path_root: Path
49
+ +params: dict
50
+
51
+ %% Main workflow methods
52
+ +export(export_items, results, **kwargs) dict
53
+ +process_data_conversion(export_item) object
54
+ +process_file_saving(...) bool
55
+ +setup_output_directories(path, flag) dict
56
+
57
+ %% Abstract methods (to be implemented)
58
+ +convert_data(data)* object
59
+ +before_convert(data)* object
60
+ +after_convert(data)* object
61
+
62
+ %% File operations
63
+ +save_original_file(result, path, errors) ExportStatus
64
+ +save_as_json(result, path, errors) ExportStatus
65
+ +get_original_file_name(files) str
66
+
67
+ %% Helper methods
68
+ -_create_unique_export_path(name) Path
69
+ -_save_error_list(path, json_errors, file_errors)
70
+ -_process_original_file_saving(...) bool
71
+ -_process_json_file_saving(...) bool
72
+ }
73
+
74
+ class Exporter {
75
+ %% Inherited from BaseExporter
76
+ +export(export_items, results, **kwargs) dict
77
+
78
+ %% Implemented abstract methods
79
+ +convert_data(data) object
80
+ +before_convert(data) object
81
+ +after_convert(data) object
82
+ }
83
+
84
+ %% Inheritance relationship
85
+ BaseExporter <|-- Exporter
86
+
87
+ %% Apply styles
88
+ class BaseExporter baseClass
89
+ class Exporter childClass
90
+ ```
91
+
92
+ ### Method Execution Flow
93
+
94
+ This flowchart shows the complete execution flow of export operations:
95
+
96
+ ```mermaid
97
+ flowchart TD
98
+ %% Start
99
+ A[export method called] --> B[Initialize paths and metrics]
100
+ B --> C[Setup output directories]
101
+ C --> D[Loop through export_items]
102
+
103
+ %% Data processing pipeline
104
+ D --> E[process_data_conversion]
105
+ E --> F[before_convert]
106
+ F --> G[convert_data]
107
+ G --> H[after_convert]
108
+
109
+ %% File saving pipeline
110
+ H --> I[process_file_saving]
111
+ I --> J{save_original_file?}
112
+ J -->|Yes| K[_process_original_file_saving]
113
+ J -->|No| L[_process_json_file_saving]
114
+ K --> L
115
+
116
+ %% Continue or finish
117
+ L --> M{More items?}
118
+ M -->|Yes| D
119
+ M -->|No| N[Save error lists]
120
+ N --> O[Return export path]
121
+
122
+ %% Error handling
123
+ K --> P{Original file failed?}
124
+ P -->|Yes| Q[Skip to next item]
125
+ P -->|No| L
126
+
127
+ L --> R{JSON file failed?}
128
+ R -->|Yes| Q
129
+ R -->|No| S[Update metrics]
130
+ S --> M
131
+ Q --> M
132
+
133
+ %% Styling for light/dark compatibility
134
+ classDef startEnd fill:#e1f5fe,stroke:#01579b,color:#000
135
+ classDef process fill:#f3e5f5,stroke:#4a148c,color:#000
136
+ classDef decision fill:#fff3e0,stroke:#e65100,color:#000
137
+ classDef data fill:#e8f5e8,stroke:#2e7d32,color:#000
138
+ classDef error fill:#ffebee,stroke:#c62828,color:#000
139
+
140
+ class A,O startEnd
141
+ class B,C,E,F,G,H,I,K,L,N,S process
142
+ class J,M,P,R decision
143
+ class D data
144
+ class Q error
145
+ ```
146
+
147
+ ### Key Relationships and Responsibilities
148
+
149
+ **BaseExporter (Abstract Base Class)**
150
+
151
+ - **Core Functionality**: Provides complete export workflow infrastructure
152
+ - **Template Methods**: `export()` method orchestrates the entire process
153
+ - **Hook Methods**: `convert_data()`, `before_convert()`, `after_convert()` for customization
154
+ - **Utilities**: File operations, directory setup, error handling, progress tracking
155
+
156
+ **Exporter (Concrete Implementation)**
157
+
158
+ - **Inheritance**: Extends `BaseExporter`
159
+ - **Minimal Implementation**: Provides basic implementations of abstract methods
160
+ - **Pass-through Behavior**: Most methods delegate to parent class
161
+ - **Customization Points**: Override conversion methods for specific logic
162
+
163
+ ### Method Categories
164
+
165
+ - **🔵 Core Workflow**: Main export orchestration methods
166
+ - **🟢 Template/Hook**: Methods designed to be overridden by subclasses
167
+ - **🟡 File Operations**: Concrete file saving and handling methods
168
+ - **🔸 Helper/Utility**: Private methods for internal operations
169
+
170
+ The design follows the **Template Method Pattern** where `BaseExporter.export()` defines the algorithm skeleton, and subclasses customize specific steps through the hook methods.
171
+
172
+ ## Plugin Configuration
173
+
174
+ Export plugin templates include configuration fields for filtering and plugin discovery:
175
+
176
+ ```yaml
177
+ actions:
178
+ export:
179
+ entrypoint: plugin.export.Exporter
180
+ annotation_types:
181
+ - image
182
+ - video
183
+ - audio
184
+ - text
185
+ - pcd
186
+ - prompt
187
+
188
+ data_types:
189
+ - image
190
+ - video
191
+ - audio
192
+ - text
193
+ - pcd
194
+ ```
195
+
196
+ ### Configuration Fields
197
+
198
+ - **data_types**: List of supported data types for filtering export plugins (plugin-level filter)
199
+
200
+ - Supported values: `image`, `video`, `audio`, `text`, `pcd`
201
+ - Used by the platform to filter and display relevant export plugins to users based on their data type
202
+
203
+ - **annotation_types**: List of supported annotation types for filtering export plugins (action-level filter)
204
+ - Supported values: `image`, `video`, `audio`, `text`, `pcd`, `prompt`
205
+ - Defined within each action's configuration (e.g., `actions.export.annotation_types`)
206
+ - Used by the platform to filter and display relevant export plugins to users based on their annotation type
207
+ - Each action can have different annotation type requirements
208
+
209
+ **Best Practice**: Customize these fields to accurately reflect your plugin's capabilities. The template includes all common types as examples, but you should modify the list to match what your plugin actually supports.
210
+
211
+ ## BaseExporter Class Structure
212
+
213
+ The new BaseExporter class provides an object-oriented approach for export plugins:
214
+
215
+ ```python
216
+ from synapse_sdk.plugins.categories.export.templates.plugin import BaseExporter
217
+
218
+ class Exporter(BaseExporter):
219
+ """Plugin export action interface for organizing files."""
220
+
221
+ def __init__(self, run, export_items, path_root, **params):
222
+ """Initialize the plugin export action class."""
223
+ super().__init__(run, export_items, path_root, **params)
224
+
225
+ def convert_data(self, data):
226
+ """Converts the data."""
227
+ return data
228
+
229
+ def before_convert(self, data):
230
+ """Preprocesses the data before conversion."""
231
+ return data
232
+
233
+ def after_convert(self, data):
234
+ """Post-processes the data after conversion."""
235
+ return data
236
+ ```
237
+
238
+ ## BaseExporter Core Functionality
239
+
240
+ ### Auto-provided Utilities
241
+
242
+ - **Complete Export Workflow**: `export()` method handles the complete export process
243
+ - **Data Conversion Pipeline**: `process_data_conversion()` handles before_convert → convert_data → after_convert processing
244
+ - **File Saving Management**: `process_file_saving()` handles original file and JSON file saving operations (can be overridden)
245
+ - **Output Directory Setup**: `setup_output_directories()` creates output directory structure (can be overridden)
246
+
247
+ ### Required Methods (should be implemented by subclasses)
248
+
249
+ - **convert_data()**: Transform data during export
250
+
251
+ ### Optional Methods (can be overridden by subclasses)
252
+
253
+ - **save_original_file()**: Save original files from export items
254
+ - **save_as_json()**: Save data as JSON files
255
+ - **before_convert()**: Pre-process data before conversion
256
+ - **after_convert()**: Post-process data after conversion
257
+ - **process_file_saving()**: Custom file saving logic
258
+ - **additional_file_saving()**: Save additional files after processing all export items
259
+
260
+ ### Helper Methods
261
+
262
+ - **\_process_original_file_saving()**: Handle original file saving with metrics
263
+ - **\_process_json_file_saving()**: Handle JSON file saving with metrics
264
+
265
+ ### Auto-provided Utilities
266
+
267
+ - Progress tracking via `self.run.set_progress()`
268
+ - Logging via `self.run.log_message()` and other run methods
269
+ - Error handling and metrics collection via self.run methods
270
+
271
+ ## Additional File Saving
272
+
273
+ The `additional_file_saving()` method is called after all export items have been processed and is designed for saving files that depend on the collective data from all processed items. This is useful for creating:
274
+
275
+ - Metadata files (e.g., dataset statistics, class mappings)
276
+ - Configuration files (e.g., dataset.yaml for YOLO, classes.txt)
277
+ - Summary files (e.g., export reports, processing logs)
278
+ - Index files (e.g., file lists, directory structures)
279
+
280
+ ### Method Signature
281
+
282
+ ```python
283
+ def additional_file_saving(self, unique_export_path):
284
+ """Save additional files after processing all export items.
285
+
286
+ This method is called after the main export loop completes and is intended
287
+ for saving files that need to be created based on the collective data from
288
+ all processed export items (e.g., metadata files, configuration files,
289
+ summary files, etc.).
290
+
291
+ Args:
292
+ unique_export_path (str): The unique export directory path where
293
+ additional files should be saved.
294
+ """
295
+ pass
296
+ ```
297
+
298
+ ### Example Usage
299
+
300
+ ```python
301
+ class YOLOExporter(BaseExporter):
302
+ def __init__(self, run, export_items, path_root, **params):
303
+ super().__init__(run, export_items, path_root, **params)
304
+ self.class_names = set()
305
+ self.dataset_stats = {
306
+ 'total_images': 0,
307
+ 'total_annotations': 0,
308
+ 'class_distribution': {}
309
+ }
310
+
311
+ def convert_data(self, data):
312
+ # Track classes and stats during conversion
313
+ for annotation in data.get('annotations', []):
314
+ class_name = annotation['class_name']
315
+ self.class_names.add(class_name)
316
+ self.dataset_stats['class_distribution'][class_name] = \
317
+ self.dataset_stats['class_distribution'].get(class_name, 0) + 1
318
+
319
+ self.dataset_stats['total_images'] += 1
320
+ self.dataset_stats['total_annotations'] += len(data.get('annotations', []))
321
+
322
+ return data # ... rest of conversion logic
323
+
324
+ def additional_file_saving(self, unique_export_path):
325
+ """Save YOLO configuration and metadata files."""
326
+ data_dir = Path(unique_export_path) / 'data'
327
+ data_dir.mkdir(exist_ok=True)
328
+
329
+ # 1. Save classes.txt file
330
+ classes_file = data_dir / 'classes.txt'
331
+ with classes_file.open('w') as f:
332
+ for class_name in sorted(self.class_names):
333
+ f.write(f"{class_name}\n")
334
+ self.run.log_message(f"Saved classes file: {classes_file}")
335
+
336
+ # 2. Save dataset.yaml file
337
+ dataset_config = {
338
+ 'path': str(unique_export_path),
339
+ 'train': 'images',
340
+ 'val': 'images',
341
+ 'names': {i: name for i, name in enumerate(sorted(self.class_names))}
342
+ }
343
+
344
+ dataset_file = data_dir / 'dataset.yaml'
345
+ with dataset_file.open('w') as f:
346
+ yaml.dump(dataset_config, f, default_flow_style=False)
347
+ self.run.log_message(f"Saved dataset config: {dataset_file}")
348
+
349
+ # 3. Save export statistics
350
+ stats_file = data_dir / 'export_stats.json'
351
+ with stats_file.open('w') as f:
352
+ json.dump(self.dataset_stats, f, indent=2)
353
+ self.run.log_message(f"Saved export statistics: {stats_file}")
354
+ ```
355
+
356
+ ### Common Use Cases
357
+
358
+ #### 1. Dataset Configuration Files
359
+
360
+ ```python
361
+ def additional_file_saving(self, unique_export_path):
362
+ # Create dataset configuration for training frameworks
363
+ config = {
364
+ 'dataset_name': self.params.get('name'),
365
+ 'created_at': datetime.now().isoformat(),
366
+ 'total_samples': len(self.processed_items),
367
+ 'classes': list(self.class_mapping.keys())
368
+ }
369
+
370
+ config_file = Path(unique_export_path) / 'dataset_config.json'
371
+ with config_file.open('w') as f:
372
+ json.dump(config, f, indent=2)
373
+ ```
374
+
375
+ #### 2. Export Summary Reports
376
+
377
+ ```python
378
+ def additional_file_saving(self, unique_export_path):
379
+ # Generate export summary
380
+ summary = {
381
+ 'export_info': {
382
+ 'plugin_name': self.__class__.__name__,
383
+ 'export_time': datetime.now().isoformat(),
384
+ 'export_path': str(unique_export_path)
385
+ },
386
+ 'statistics': self.get_export_statistics(),
387
+ 'errors': self.get_error_summary()
388
+ }
389
+
390
+ summary_file = Path(unique_export_path) / 'export_summary.json'
391
+ with summary_file.open('w') as f:
392
+ json.dump(summary, f, indent=2)
393
+ ```
394
+
395
+ #### 3. Index and Manifest Files
396
+
397
+ ```python
398
+ def additional_file_saving(self, unique_export_path):
399
+ # Create file index for processed items
400
+ file_index = []
401
+ for item in self.processed_items:
402
+ file_index.append({
403
+ 'original_file': item['original_filename'],
404
+ 'json_file': f"{item['stem']}.json",
405
+ 'processed_at': item['timestamp']
406
+ })
407
+
408
+ index_file = Path(unique_export_path) / 'file_index.json'
409
+ with index_file.open('w') as f:
410
+ json.dump(file_index, f, indent=2)
411
+ ```
412
+
413
+ ## Key Features
414
+
415
+ - **Progress Tracking**: Built-in progress monitoring with `run.set_progress()`
416
+ - **Error Handling**: Automatic error collection and reporting
417
+ - **Metrics Logging**: Track success/failure rates with `run.log_metrics()`
418
+ - **File Management**: Handles both original files and processed JSON data
419
+ - **Logging**: Comprehensive logging with `run.log_message()` and custom events
420
+
421
+ ## Practical Examples
422
+
423
+ ### YOLO Format Exporter with Custom Directory Structure
424
+
425
+ Here's a complete example that exports data in YOLO format while leveraging `setup_output_directories` and `process_file_saving`:
426
+
427
+ ```python
428
+ from synapse_sdk.plugins.categories.export.templates.plugin import BaseExporter
429
+ import os
430
+ import json
431
+
432
+ class YOLOExporter(BaseExporter):
433
+ """Plugin to export data in YOLO format."""
434
+
435
+ def __init__(self, run, export_items, path_root, **params):
436
+ super().__init__(run, export_items, path_root, **params)
437
+ self.class_mapping = {}
438
+
439
+ def setup_output_directories(self, unique_export_path, save_original_file_flag):
440
+ """Create directories matching YOLO project structure."""
441
+ directories = ['images', 'labels', 'data']
442
+
443
+ for directory in directories:
444
+ dir_path = os.path.join(unique_export_path, directory)
445
+ os.makedirs(dir_path, exist_ok=True)
446
+ self.run.log_message(f"Created YOLO directory: {dir_path}")
447
+
448
+ return unique_export_path
449
+
450
+ def convert_data(self, data):
451
+ """Convert annotation data to YOLO format."""
452
+ converted_annotations = []
453
+
454
+ for annotation in data.get('annotations', []):
455
+ # Convert bounding box to YOLO format
456
+ bbox = annotation['geometry']['bbox']
457
+ image_width = data['image']['width']
458
+ image_height = data['image']['height']
459
+
460
+ # YOLO format: center_x, center_y, width, height (normalized)
461
+ center_x = (bbox['x'] + bbox['width'] / 2) / image_width
462
+ center_y = (bbox['y'] + bbox['height'] / 2) / image_height
463
+ width = bbox['width'] / image_width
464
+ height = bbox['height'] / image_height
465
+
466
+ # Class ID mapping
467
+ class_name = annotation['class_name']
468
+ if class_name not in self.class_mapping:
469
+ self.class_mapping[class_name] = len(self.class_mapping)
470
+
471
+ class_id = self.class_mapping[class_name]
472
+
473
+ converted_annotations.append({
474
+ 'class_id': class_id,
475
+ 'center_x': center_x,
476
+ 'center_y': center_y,
477
+ 'width': width,
478
+ 'height': height
479
+ })
480
+
481
+ return {
482
+ 'yolo_annotations': converted_annotations,
483
+ 'class_mapping': self.class_mapping,
484
+ 'image_info': data['image']
485
+ }
486
+
487
+ def process_file_saving(
488
+ self,
489
+ final_data,
490
+ unique_export_path,
491
+ save_original_file_flag,
492
+ errors_json_file_list,
493
+ errors_original_file_list,
494
+ original_file_metrics_record,
495
+ data_file_metrics_record,
496
+ current_index,
497
+ ):
498
+ """Handle file saving in YOLO format."""
499
+ try:
500
+ export_item = self.export_items[current_index - 1]
501
+ base_name = os.path.splitext(export_item.original_file.name)[0]
502
+
503
+ # 1. Save image file to images folder
504
+ if save_original_file_flag:
505
+ images_dir = os.path.join(unique_export_path, 'images')
506
+ image_path = os.path.join(images_dir, export_item.original_file.name)
507
+ import shutil
508
+ shutil.copy2(export_item.original_file.path, image_path)
509
+ self.run.log_message(f"Saved image: {image_path}")
510
+
511
+ # 2. Save YOLO label file to labels folder
512
+ labels_dir = os.path.join(unique_export_path, 'labels')
513
+ label_path = os.path.join(labels_dir, f"{base_name}.txt")
514
+
515
+ with open(label_path, 'w') as f:
516
+ for ann in final_data.get('yolo_annotations', []):
517
+ line = f"{ann['class_id']} {ann['center_x']} {ann['center_y']} {ann['width']} {ann['height']}\n"
518
+ f.write(line)
519
+
520
+ self.run.log_message(f"Saved YOLO label: {label_path}")
521
+
522
+ # 3. Save class mapping file (only once)
523
+ if current_index == 1: # Only when processing first file
524
+ classes_path = os.path.join(unique_export_path, 'data', 'classes.txt')
525
+ with open(classes_path, 'w') as f:
526
+ for class_name, class_id in sorted(final_data['class_mapping'].items(), key=lambda x: x[1]):
527
+ f.write(f"{class_name}\n")
528
+ self.run.log_message(f"Saved classes file: {classes_path}")
529
+
530
+ return True
531
+
532
+ except Exception as e:
533
+ self.run.log_message(f"Error during file saving: {str(e)}", level="error")
534
+ errors_json_file_list.append(f"Export item {current_index}: {str(e)}")
535
+ return True # Return True to continue processing other files
536
+ ```
537
+
538
+ This example demonstrates how to leverage BaseExporter's key extension points `setup_output_directories` and `process_file_saving` to:
539
+
540
+ - Create YOLO project structure (`images/`, `labels/`, `data/`)
541
+ - Save image files and YOLO label files in appropriate locations
542
+ - Manage class mapping files
543
+ - Track progress and handle errors
544
+
545
+ ## Quick Start Guide
546
+
547
+ Step-by-step guide to create a simple plugin using BaseExporter:
548
+
549
+ ### Step 1: Inherit Base Class
550
+
551
+ ```python
552
+ from synapse_sdk.plugins.categories.export.templates.plugin import BaseExporter
553
+
554
+ class MyExporter(BaseExporter):
555
+ def convert_data(self, data):
556
+ # Required: Implement data transformation logic
557
+ return data # or return transformed data
558
+ ```
559
+
560
+ ### Step 2: Override Additional Methods as Needed
561
+
562
+ ```python
563
+ def before_convert(self, data):
564
+ # Optional: Pre-processing before conversion
565
+ return data
566
+
567
+ def after_convert(self, converted_data):
568
+ # Optional: Post-processing after conversion
569
+ return converted_data
570
+
571
+ def save_as_json(self, converted_data, output_path):
572
+ # Optional: Custom save format
573
+ # By default saves as JSON format
574
+ pass
575
+ ```
576
+
577
+ ### Step 3: Register Plugin
578
+
579
+ Plugin directory structure:
580
+
581
+ ```
582
+ my_plugin/
583
+ ├── __init__.py
584
+ ├── plugin.py # MyExporter class definition
585
+ └── manifest.yaml # Plugin metadata
586
+ ```
587
+
588
+ ## Export Action Architecture
589
+
590
+ The export system has been refactored into a modular architecture with specialized components for different aspects of data export processing:
591
+
592
+ ```mermaid
593
+ classDiagram
594
+ %% Light/Dark mode compatible colors with semi-transparency
595
+ classDef baseClass fill:#e1f5fe80,stroke:#0288d1,stroke-width:2px
596
+ classDef childClass fill:#c8e6c980,stroke:#388e3c,stroke-width:2px
597
+ classDef modelClass fill:#fff9c480,stroke:#f57c00,stroke-width:2px
598
+ classDef utilClass fill:#f5f5f580,stroke:#616161,stroke-width:2px
599
+ classDef enumClass fill:#ffccbc80,stroke:#d32f2f,stroke-width:2px
600
+
601
+ class ExportAction {
602
+ +name: str = "export"
603
+ +category: PluginCategory.EXPORT
604
+ +method: RunMethod.JOB
605
+ +run_class: ExportRun
606
+ +params_model: ExportParams
607
+ +progress_categories: dict
608
+ +metrics_categories: dict
609
+
610
+ +start() dict
611
+ +get_exporter(...) object
612
+ +_get_export_items(target, filter) Generator
613
+ +_create_target_handler(target) object
614
+ }
615
+
616
+ class ExportRun {
617
+ +log_message_with_code(code, args, level) None
618
+ +log_export_event(code, args, level) None
619
+ +export_log_json_file(id, file_info, status) None
620
+ +export_log_original_file(id, file_info, status) None
621
+ +ExportEventLog: BaseModel
622
+ +DataFileLog: BaseModel
623
+ +MetricsRecord: BaseModel
624
+ }
625
+
626
+ class ExportParams {
627
+ +name: str
628
+ +storage: int
629
+ +target: Literal["assignment", "ground_truth", "task"]
630
+ +filter: dict
631
+ +path: str
632
+ +save_original_file: bool = True
633
+ +extra_params: dict = {}
634
+
635
+ +check_storage_exists(value) str
636
+ +validate_target_filter(cls, values) dict
637
+ }
638
+
639
+ class LogCode {
640
+ +EXPORT_STARTED: str
641
+ +ITEMS_DISCOVERED: str
642
+ +CONVERSION_STARTED: str
643
+ +CONVERSION_COMPLETED: str
644
+ +FILE_SAVED: str
645
+ +EXPORT_COMPLETED: str
646
+ +EXPORT_FAILED: str
647
+ }
648
+
649
+ class ExportStatus {
650
+ +SUCCESS: str = "success"
651
+ +FAILED: str = "failed"
652
+ +SKIPPED: str = "skipped"
653
+ }
654
+
655
+ class ExportError {
656
+ +message: str
657
+ +code: str
658
+ }
659
+
660
+ class ExportValidationError {
661
+ +message: str
662
+ +field: str
663
+ }
664
+
665
+ class ExportTargetError {
666
+ +message: str
667
+ +target: str
668
+ }
669
+
670
+ %% Relationships
671
+ ExportAction --> ExportRun : uses
672
+ ExportAction --> ExportParams : validates with
673
+ ExportRun --> LogCode : logs with
674
+ ExportRun --> ExportStatus : tracks status
675
+ ExportAction --> ExportError : may raise
676
+ ExportAction --> ExportValidationError : may raise
677
+ ExportAction --> ExportTargetError : may raise
678
+
679
+ %% Apply styles
680
+ class ExportAction baseClass
681
+ class ExportRun childClass
682
+ class ExportParams modelClass
683
+ class LogCode,ExportStatus enumClass
684
+ class ExportError,ExportValidationError,ExportTargetError utilClass
685
+ ```
686
+
687
+ ### Modular Structure
688
+
689
+ The export action follows a clean modular organization:
690
+
691
+ ```
692
+ synapse_sdk/plugins/categories/export/actions/export/
693
+ ├── __init__.py # Clean module interfaces
694
+ ├── action.py # ExportAction class
695
+ ├── enums.py # ExportStatus, LogCode + LOG_MESSAGES
696
+ ├── exceptions.py # Export-specific exceptions
697
+ ├── models.py # ExportParams model
698
+ ├── run.py # ExportRun class
699
+ └── utils.py # Target handlers and utilities
700
+ ```
701
+
702
+ **Key Benefits:**
703
+
704
+ - **Enhanced Maintainability**: Smaller, focused files are easier to understand and modify
705
+ - **Code Consistency**: Export action now follows the same pattern as upload action
706
+ - **Better Organization**: Related functionality is grouped logically
707
+ - **Improved Readability**: Clear separation of concerns across modules
708
+
709
+ ## Creating Export Plugins
710
+
711
+ Export plugins now use the BaseExporter class-based approach for better organization and reusability. Here's how to create a custom export plugin:
712
+
713
+ ### Step 1: Generate Export Plugin Template
714
+
715
+ ```bash
716
+ synapse plugin create
717
+ # Select 'export' as category
718
+ # Plugin will be created with export template
719
+ ```
720
+
721
+ ### Step 2: Customize Export Parameters
722
+
723
+ The `ExportParams` model defines the required parameters:
724
+
725
+ ```python
726
+ from synapse_sdk.plugins.categories.export.actions.export.models import ExportParams
727
+ from pydantic import BaseModel
728
+ from typing import Literal
729
+
730
+ class CustomExportParams(ExportParams):
731
+ # Add custom parameters
732
+ output_format: Literal['json', 'csv', 'xml'] = 'json'
733
+ include_metadata: bool = True
734
+ compression: bool = False
735
+ ```
736
+
737
+ ### Step 3: Implement Data Transformation
738
+
739
+ Implement the required methods in your `Exporter` class in `plugin/export.py`:
740
+
741
+ ```python
742
+ from datetime import datetime
743
+ from synapse_sdk.plugins.categories.export.templates.plugin import BaseExporter
744
+
745
+ class Exporter(BaseExporter):
746
+ """Custom export plugin with COCO format conversion."""
747
+
748
+ def convert_data(self, data):
749
+ """Convert annotation data to your desired format."""
750
+ # Example: Convert to COCO format
751
+ if data.get('data_type') == 'image_detection':
752
+ return self.convert_to_coco_format(data)
753
+ elif data.get('data_type') == 'image_classification':
754
+ return self.convert_to_classification_format(data)
755
+ return data
756
+
757
+ def before_convert(self, export_item):
758
+ """Preprocess data before conversion."""
759
+ # Add validation, filtering, or preprocessing
760
+ if not export_item.get('data'):
761
+ return None # Skip empty items
762
+
763
+ # Add custom metadata
764
+ export_item['processed_at'] = datetime.now().isoformat()
765
+ return export_item
766
+
767
+ def after_convert(self, converted_data):
768
+ """Post-process converted data."""
769
+ # Add final touches, validation, or formatting
770
+ if 'annotations' in converted_data:
771
+ converted_data['annotation_count'] = len(converted_data['annotations'])
772
+ return converted_data
773
+
774
+ def convert_to_coco_format(self, data):
775
+ """Example: Convert to COCO detection format."""
776
+ coco_data = {
777
+ "images": [],
778
+ "annotations": [],
779
+ "categories": []
780
+ }
781
+
782
+ # Transform annotation data to COCO format
783
+ for annotation in data.get('annotations', []):
784
+ coco_annotation = {
785
+ "id": annotation['id'],
786
+ "image_id": annotation['image_id'],
787
+ "category_id": annotation['category_id'],
788
+ "bbox": annotation['bbox'],
789
+ "area": annotation.get('area', 0),
790
+ "iscrowd": 0
791
+ }
792
+ coco_data["annotations"].append(coco_annotation)
793
+
794
+ return coco_data
795
+ ```
796
+
797
+ ### Step 4: Configure Export Targets
798
+
799
+ The export action supports different data sources:
800
+
801
+ ```python
802
+ # Filter examples for different targets
803
+ filters = {
804
+ # For ground truth export
805
+ "ground_truth": {
806
+ "ground_truth_dataset_version": 123,
807
+ "expand": ["data"]
808
+ },
809
+
810
+ # For assignment export
811
+ "assignment": {
812
+ "project": 456,
813
+ "status": "completed",
814
+ "expand": ["data"]
815
+ },
816
+
817
+ # For task export
818
+ "task": {
819
+ "project": 456,
820
+ "assignment": 789,
821
+ "expand": ["data_unit", "assignment"]
822
+ }
823
+ }
824
+ ```
825
+
826
+ ### Step 5: Handle File Operations
827
+
828
+ Customize file saving and organization by overriding BaseExporter methods:
829
+
830
+ ```python
831
+ import json
832
+ from pathlib import Path
833
+ from synapse_sdk.plugins.categories.export.actions.export.enums import ExportStatus
834
+
835
+ class Exporter(BaseExporter):
836
+ """Custom export plugin with multiple format support."""
837
+
838
+ def save_as_json(self, result, base_path, error_file_list):
839
+ """Custom JSON saving with different formats."""
840
+ file_name = Path(self.get_original_file_name(result['files'])).stem
841
+
842
+ # Choose output format based on params
843
+ if self.params.get('output_format') == 'csv':
844
+ return self.save_as_csv(result, base_path, error_file_list)
845
+ elif self.params.get('output_format') == 'xml':
846
+ return self.save_as_xml(result, base_path, error_file_list)
847
+
848
+ # Default JSON handling
849
+ json_data = result['data']
850
+ file_info = {'file_name': f'{file_name}.json'}
851
+
852
+ try:
853
+ with (base_path / f'{file_name}.json').open('w', encoding='utf-8') as f:
854
+ json.dump(json_data, f, indent=4, ensure_ascii=False)
855
+ status = ExportStatus.SUCCESS
856
+ except Exception as e:
857
+ error_file_list.append([f'{file_name}.json', str(e)])
858
+ status = ExportStatus.FAILED
859
+
860
+ self.run.export_log_json_file(result['id'], file_info, status)
861
+ return status
862
+
863
+ def setup_output_directories(self, unique_export_path, save_original_file_flag):
864
+ """Custom directory structure."""
865
+ # Create format-specific directories
866
+ output_paths = super().setup_output_directories(unique_export_path, save_original_file_flag)
867
+
868
+ # Add custom directories based on output format
869
+ format_dir = unique_export_path / self.params.get('output_format', 'json')
870
+ format_dir.mkdir(parents=True, exist_ok=True)
871
+ output_paths['format_output_path'] = format_dir
872
+
873
+ return output_paths
874
+ ```
875
+
876
+ ### Step 6: Usage Examples
877
+
878
+ Running export plugins with different configurations:
879
+
880
+ ```bash
881
+ # Basic export of ground truth data
882
+ synapse plugin run export '{
883
+ "name": "my_export",
884
+ "storage": 1,
885
+ "target": "ground_truth",
886
+ "filter": {"ground_truth_dataset_version": 123},
887
+ "path": "exports/ground_truth",
888
+ "save_original_file": true
889
+ }' --plugin my-export-plugin
890
+
891
+ # Export assignments with custom parameters
892
+ synapse plugin run export '{
893
+ "name": "assignment_export",
894
+ "storage": 1,
895
+ "target": "assignment",
896
+ "filter": {"project": 456, "status": "completed"},
897
+ "path": "exports/assignments",
898
+ "save_original_file": false,
899
+ "extra_params": {
900
+ "output_format": "coco",
901
+ "include_metadata": true
902
+ }
903
+ }' --plugin custom-coco-export
904
+ ```
905
+
906
+ ## Common Export Patterns
907
+
908
+ ```python
909
+ # Pattern 1: Format-specific conversion
910
+ class Exporter(BaseExporter):
911
+ def convert_data(self, data):
912
+ """Convert to YOLO format."""
913
+ if data.get('task_type') == 'object_detection':
914
+ return self.convert_to_yolo_format(data)
915
+ return data
916
+
917
+ # Pattern 2: Conditional file organization
918
+ class Exporter(BaseExporter):
919
+ def setup_output_directories(self, unique_export_path, save_original_file_flag):
920
+ # Call parent method
921
+ output_paths = super().setup_output_directories(unique_export_path, save_original_file_flag)
922
+
923
+ # Create separate folders by category
924
+ for category in ['train', 'val', 'test']:
925
+ category_path = unique_export_path / category
926
+ category_path.mkdir(parents=True, exist_ok=True)
927
+ output_paths[f'{category}_path'] = category_path
928
+
929
+ return output_paths
930
+
931
+ # Pattern 3: Batch processing with validation
932
+ class Exporter(BaseExporter):
933
+ def before_convert(self, export_item):
934
+ # Validate required fields
935
+ required_fields = ['data', 'files', 'id']
936
+ for field in required_fields:
937
+ if field not in export_item:
938
+ raise ValueError(f"Missing required field: {field}")
939
+ return export_item
940
+ ```
941
+
942
+ ## Development Tips and Best Practices
943
+
944
+ ### 1. Error Handling
945
+
946
+ ```python
947
+ def convert_data(self, data):
948
+ try:
949
+ # Conversion logic
950
+ result = self.process_annotations(data)
951
+ return result
952
+ except Exception as e:
953
+ self.run.log_message(f"Error during conversion: {str(e)}", level="error")
954
+ raise # BaseExporter handles errors automatically
955
+ ```
956
+
957
+ ### 2. Progress Tracking
958
+
959
+ ```python
960
+ def convert_data(self, data):
961
+ annotations = data.get('annotations', [])
962
+ total = len(annotations)
963
+
964
+ for i, annotation in enumerate(annotations):
965
+ # Update progress (value between 0-100)
966
+ progress = int((i / total) * 100)
967
+ self.run.set_progress(progress)
968
+
969
+ # Conversion logic...
970
+
971
+ return converted_data
972
+ ```
973
+
974
+ ### 3. Metrics Collection
975
+
976
+ ```python
977
+ def after_convert(self, converted_data):
978
+ # Collect useful metrics
979
+ metrics = {
980
+ 'total_exported': len(converted_data.get('annotations', [])),
981
+ 'processing_time': time.time() - self.start_time,
982
+ 'success_rate': self.calculate_success_rate(),
983
+ }
984
+
985
+ self.run.log_metrics(metrics)
986
+ return converted_data
987
+ ```
988
+
989
+ ### 4. Logging Usage
990
+
991
+ ```python
992
+ def convert_data(self, data):
993
+ self.run.log_message("Starting data conversion", level="info")
994
+
995
+ if not data.get('annotations'):
996
+ self.run.log_message("No annotation data found", level="warning")
997
+ return data
998
+
999
+ # Conversion logic...
1000
+
1001
+ self.run.log_message(f"Conversion complete: processed {len(result)} items", level="success")
1002
+ return result
1003
+ ```
1004
+
1005
+ ### 5. Parameter Handling
1006
+
1007
+ ```python
1008
+ def __init__(self, run, export_items, path_root, **params):
1009
+ super().__init__(run, export_items, path_root, **params)
1010
+
1011
+ # Handle custom parameters
1012
+ self.output_format = params.get('output_format', 'json')
1013
+ self.include_metadata = params.get('include_metadata', True)
1014
+ self.compression = params.get('compression', False)
1015
+ ```
1016
+
1017
+ ## Best Practices
1018
+
1019
+ ### Data Processing
1020
+
1021
+ - **Memory Efficiency**: Use generators for processing large datasets
1022
+ - **Error Recovery**: Implement graceful error handling for individual items
1023
+ - **Progress Reporting**: Update progress regularly for long-running exports
1024
+ - **Data Validation**: Validate data structure before conversion
1025
+
1026
+ ```python
1027
+ class Exporter(BaseExporter):
1028
+ def export(self, export_items=None, results=None, **kwargs):
1029
+ """Override the main export method for custom processing."""
1030
+ # Use tee to count items without consuming generator
1031
+ items_to_process = export_items if export_items is not None else self.export_items
1032
+ export_items_count, export_items_process = tee(items_to_process)
1033
+ total = sum(1 for _ in export_items_count)
1034
+
1035
+ # Custom processing with error handling
1036
+ for no, export_item in enumerate(export_items_process, start=1):
1037
+ try:
1038
+ # Use the built-in data conversion pipeline
1039
+ processed_item = self.process_data_conversion(export_item)
1040
+ self.run.set_progress(no, total, category='dataset_conversion')
1041
+ except Exception as e:
1042
+ self.run.log_message(f"Error processing item {no}: {str(e)}", "ERROR")
1043
+ continue
1044
+
1045
+ # Call parent's export method for standard processing
1046
+ # or implement your own complete workflow
1047
+ return super().export(export_items, results, **kwargs)
1048
+ ```
1049
+
1050
+ ### File Management
1051
+
1052
+ - **Unique Paths**: Prevent file collisions with timestamp or counter suffixes
1053
+ - **Directory Structure**: Organize output files logically
1054
+ - **Error Logging**: Track failed files for debugging
1055
+ - **Cleanup**: Remove temporary files on completion
1056
+
1057
+ ```python
1058
+ class Exporter(BaseExporter):
1059
+ def setup_output_directories(self, unique_export_path, save_original_file_flag):
1060
+ """Create unique export directory structure."""
1061
+ # BaseExporter already handles unique path creation via _create_unique_export_path
1062
+ # This method sets up the internal directory structure
1063
+ output_paths = super().setup_output_directories(unique_export_path, save_original_file_flag)
1064
+
1065
+ # Add custom subdirectories as needed
1066
+ custom_dir = unique_export_path / 'custom_output'
1067
+ custom_dir.mkdir(parents=True, exist_ok=True)
1068
+ output_paths['custom_output_path'] = custom_dir
1069
+
1070
+ return output_paths
1071
+ ```
1072
+
1073
+ ### Format Conversion
1074
+
1075
+ - **Flexible Templates**: Design templates that work with multiple data types
1076
+ - **Schema Validation**: Validate output against expected schemas
1077
+ - **Metadata Preservation**: Maintain important metadata during conversion
1078
+ - **Version Compatibility**: Handle different data schema versions
1079
+
1080
+ ## Frequently Asked Questions
1081
+
1082
+ **Q: Can I implement plugins directly without using BaseExporter?**
1083
+ A: Yes, but it's not recommended. BaseExporter provides essential features like progress tracking, error handling, and metrics collection automatically.
1084
+
1085
+ **Q: Can I export to multiple file formats simultaneously?**
1086
+ A: Yes, you can override the `process_file_saving()` method to save in multiple formats.
1087
+
1088
+ **Q: How can I optimize memory usage when processing large datasets?**
1089
+ A: Consider using streaming processing in `convert_data()` rather than loading all data at once.
1090
+
1091
+ **Q: What should I do if progress is not displaying correctly?**
1092
+ A: Make sure you're calling `self.run.set_progress()` at appropriate intervals and using integer values between 0-100.