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,294 @@
1
+ from pathlib import Path
2
+ from typing import Dict, List
3
+
4
+
5
+ class BaseUploader:
6
+ """Base class for upload plugins with common functionality.
7
+
8
+ This class handles common tasks like file organization, validation, and metadata
9
+ that are shared across all upload plugins. Plugin developers should inherit
10
+ from this class and implement the required methods for their specific logic.
11
+
12
+ Important: Plugin extensions work with already-organized files from the main upload workflow.
13
+ Whether single-path or multi-path mode is used is transparent to plugin developers - you
14
+ simply process the organized_files list provided to you.
15
+
16
+ Core Methods:
17
+ handle_upload_files(): Main upload method - handles the complete upload workflow
18
+ organize_files(): Handle file organization logic (can be overridden)
19
+ validate_files(): Handle file validation logic (can be overridden)
20
+
21
+ Required Methods (should be implemented by subclasses):
22
+ process_files(): Transform/process files during upload
23
+
24
+ Optional Methods (can be overridden by subclasses):
25
+ before_process(): Pre-process files before main processing
26
+ after_process(): Post-process files after main processing
27
+ setup_directories(): Setup custom directories
28
+ validate_file_types(): Custom file type validation
29
+
30
+ Helper Methods:
31
+ _log_validation_warning(): Log validation warnings
32
+ _log_conversion_warning(): Log conversion warnings
33
+ _filter_valid_files(): Filter files based on validation
34
+
35
+ Auto-provided Utilities:
36
+ Logging via self.run.log_message() and other run methods
37
+ File path utilities via self.path
38
+ Specification access via self.file_specification
39
+
40
+ Customization:
41
+ To restrict file extensions, modify get_file_extensions_config() in this file:
42
+
43
+ Example - Allow only MP4 videos:
44
+ def get_file_extensions_config(self):
45
+ return {
46
+ 'video': ['.mp4'], # Only MP4 allowed
47
+ 'image': ['.jpg', '.png'],
48
+ # ... other types
49
+ }
50
+ """
51
+
52
+ def __init__(
53
+ self,
54
+ run,
55
+ path: Path,
56
+ file_specification: List = None,
57
+ organized_files: List = None,
58
+ extra_params: Dict = None,
59
+ ):
60
+ """Initialize the base upload class.
61
+
62
+ Args:
63
+ run: Plugin run object with logging capabilities.
64
+ path: Path object pointing to the upload target directory.
65
+ - In single-path mode: Base directory path (Path object)
66
+ - In multi-path mode: None (not needed - use self.assets_config instead)
67
+ Files have already been discovered from their respective asset paths.
68
+ file_specification: List of specifications that define the structure of files to be uploaded.
69
+ organized_files: List of pre-organized files based on the default logic.
70
+ Plugin extensions work with these already-organized files regardless of
71
+ whether single-path or multi-path mode was used.
72
+ extra_params: Additional parameters for customization.
73
+ """
74
+ self.run = run
75
+ self.path = path
76
+ self.file_specification = file_specification or []
77
+ self.organized_files = organized_files or []
78
+ self.extra_params = extra_params or {}
79
+
80
+ def get_file_extensions_config(self) -> Dict[str, List[str]]:
81
+ """Get allowed file extensions configuration.
82
+
83
+ Modify this dictionary to restrict file extensions per file type.
84
+ Extensions are case-insensitive and must include the dot prefix.
85
+
86
+ Example:
87
+ To allow only MP4 videos::
88
+
89
+ def get_file_extensions_config(self):
90
+ return {
91
+ 'video': ['.mp4'],
92
+ 'image': ['.jpg', '.png'],
93
+ }
94
+
95
+ Returns:
96
+ Dict[str, List[str]]: Mapping of file types to allowed extensions.
97
+ Each key is a file type (e.g., 'video', 'image') and each value
98
+ is a list of allowed extensions (e.g., ['.mp4', '.avi']).
99
+ """
100
+ # Configure allowed extensions here
101
+ # Extensions should include the dot (e.g., '.mp4', not 'mp4')
102
+ return {
103
+ 'video': ['.mp4', '.avi', '.mov', '.mkv', '.webm', '.flv', '.wmv'],
104
+ 'image': ['.jpg', '.jpeg', '.png'],
105
+ 'pcd': ['.pcd'],
106
+ 'text': ['.txt', '.html'],
107
+ 'audio': ['.mp3', '.wav'],
108
+ 'data': ['.xml', '.bin', '.json', '.fbx'],
109
+ }
110
+
111
+ def _log_validation_warning(self, spec_name: str, invalid_extensions: List[str], expected_extensions: List[str]):
112
+ """Log validation warning for invalid file extensions."""
113
+ self.run.log_message(
114
+ f"Validation warning in '{spec_name}': File extensions {invalid_extensions} do not match expected extensions {expected_extensions}. These files will be excluded from upload."
115
+ )
116
+
117
+ def _log_conversion_warning(self, spec_name: str, extension: str, recommended_formats: str):
118
+ """Log conversion warning for file formats that may need conversion."""
119
+ self.run.log_message(
120
+ f"Conversion warning in '{spec_name}': File extension '{extension}' may require conversion to [{recommended_formats}]."
121
+ )
122
+
123
+ def _filter_valid_files(self, files_to_validate: List) -> List:
124
+ """Filter files based on validation criteria.
125
+
126
+ Args:
127
+ files_to_validate: List of organized file dictionaries to validate
128
+
129
+ Returns:
130
+ List: Filtered list containing only valid files
131
+ """
132
+ return files_to_validate # Default: return all files
133
+
134
+ # Abstract methods that should be implemented by subclasses
135
+ def process_files(self, organized_files: List) -> List:
136
+ """Process files. Should be implemented by subclasses."""
137
+ return organized_files
138
+
139
+ def before_process(self, organized_files: List) -> List:
140
+ """Pre-process files before main processing. Can be overridden by subclasses."""
141
+ return organized_files
142
+
143
+ def after_process(self, processed_files: List) -> List:
144
+ """Post-process files after main processing. Can be overridden by subclasses."""
145
+ return processed_files
146
+
147
+ def organize_files(self, files: List) -> List:
148
+ """Organize files. Can be overridden by subclasses."""
149
+ return files
150
+
151
+ def validate_files(self, files: List) -> List:
152
+ """Validate files against allowed extensions and custom rules.
153
+
154
+ This method first validates file types against get_file_extensions_config(),
155
+ then applies custom filtering via _filter_valid_files().
156
+
157
+ Override this method for complete custom validation, or override
158
+ _filter_valid_files() to add additional filtering after extension validation.
159
+ """
160
+ # First, validate file extensions
161
+ files = self.validate_file_types(files)
162
+
163
+ # Then apply custom filtering
164
+ return self._filter_valid_files(files)
165
+
166
+ def setup_directories(self) -> None:
167
+ """Setup custom directories. Can be overridden by subclasses."""
168
+ pass
169
+
170
+ def validate_file_types(self, organized_files: List) -> List:
171
+ """Validate file types against allowed extensions configuration.
172
+
173
+ Filters files based on their extensions according to get_file_extensions_config().
174
+ Files with extensions not matching their file type will be filtered out and logged.
175
+
176
+ Args:
177
+ organized_files (List[Dict]): List of organized file dictionaries.
178
+ Each dict contains a 'files' key mapping spec names to file paths.
179
+
180
+ Returns:
181
+ List[Dict]: Filtered list containing only files with valid extensions.
182
+ Files with disallowed extensions are removed and logged as WARNING.
183
+
184
+ Note:
185
+ Extension matching is case-insensitive (.mp4 == .MP4).
186
+ Filtered files are logged using LogCode.FILES_FILTERED_BY_EXTENSION.
187
+ """
188
+ if not organized_files or not self.file_specification:
189
+ return organized_files
190
+
191
+ valid_files = []
192
+ allowed_extensions_config = self.get_file_extensions_config()
193
+ filtered_by_type = {} # Track filtered files per type
194
+
195
+ for file_group in organized_files:
196
+ files_dict = file_group.get('files', {})
197
+ is_valid_group = True
198
+
199
+ for spec_name, file_path in files_dict.items():
200
+ # Find the specification for this file type
201
+ file_spec = next((s for s in self.file_specification if s['name'] == spec_name), None)
202
+ if not file_spec:
203
+ continue
204
+
205
+ # Handle file path lists
206
+ if isinstance(file_path, list):
207
+ file_path = file_path[0] if file_path else None
208
+
209
+ if file_path is None:
210
+ continue
211
+
212
+ # Get file type and extension
213
+ file_type = file_spec['file_type']
214
+ file_extension = file_path.suffix.lower()
215
+
216
+ # Check if this file type has allowed extensions
217
+ if file_type in allowed_extensions_config:
218
+ allowed_exts = [ext.lower() for ext in allowed_extensions_config[file_type]]
219
+
220
+ if file_extension not in allowed_exts:
221
+ # Track filtered extension
222
+ if file_type not in filtered_by_type:
223
+ filtered_by_type[file_type] = {'extensions': set(), 'count': 0}
224
+ filtered_by_type[file_type]['extensions'].add(
225
+ file_extension if file_extension else '(no extension)'
226
+ )
227
+ filtered_by_type[file_type]['count'] += 1
228
+ is_valid_group = False
229
+ break
230
+
231
+ # Add file group if all files are valid
232
+ if is_valid_group:
233
+ valid_files.append(file_group)
234
+
235
+ # Log filtered files by type
236
+ self._log_filtered_files(filtered_by_type, allowed_extensions_config)
237
+
238
+ return valid_files
239
+
240
+ def _log_filtered_files(self, filtered_by_type: Dict, allowed_config: Dict):
241
+ """Log filtered files by type with detailed information.
242
+
243
+ Args:
244
+ filtered_by_type (Dict[str, Dict]): Filtered file information per type.
245
+ Each entry contains 'extensions' (set) and 'count' (int).
246
+ allowed_config (Dict[str, List[str]]): The allowed extensions configuration
247
+ mapping file types to allowed extension lists.
248
+ """
249
+ from synapse_sdk.plugins.categories.upload.actions.upload.enums import LogCode
250
+
251
+ for file_type, info in filtered_by_type.items():
252
+ if info['count'] > 0:
253
+ extensions_str = ', '.join(sorted(info['extensions']))
254
+ allowed_str = ', '.join(allowed_config.get(file_type, []))
255
+ self.run.log_message_with_code(
256
+ LogCode.FILES_FILTERED_BY_EXTENSION,
257
+ info['count'],
258
+ file_type,
259
+ extensions_str,
260
+ allowed_str,
261
+ )
262
+
263
+ def handle_upload_files(self) -> List:
264
+ """Main upload method that handles the complete upload workflow.
265
+
266
+ This method provides the core workflow for upload plugins:
267
+ setup_directories -> organize_files -> before_process -> process_files ->
268
+ after_process -> validate_files
269
+
270
+ Returns:
271
+ List: The final processed and validated list of files ready for upload.
272
+ """
273
+ # Setup any required directories
274
+ self.setup_directories()
275
+
276
+ # Start with organized files from the workflow
277
+ current_files = self.organized_files
278
+
279
+ # Apply organization logic
280
+ current_files = self.organize_files(current_files)
281
+
282
+ # Pre-process files
283
+ current_files = self.before_process(current_files)
284
+
285
+ # Main processing step
286
+ current_files = self.process_files(current_files)
287
+
288
+ # Post-process files
289
+ current_files = self.after_process(current_files)
290
+
291
+ # Final validation
292
+ current_files = self.validate_files(current_files)
293
+
294
+ return current_files
@@ -0,0 +1,102 @@
1
+ from pathlib import Path
2
+ from typing import Any, Dict, List
3
+
4
+ from . import BaseUploader
5
+
6
+
7
+ class Uploader(BaseUploader):
8
+ """Plugin upload action interface for organizing files.
9
+
10
+ This class provides a template for plugin developers to implement
11
+ their own file organization logic by inheriting from BaseUploader.
12
+
13
+ Important: This plugin extension works with already-organized files from the
14
+ main upload workflow. Files are provided via organized_files parameter regardless
15
+ of whether single-path or multi-path mode was used in the upload configuration.
16
+
17
+ Example usage:
18
+ Override process_files() to implement custom file processing logic.
19
+ Override validate_file_types() to implement custom validation rules.
20
+ Override setup_directories() to create custom directory structures.
21
+ """
22
+
23
+ def __init__(
24
+ self, run, path: Path, file_specification: List = None, organized_files: List = None, extra_params: Dict = None
25
+ ):
26
+ """Initialize the uploader with required parameters.
27
+
28
+ Args:
29
+ run: Plugin run object with logging capabilities.
30
+ path: Path object pointing to the upload target directory.
31
+ - In single-path mode: Base directory path (Path object)
32
+ - In multi-path mode: None (use self.assets_config instead)
33
+ file_specification: List of specifications that define the structure of files to be uploaded.
34
+ organized_files: List of pre-organized files from the main upload workflow.
35
+ Works transparently with both single-path and multi-path modes.
36
+ extra_params: Additional parameters for customization.
37
+ """
38
+ super().__init__(run, path, file_specification, organized_files, extra_params)
39
+
40
+ def process_files(self, organized_files: List) -> List:
41
+ """Process and transform files during upload.
42
+
43
+ Override this method to implement custom file processing logic.
44
+ This is the main method where plugin-specific logic should be implemented.
45
+
46
+ Args:
47
+ organized_files: List of organized file dictionaries from the workflow.
48
+
49
+ Returns:
50
+ List: The processed list of files ready for upload.
51
+ """
52
+ # Default implementation: return files as-is
53
+ # Plugin developers should override this method for custom logic
54
+ return organized_files
55
+
56
+ def validate_file_types(self, organized_files: List) -> List:
57
+ """Validate file types against specifications.
58
+
59
+ This example shows how to use the BaseUploader's comprehensive validation logic.
60
+ You can override this method for custom validation or call super() to use the base implementation.
61
+
62
+ Args:
63
+ organized_files: List of organized file dictionaries to validate.
64
+
65
+ Returns:
66
+ List: Filtered list containing only valid files that match specifications.
67
+ """
68
+ return super().validate_file_types(organized_files)
69
+
70
+ def handle_upload_files(self) -> List[Dict[str, Any]]:
71
+ """Executes the upload task using the base class implementation.
72
+
73
+ Returns:
74
+ List: The final list of organized files ready for upload
75
+ """
76
+ return super().handle_upload_files()
77
+
78
+ def organize_files(self, organized_files: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
79
+ """Transform and organize files based on plugin logic.
80
+
81
+ Override this method to implement custom file organization logic.
82
+
83
+ Args:
84
+ organized_files: List of organized files from the default logic
85
+
86
+ Returns:
87
+ List of transformed organized files
88
+ """
89
+ return organized_files
90
+
91
+ def filter_files(self, organized_file: Dict[str, Any]) -> bool:
92
+ """Filter files based on custom criteria.
93
+
94
+ Override this method to implement custom filtering logic.
95
+
96
+ Args:
97
+ organized_file: Single organized file to filter
98
+
99
+ Returns:
100
+ bool: True to include the file, False to filter it out
101
+ """
102
+ return True
@@ -2,6 +2,8 @@ from enum import Enum
2
2
 
3
3
 
4
4
  class RunMethod(Enum):
5
+ """Plugin Execution Methods."""
6
+
5
7
  JOB = 'job'
6
8
  TASK = 'task'
7
9
  RESTAPI = 'restapi'
@@ -10,7 +12,7 @@ class RunMethod(Enum):
10
12
  class PluginCategory(Enum):
11
13
  NEURAL_NET = 'neural_net'
12
14
  EXPORT = 'export'
13
- IMPORT = 'import'
15
+ UPLOAD = 'upload'
14
16
  SMART_TOOL = 'smart_tool'
15
17
  POST_ANNOTATION = 'post_annotation'
16
18
  PRE_ANNOTATION = 'pre_annotation'
@@ -1,10 +1,15 @@
1
1
  import os
2
+ from datetime import datetime
2
3
  from functools import cached_property
3
4
  from typing import Any, Dict
4
5
 
6
+ from pydantic import BaseModel
7
+
5
8
  from synapse_sdk.clients.backend import BackendClient
9
+ from synapse_sdk.devtools.config import get_backend_config
6
10
  from synapse_sdk.loggers import BackendLogger, ConsoleLogger
7
11
  from synapse_sdk.plugins.utils import read_plugin_config
12
+ from synapse_sdk.shared import needs_sentry_init
8
13
  from synapse_sdk.shared.enums import Context
9
14
  from synapse_sdk.utils.storage import get_storage
10
15
  from synapse_sdk.utils.string import hash_text
@@ -41,6 +46,33 @@ class PluginRelease:
41
46
  def name(self):
42
47
  return self.config['name']
43
48
 
49
+ @cached_property
50
+ def package_manager(self):
51
+ return self.config.get('package_manager', 'pip')
52
+
53
+ @cached_property
54
+ def package_manager_options(self):
55
+ # Get user-defined options from config
56
+ user_options = self.config.get('package_manager_options', [])
57
+
58
+ if self.package_manager == 'uv':
59
+ defaults = ['--no-cache']
60
+ # Add defaults if not already present
61
+ options_list = defaults.copy()
62
+ for option in user_options:
63
+ if option not in options_list:
64
+ options_list.append(option)
65
+ return {'uv_pip_install_options': options_list}
66
+ else:
67
+ # For pip, use pip_install_options with --upgrade flag to ensure
68
+ # packages from requirements.txt (like synapse-sdk) override pre-installed versions
69
+ defaults = ['--upgrade']
70
+ options_list = defaults.copy()
71
+ for option in user_options:
72
+ if option not in options_list:
73
+ options_list.append(option)
74
+ return {'pip_install_options': options_list}
75
+
44
76
  @cached_property
45
77
  def checksum(self):
46
78
  return hash_text(self.code)
@@ -58,6 +90,11 @@ class PluginRelease:
58
90
  def warm_up():
59
91
  pass
60
92
 
93
+ extra_runtime_env = {}
94
+
95
+ if needs_sentry_init():
96
+ extra_runtime_env['worker_process_setup_hook'] = 'synapse_sdk.shared.worker_process_setup_hook'
97
+
61
98
  nodes = list_nodes(address=self.envs['RAY_DASHBOARD_URL'])
62
99
  node_ids = [n['node_id'] for n in nodes]
63
100
  for node_id in node_ids:
@@ -65,8 +102,12 @@ class PluginRelease:
65
102
 
66
103
  warm_up.options(
67
104
  runtime_env={
68
- 'pip': ['-r ${RAY_RUNTIME_ENV_CREATE_WORKING_DIR}/requirements.txt'],
105
+ self.package_manager: {
106
+ 'packages': ['-r ${RAY_RUNTIME_ENV_CREATE_WORKING_DIR}/requirements.txt']
107
+ ** self.package_manager_options
108
+ },
69
109
  'working_dir': self.get_url(self.envs['SYNAPSE_PLUGIN_STORAGE']),
110
+ **extra_runtime_env,
70
111
  },
71
112
  scheduling_strategy=strategy,
72
113
  ).remote()
@@ -83,39 +124,122 @@ class PluginRelease:
83
124
 
84
125
 
85
126
  class Run:
127
+ """Run class for manage plugin run istance.
128
+
129
+ Attrs:
130
+ job_id: plugin run job id
131
+ context: plugin run context
132
+ client: backend client for communicate with backend
133
+ logger: logger for log plugin run events
134
+ """
135
+
86
136
  logger = None
87
137
  job_id = None
88
138
  context = None
139
+ client = None
140
+
141
+ class DevLog(BaseModel):
142
+ """Model for developer log entries.
143
+
144
+ Records custom events and information that plugin developers want to track
145
+ during plugin execution for debugging and monitoring purposes.
89
146
 
90
- def __init__(self, job_id, context):
147
+ Attributes:
148
+ event_type (str): Type/category of the development event
149
+ message (str): Descriptive message about the event
150
+ data (dict | None): Optional additional data/context
151
+ level (Context): Event status/severity level
152
+ created (str): Timestamp when event occurred
153
+ """
154
+
155
+ event_type: str
156
+ message: str
157
+ data: dict | None = None
158
+ level: Context
159
+ created: str
160
+
161
+ def __init__(self, job_id, context=None):
91
162
  self.job_id = job_id
92
- self.context = context
163
+ self.context = context or {}
164
+ config = get_backend_config()
165
+ if config:
166
+ self.client = BackendClient(
167
+ config['host'],
168
+ access_token=config['token'],
169
+ )
170
+ else:
171
+ # Handle missing environment variables for test environments
172
+ envs = self.context.get('envs', {})
173
+ host = envs.get('SYNAPSE_PLUGIN_RUN_HOST', os.getenv('SYNAPSE_PLUGIN_RUN_HOST', 'http://localhost:8000'))
174
+ token = envs.get('SYNAPSE_PLUGIN_RUN_USER_TOKEN', os.getenv('SYNAPSE_PLUGIN_RUN_USER_TOKEN'))
175
+ tenant = envs.get('SYNAPSE_PLUGIN_RUN_TENANT', os.getenv('SYNAPSE_PLUGIN_RUN_TENANT'))
176
+
177
+ self.client = BackendClient(
178
+ host,
179
+ token=token,
180
+ tenant=tenant,
181
+ )
93
182
  self.set_logger()
94
183
 
95
184
  def set_logger(self):
96
- kwargs = {'progress_categories': self.context['progress_categories']}
185
+ kwargs = {
186
+ 'progress_categories': self.context.get('progress_categories'),
187
+ 'metrics_categories': self.context.get('metrics_categories'),
188
+ }
189
+
97
190
  if self.job_id:
98
- client = BackendClient(
99
- self.context['envs']['SYNAPSE_PLUGIN_RUN_HOST'],
100
- self.context['envs']['SYNAPSE_PLUGIN_RUN_USER_TOKEN'],
101
- self.context['envs']['SYNAPSE_PLUGIN_RUN_TENANT'],
102
- )
103
- self.logger = BackendLogger(client, self.job_id, **kwargs)
191
+ self.logger = BackendLogger(self.client, self.job_id, **kwargs)
104
192
  else:
105
193
  self.logger = ConsoleLogger(**kwargs)
106
194
 
107
- @property
108
- def client(self):
109
- return getattr(self.logger, 'client', None)
110
-
111
195
  def set_progress(self, current, total, category=''):
112
196
  self.logger.set_progress(current, total, category)
113
197
 
114
- def log(self, event, data):
115
- self.logger.log(event, data)
198
+ def set_metrics(self, value: Dict[Any, Any], category: str):
199
+ self.logger.set_metrics(value, category)
200
+
201
+ def log(self, event, data, file=None):
202
+ self.logger.log(event, data, file=file)
116
203
 
117
204
  def log_message(self, message, context=Context.INFO.value):
118
205
  self.logger.log('message', {'context': context, 'content': message})
119
206
 
207
+ def log_dev_event(self, message: str, data: dict | None = None, level: Context = Context.INFO):
208
+ """Log development event for plugin developers.
209
+
210
+ This function allows plugin developers to log custom events and information
211
+ during plugin execution for debugging, monitoring, and development purposes.
212
+ The event_type is automatically constructed as '{action_name}_dev_log' and cannot
213
+ be modified by plugin developers.
214
+
215
+ Args:
216
+ message (str): Descriptive message about the event
217
+ data (dict | None): Optional additional data or context to include
218
+ level (Context): Event severity level (INFO, WARNING, DANGER, SUCCESS)
219
+
220
+ Example:
221
+ >>> run = Run(job_id, context)
222
+ >>> run.log_dev_event('Data validation completed', {'records_count': 100})
223
+ >>> run.log_dev_event('Processing time recorded', {'duration_ms': 1500})
224
+ >>> run.log_dev_event('Variable state at checkpoint', {'variable_x': 42}, level=Context.WARNING)
225
+ """
226
+ # Construct event_type from action name - this cannot be modified by developers
227
+ action_name = self.context.get('action_name', 'unknown')
228
+ event_type = f'{action_name}_dev_log'
229
+
230
+ # Log the structured event for development tracking only
231
+ # Do NOT use log_message to avoid showing debug logs to end users
232
+ now = datetime.now().isoformat()
233
+ self.log(
234
+ 'dev_event',
235
+ self.DevLog(
236
+ event_type=event_type,
237
+ message=message,
238
+ data=data,
239
+ level=level,
240
+ created=now,
241
+ ).model_dump(),
242
+ )
243
+
120
244
  def end_log(self):
121
245
  self.log_message('Plugin run is complete.')