synapse-sdk 1.0.0a11__py3-none-any.whl → 2026.1.1b2__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 (261) hide show
  1. synapse_sdk/__init__.py +24 -0
  2. synapse_sdk/cli/__init__.py +9 -8
  3. synapse_sdk/cli/agent/__init__.py +25 -0
  4. synapse_sdk/cli/agent/config.py +104 -0
  5. synapse_sdk/cli/agent/select.py +197 -0
  6. synapse_sdk/cli/auth.py +104 -0
  7. synapse_sdk/cli/main.py +1025 -0
  8. synapse_sdk/cli/plugin/__init__.py +58 -0
  9. synapse_sdk/cli/plugin/create.py +566 -0
  10. synapse_sdk/cli/plugin/job.py +196 -0
  11. synapse_sdk/cli/plugin/publish.py +322 -0
  12. synapse_sdk/cli/plugin/run.py +131 -0
  13. synapse_sdk/cli/plugin/test.py +200 -0
  14. synapse_sdk/clients/README.md +239 -0
  15. synapse_sdk/clients/__init__.py +5 -0
  16. synapse_sdk/clients/_template.py +266 -0
  17. synapse_sdk/clients/agent/__init__.py +84 -29
  18. synapse_sdk/clients/agent/async_ray.py +289 -0
  19. synapse_sdk/clients/agent/container.py +83 -0
  20. synapse_sdk/clients/agent/plugin.py +101 -0
  21. synapse_sdk/clients/agent/ray.py +296 -39
  22. synapse_sdk/clients/backend/__init__.py +152 -12
  23. synapse_sdk/clients/backend/annotation.py +164 -22
  24. synapse_sdk/clients/backend/core.py +101 -0
  25. synapse_sdk/clients/backend/data_collection.py +292 -0
  26. synapse_sdk/clients/backend/hitl.py +87 -0
  27. synapse_sdk/clients/backend/integration.py +374 -46
  28. synapse_sdk/clients/backend/ml.py +134 -22
  29. synapse_sdk/clients/backend/models.py +247 -0
  30. synapse_sdk/clients/base.py +538 -59
  31. synapse_sdk/clients/exceptions.py +35 -7
  32. synapse_sdk/clients/pipeline/__init__.py +5 -0
  33. synapse_sdk/clients/pipeline/client.py +636 -0
  34. synapse_sdk/clients/protocols.py +178 -0
  35. synapse_sdk/clients/utils.py +86 -8
  36. synapse_sdk/clients/validation.py +58 -0
  37. synapse_sdk/enums.py +76 -0
  38. synapse_sdk/exceptions.py +168 -0
  39. synapse_sdk/integrations/__init__.py +74 -0
  40. synapse_sdk/integrations/_base.py +119 -0
  41. synapse_sdk/integrations/_context.py +53 -0
  42. synapse_sdk/integrations/ultralytics/__init__.py +78 -0
  43. synapse_sdk/integrations/ultralytics/_callbacks.py +126 -0
  44. synapse_sdk/integrations/ultralytics/_patches.py +124 -0
  45. synapse_sdk/loggers.py +476 -95
  46. synapse_sdk/mcp/MCP.md +69 -0
  47. synapse_sdk/mcp/__init__.py +48 -0
  48. synapse_sdk/mcp/__main__.py +6 -0
  49. synapse_sdk/mcp/config.py +349 -0
  50. synapse_sdk/mcp/prompts/__init__.py +4 -0
  51. synapse_sdk/mcp/resources/__init__.py +4 -0
  52. synapse_sdk/mcp/server.py +1352 -0
  53. synapse_sdk/mcp/tools/__init__.py +6 -0
  54. synapse_sdk/plugins/__init__.py +133 -9
  55. synapse_sdk/plugins/action.py +229 -0
  56. synapse_sdk/plugins/actions/__init__.py +82 -0
  57. synapse_sdk/plugins/actions/dataset/__init__.py +37 -0
  58. synapse_sdk/plugins/actions/dataset/action.py +471 -0
  59. synapse_sdk/plugins/actions/export/__init__.py +55 -0
  60. synapse_sdk/plugins/actions/export/action.py +183 -0
  61. synapse_sdk/plugins/actions/export/context.py +59 -0
  62. synapse_sdk/plugins/actions/inference/__init__.py +84 -0
  63. synapse_sdk/plugins/actions/inference/action.py +285 -0
  64. synapse_sdk/plugins/actions/inference/context.py +81 -0
  65. synapse_sdk/plugins/actions/inference/deployment.py +322 -0
  66. synapse_sdk/plugins/actions/inference/serve.py +252 -0
  67. synapse_sdk/plugins/actions/train/__init__.py +54 -0
  68. synapse_sdk/plugins/actions/train/action.py +326 -0
  69. synapse_sdk/plugins/actions/train/context.py +57 -0
  70. synapse_sdk/plugins/actions/upload/__init__.py +49 -0
  71. synapse_sdk/plugins/actions/upload/action.py +165 -0
  72. synapse_sdk/plugins/actions/upload/context.py +61 -0
  73. synapse_sdk/plugins/config.py +98 -0
  74. synapse_sdk/plugins/context/__init__.py +109 -0
  75. synapse_sdk/plugins/context/env.py +113 -0
  76. synapse_sdk/plugins/datasets/__init__.py +113 -0
  77. synapse_sdk/plugins/datasets/converters/__init__.py +76 -0
  78. synapse_sdk/plugins/datasets/converters/base.py +347 -0
  79. synapse_sdk/plugins/datasets/converters/yolo/__init__.py +9 -0
  80. synapse_sdk/plugins/datasets/converters/yolo/from_dm.py +468 -0
  81. synapse_sdk/plugins/datasets/converters/yolo/to_dm.py +381 -0
  82. synapse_sdk/plugins/datasets/formats/__init__.py +82 -0
  83. synapse_sdk/plugins/datasets/formats/dm.py +351 -0
  84. synapse_sdk/plugins/datasets/formats/yolo.py +240 -0
  85. synapse_sdk/plugins/decorators.py +83 -0
  86. synapse_sdk/plugins/discovery.py +790 -0
  87. synapse_sdk/plugins/docs/ACTION_DEV_GUIDE.md +933 -0
  88. synapse_sdk/plugins/docs/ARCHITECTURE.md +1225 -0
  89. synapse_sdk/plugins/docs/LOGGING_SYSTEM.md +683 -0
  90. synapse_sdk/plugins/docs/OVERVIEW.md +531 -0
  91. synapse_sdk/plugins/docs/PIPELINE_GUIDE.md +145 -0
  92. synapse_sdk/plugins/docs/README.md +513 -0
  93. synapse_sdk/plugins/docs/STEP.md +656 -0
  94. synapse_sdk/plugins/enums.py +70 -10
  95. synapse_sdk/plugins/errors.py +92 -0
  96. synapse_sdk/plugins/executors/__init__.py +43 -0
  97. synapse_sdk/plugins/executors/local.py +99 -0
  98. synapse_sdk/plugins/executors/ray/__init__.py +18 -0
  99. synapse_sdk/plugins/executors/ray/base.py +282 -0
  100. synapse_sdk/plugins/executors/ray/job.py +298 -0
  101. synapse_sdk/plugins/executors/ray/jobs_api.py +511 -0
  102. synapse_sdk/plugins/executors/ray/packaging.py +137 -0
  103. synapse_sdk/plugins/executors/ray/pipeline.py +792 -0
  104. synapse_sdk/plugins/executors/ray/task.py +257 -0
  105. synapse_sdk/plugins/models/__init__.py +26 -0
  106. synapse_sdk/plugins/models/logger.py +173 -0
  107. synapse_sdk/plugins/models/pipeline.py +25 -0
  108. synapse_sdk/plugins/pipelines/__init__.py +81 -0
  109. synapse_sdk/plugins/pipelines/action_pipeline.py +417 -0
  110. synapse_sdk/plugins/pipelines/context.py +107 -0
  111. synapse_sdk/plugins/pipelines/display.py +311 -0
  112. synapse_sdk/plugins/runner.py +114 -0
  113. synapse_sdk/plugins/schemas/__init__.py +19 -0
  114. synapse_sdk/plugins/schemas/results.py +152 -0
  115. synapse_sdk/plugins/steps/__init__.py +63 -0
  116. synapse_sdk/plugins/steps/base.py +128 -0
  117. synapse_sdk/plugins/steps/context.py +90 -0
  118. synapse_sdk/plugins/steps/orchestrator.py +128 -0
  119. synapse_sdk/plugins/steps/registry.py +103 -0
  120. synapse_sdk/plugins/steps/utils/__init__.py +20 -0
  121. synapse_sdk/plugins/steps/utils/logging.py +85 -0
  122. synapse_sdk/plugins/steps/utils/timing.py +71 -0
  123. synapse_sdk/plugins/steps/utils/validation.py +68 -0
  124. synapse_sdk/plugins/templates/__init__.py +50 -0
  125. synapse_sdk/plugins/templates/base/.gitignore.j2 +26 -0
  126. synapse_sdk/plugins/templates/base/.synapseignore.j2 +11 -0
  127. synapse_sdk/plugins/templates/base/README.md.j2 +26 -0
  128. synapse_sdk/plugins/templates/base/plugin/__init__.py.j2 +1 -0
  129. synapse_sdk/plugins/templates/base/pyproject.toml.j2 +14 -0
  130. synapse_sdk/plugins/templates/base/requirements.txt.j2 +1 -0
  131. synapse_sdk/plugins/templates/custom/plugin/main.py.j2 +18 -0
  132. synapse_sdk/plugins/templates/data_validation/plugin/validate.py.j2 +32 -0
  133. synapse_sdk/plugins/templates/export/plugin/export.py.j2 +36 -0
  134. synapse_sdk/plugins/templates/neural_net/plugin/inference.py.j2 +36 -0
  135. synapse_sdk/plugins/templates/neural_net/plugin/train.py.j2 +33 -0
  136. synapse_sdk/plugins/templates/post_annotation/plugin/post_annotate.py.j2 +32 -0
  137. synapse_sdk/plugins/templates/pre_annotation/plugin/pre_annotate.py.j2 +32 -0
  138. synapse_sdk/plugins/templates/smart_tool/plugin/auto_label.py.j2 +44 -0
  139. synapse_sdk/plugins/templates/upload/plugin/upload.py.j2 +35 -0
  140. synapse_sdk/plugins/testing/__init__.py +25 -0
  141. synapse_sdk/plugins/testing/sample_actions.py +98 -0
  142. synapse_sdk/plugins/types.py +206 -0
  143. synapse_sdk/plugins/upload.py +595 -64
  144. synapse_sdk/plugins/utils.py +325 -37
  145. synapse_sdk/shared/__init__.py +25 -0
  146. synapse_sdk/utils/__init__.py +1 -0
  147. synapse_sdk/utils/auth.py +74 -0
  148. synapse_sdk/utils/file/__init__.py +58 -0
  149. synapse_sdk/utils/file/archive.py +449 -0
  150. synapse_sdk/utils/file/checksum.py +167 -0
  151. synapse_sdk/utils/file/download.py +286 -0
  152. synapse_sdk/utils/file/io.py +129 -0
  153. synapse_sdk/utils/file/requirements.py +36 -0
  154. synapse_sdk/utils/network.py +168 -0
  155. synapse_sdk/utils/storage/__init__.py +238 -0
  156. synapse_sdk/utils/storage/config.py +188 -0
  157. synapse_sdk/utils/storage/errors.py +52 -0
  158. synapse_sdk/utils/storage/providers/__init__.py +13 -0
  159. synapse_sdk/utils/storage/providers/base.py +76 -0
  160. synapse_sdk/utils/storage/providers/gcs.py +168 -0
  161. synapse_sdk/utils/storage/providers/http.py +250 -0
  162. synapse_sdk/utils/storage/providers/local.py +126 -0
  163. synapse_sdk/utils/storage/providers/s3.py +177 -0
  164. synapse_sdk/utils/storage/providers/sftp.py +208 -0
  165. synapse_sdk/utils/storage/registry.py +125 -0
  166. synapse_sdk/utils/websocket.py +99 -0
  167. synapse_sdk-2026.1.1b2.dist-info/METADATA +715 -0
  168. synapse_sdk-2026.1.1b2.dist-info/RECORD +172 -0
  169. {synapse_sdk-1.0.0a11.dist-info → synapse_sdk-2026.1.1b2.dist-info}/WHEEL +1 -1
  170. synapse_sdk-2026.1.1b2.dist-info/licenses/LICENSE +201 -0
  171. locale/en/LC_MESSAGES/messages.mo +0 -0
  172. locale/en/LC_MESSAGES/messages.po +0 -39
  173. locale/ko/LC_MESSAGES/messages.mo +0 -0
  174. locale/ko/LC_MESSAGES/messages.po +0 -34
  175. synapse_sdk/cli/create_plugin.py +0 -10
  176. synapse_sdk/clients/agent/core.py +0 -7
  177. synapse_sdk/clients/agent/service.py +0 -15
  178. synapse_sdk/clients/backend/dataset.py +0 -51
  179. synapse_sdk/clients/ray/__init__.py +0 -6
  180. synapse_sdk/clients/ray/core.py +0 -22
  181. synapse_sdk/clients/ray/serve.py +0 -20
  182. synapse_sdk/i18n.py +0 -35
  183. synapse_sdk/plugins/categories/__init__.py +0 -0
  184. synapse_sdk/plugins/categories/base.py +0 -235
  185. synapse_sdk/plugins/categories/data_validation/__init__.py +0 -0
  186. synapse_sdk/plugins/categories/data_validation/actions/__init__.py +0 -0
  187. synapse_sdk/plugins/categories/data_validation/actions/validation.py +0 -10
  188. synapse_sdk/plugins/categories/data_validation/templates/config.yaml +0 -3
  189. synapse_sdk/plugins/categories/data_validation/templates/plugin/__init__.py +0 -0
  190. synapse_sdk/plugins/categories/data_validation/templates/plugin/validation.py +0 -5
  191. synapse_sdk/plugins/categories/decorators.py +0 -13
  192. synapse_sdk/plugins/categories/export/__init__.py +0 -0
  193. synapse_sdk/plugins/categories/export/actions/__init__.py +0 -0
  194. synapse_sdk/plugins/categories/export/actions/export.py +0 -10
  195. synapse_sdk/plugins/categories/import/__init__.py +0 -0
  196. synapse_sdk/plugins/categories/import/actions/__init__.py +0 -0
  197. synapse_sdk/plugins/categories/import/actions/import.py +0 -10
  198. synapse_sdk/plugins/categories/neural_net/__init__.py +0 -0
  199. synapse_sdk/plugins/categories/neural_net/actions/__init__.py +0 -0
  200. synapse_sdk/plugins/categories/neural_net/actions/deployment.py +0 -45
  201. synapse_sdk/plugins/categories/neural_net/actions/inference.py +0 -18
  202. synapse_sdk/plugins/categories/neural_net/actions/test.py +0 -10
  203. synapse_sdk/plugins/categories/neural_net/actions/train.py +0 -143
  204. synapse_sdk/plugins/categories/neural_net/templates/config.yaml +0 -12
  205. synapse_sdk/plugins/categories/neural_net/templates/plugin/__init__.py +0 -0
  206. synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py +0 -4
  207. synapse_sdk/plugins/categories/neural_net/templates/plugin/test.py +0 -2
  208. synapse_sdk/plugins/categories/neural_net/templates/plugin/train.py +0 -14
  209. synapse_sdk/plugins/categories/post_annotation/__init__.py +0 -0
  210. synapse_sdk/plugins/categories/post_annotation/actions/__init__.py +0 -0
  211. synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py +0 -10
  212. synapse_sdk/plugins/categories/post_annotation/templates/config.yaml +0 -3
  213. synapse_sdk/plugins/categories/post_annotation/templates/plugin/__init__.py +0 -0
  214. synapse_sdk/plugins/categories/post_annotation/templates/plugin/post_annotation.py +0 -3
  215. synapse_sdk/plugins/categories/pre_annotation/__init__.py +0 -0
  216. synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py +0 -0
  217. synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py +0 -10
  218. synapse_sdk/plugins/categories/pre_annotation/templates/config.yaml +0 -3
  219. synapse_sdk/plugins/categories/pre_annotation/templates/plugin/__init__.py +0 -0
  220. synapse_sdk/plugins/categories/pre_annotation/templates/plugin/pre_annotation.py +0 -3
  221. synapse_sdk/plugins/categories/registry.py +0 -16
  222. synapse_sdk/plugins/categories/smart_tool/__init__.py +0 -0
  223. synapse_sdk/plugins/categories/smart_tool/actions/__init__.py +0 -0
  224. synapse_sdk/plugins/categories/smart_tool/actions/auto_label.py +0 -37
  225. synapse_sdk/plugins/categories/smart_tool/templates/config.yaml +0 -7
  226. synapse_sdk/plugins/categories/smart_tool/templates/plugin/__init__.py +0 -0
  227. synapse_sdk/plugins/categories/smart_tool/templates/plugin/auto_label.py +0 -11
  228. synapse_sdk/plugins/categories/templates.py +0 -32
  229. synapse_sdk/plugins/cli/__init__.py +0 -21
  230. synapse_sdk/plugins/cli/publish.py +0 -37
  231. synapse_sdk/plugins/cli/run.py +0 -67
  232. synapse_sdk/plugins/exceptions.py +0 -22
  233. synapse_sdk/plugins/models.py +0 -121
  234. synapse_sdk/plugins/templates/cookiecutter.json +0 -11
  235. synapse_sdk/plugins/templates/hooks/post_gen_project.py +0 -3
  236. synapse_sdk/plugins/templates/hooks/pre_prompt.py +0 -21
  237. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.env +0 -24
  238. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.env.dist +0 -24
  239. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.gitignore +0 -27
  240. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.pre-commit-config.yaml +0 -7
  241. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/README.md +0 -5
  242. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml +0 -6
  243. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/main.py +0 -4
  244. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/plugin/__init__.py +0 -0
  245. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml +0 -13
  246. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/requirements.txt +0 -1
  247. synapse_sdk/shared/enums.py +0 -8
  248. synapse_sdk/utils/debug.py +0 -5
  249. synapse_sdk/utils/file.py +0 -87
  250. synapse_sdk/utils/module_loading.py +0 -29
  251. synapse_sdk/utils/pydantic/__init__.py +0 -0
  252. synapse_sdk/utils/pydantic/config.py +0 -4
  253. synapse_sdk/utils/pydantic/errors.py +0 -33
  254. synapse_sdk/utils/pydantic/validators.py +0 -7
  255. synapse_sdk/utils/storage.py +0 -91
  256. synapse_sdk/utils/string.py +0 -11
  257. synapse_sdk-1.0.0a11.dist-info/LICENSE +0 -21
  258. synapse_sdk-1.0.0a11.dist-info/METADATA +0 -43
  259. synapse_sdk-1.0.0a11.dist-info/RECORD +0 -111
  260. {synapse_sdk-1.0.0a11.dist-info → synapse_sdk-2026.1.1b2.dist-info}/entry_points.txt +0 -0
  261. {synapse_sdk-1.0.0a11.dist-info → synapse_sdk-2026.1.1b2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,531 @@
1
+ # Plugin System Overview
2
+
3
+ The Synapse SDK Plugin System is a comprehensive framework for building, discovering, and executing plugin actions. It provides a flexible architecture for creating reusable components that can run locally or distributed across Ray clusters.
4
+
5
+ ## Target Audience
6
+
7
+ This documentation is for **plugin system developers** who need to:
8
+ - Create custom plugin actions for ML training, export, upload, inference, etc.
9
+ - Understand the plugin architecture for extension and customization
10
+ - Build step-based workflows with progress tracking and rollback support
11
+
12
+ ## Prerequisites
13
+
14
+ - Python 3.12+
15
+ - Familiarity with Pydantic v2 for data validation
16
+ - Basic understanding of async/await patterns (for Ray execution)
17
+
18
+ ---
19
+
20
+ ## Key Concepts
21
+
22
+ ### Actions
23
+
24
+ Actions are the fundamental units of work in the plugin system. Each action:
25
+ - Receives typed parameters (Pydantic models)
26
+ - Has access to a runtime context (logger, environment, clients)
27
+ - Produces a result (optionally typed)
28
+
29
+ ```python
30
+ from synapse_sdk.plugins import BaseAction
31
+ from pydantic import BaseModel
32
+
33
+ class TrainParams(BaseModel):
34
+ epochs: int = 10
35
+ learning_rate: float = 0.001
36
+
37
+ class TrainAction(BaseAction[TrainParams]):
38
+ def execute(self) -> dict:
39
+ for epoch in range(self.params.epochs):
40
+ self.set_progress(epoch + 1, self.params.epochs)
41
+ # Training logic here
42
+ return {'status': 'completed'}
43
+ ```
44
+
45
+ ### Contexts
46
+
47
+ Contexts provide runtime services and shared state:
48
+
49
+ - **RuntimeContext**: Injected into all actions, provides logger, environment, job tracking
50
+ - **BaseStepContext**: Extended by step-based workflows to share state between steps
51
+ - **Specialized Contexts**: TrainContext, UploadContext, etc. for domain-specific state
52
+
53
+ ### Steps
54
+
55
+ Steps are composable workflow building blocks for multi-phase operations:
56
+
57
+ ```python
58
+ from synapse_sdk.plugins.steps import BaseStep, StepResult
59
+
60
+ class LoadDataStep(BaseStep[MyContext]):
61
+ @property
62
+ def name(self) -> str:
63
+ return 'load_data'
64
+
65
+ @property
66
+ def progress_weight(self) -> float:
67
+ return 0.3 # 30% of total progress
68
+
69
+ def execute(self, context: MyContext) -> StepResult:
70
+ context.data = load_data()
71
+ return StepResult(success=True)
72
+ ```
73
+
74
+ ### Executors
75
+
76
+ Executors determine where and how actions run:
77
+
78
+ | Executor | Use Case | Startup Time |
79
+ |----------|----------|--------------|
80
+ | `LocalExecutor` | Development, testing | Instant |
81
+ | `RayActorExecutor` | Light parallel tasks | <1 second |
82
+ | `RayJobExecutor` | Heavy workloads, isolation | ~30 seconds |
83
+ | `RayPipelineExecutor` | Multi-action workflows | Variable |
84
+
85
+ ### Discovery
86
+
87
+ Plugin discovery loads actions from:
88
+ - **Config files**: `config.yaml` with action metadata
89
+ - **Python modules**: Scans for `@action` decorators and `BaseAction` subclasses
90
+ - **AST scanning**: Static analysis without import failures
91
+
92
+ ---
93
+
94
+ ## Tutorial: Creating Your First Plugin
95
+
96
+ This tutorial walks through creating a complete plugin from scratch.
97
+
98
+ ### Step 1: Define Parameters Model
99
+
100
+ Create a Pydantic model for your action's input parameters:
101
+
102
+ ```python
103
+ # my_plugin/params.py
104
+ from pydantic import BaseModel, Field
105
+
106
+ class ProcessParams(BaseModel):
107
+ """Parameters for the process action."""
108
+
109
+ input_path: str = Field(..., description='Path to input file')
110
+ output_path: str = Field(..., description='Path to output file')
111
+ batch_size: int = Field(default=32, ge=1, le=1024)
112
+ verbose: bool = False
113
+ ```
114
+
115
+ ### Step 2: Create Action Class
116
+
117
+ Implement your action by subclassing `BaseAction`:
118
+
119
+ ```python
120
+ # my_plugin/actions.py
121
+ from synapse_sdk.plugins import BaseAction
122
+ from synapse_sdk.plugins.enums import PluginCategory
123
+ from my_plugin.params import ProcessParams
124
+
125
+ class ProcessAction(BaseAction[ProcessParams]):
126
+ """Process files with progress tracking."""
127
+
128
+ action_name = 'process'
129
+ category = PluginCategory.CUSTOM
130
+
131
+ def execute(self) -> dict:
132
+ # Access validated parameters
133
+ input_path = self.params.input_path
134
+ output_path = self.params.output_path
135
+
136
+ # Log events
137
+ self.log('process_start', {'input': input_path})
138
+
139
+ # Simulate processing with progress
140
+ total_items = 100
141
+ for i in range(total_items):
142
+ # Update progress (current, total)
143
+ self.set_progress(i + 1, total_items)
144
+
145
+ if self.params.verbose:
146
+ self.log('item_processed', {'index': i})
147
+
148
+ # Log metrics
149
+ self.set_metrics({'items_processed': total_items}, category='process')
150
+
151
+ # Return result
152
+ return {
153
+ 'status': 'completed',
154
+ 'output_path': output_path,
155
+ 'items_processed': total_items,
156
+ }
157
+ ```
158
+
159
+ ### Step 3: Write config.yaml
160
+
161
+ Create a configuration file for your plugin:
162
+
163
+ ```yaml
164
+ # my_plugin/config.yaml
165
+ name: My Plugin
166
+ code: my_plugin
167
+ version: 0.1.0
168
+ category: custom
169
+
170
+ actions:
171
+ process:
172
+ name: Process Files
173
+ description: Process input files with batch processing
174
+ entrypoint: my_plugin.actions:ProcessAction
175
+ method: task
176
+ ```
177
+
178
+ ### Step 4: Run Locally
179
+
180
+ Execute your action using `run_plugin`:
181
+
182
+ ```python
183
+ # run.py
184
+ from synapse_sdk.plugins import run_plugin
185
+
186
+ result = run_plugin(
187
+ plugin_code='my_plugin', # Module path
188
+ action='process',
189
+ params={
190
+ 'input_path': '/data/input.csv',
191
+ 'output_path': '/data/output.csv',
192
+ 'batch_size': 64,
193
+ 'verbose': True,
194
+ },
195
+ mode='local', # Run in current process
196
+ )
197
+
198
+ print(f"Result: {result}")
199
+ # Output: Result: {'status': 'completed', 'output_path': '/data/output.csv', 'items_processed': 100}
200
+ ```
201
+
202
+ ### Step 5: Add Result Schema (Optional)
203
+
204
+ For typed results, create a result model:
205
+
206
+ ```python
207
+ # my_plugin/results.py
208
+ from pydantic import BaseModel
209
+
210
+ class ProcessResult(BaseModel):
211
+ """Typed result for process action."""
212
+ status: str
213
+ output_path: str
214
+ items_processed: int
215
+ ```
216
+
217
+ Then update your action:
218
+
219
+ ```python
220
+ # my_plugin/actions.py
221
+ from my_plugin.results import ProcessResult
222
+
223
+ class ProcessAction(BaseAction[ProcessParams]):
224
+ result_model = ProcessResult # Enable result validation
225
+
226
+ def execute(self) -> ProcessResult:
227
+ # ... processing logic ...
228
+ return ProcessResult(
229
+ status='completed',
230
+ output_path=self.params.output_path,
231
+ items_processed=total_items,
232
+ )
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Two Ways to Define Actions
238
+
239
+ ### Class-Based Actions (Recommended for Complex Actions)
240
+
241
+ Use `BaseAction` subclass for:
242
+ - Complex actions with multiple methods
243
+ - Actions that need class attributes (input_type, output_type)
244
+ - Step-based workflows
245
+ - Actions requiring autolog integration
246
+
247
+ ```python
248
+ from synapse_sdk.plugins import BaseAction
249
+ from synapse_sdk.plugins.enums import PluginCategory
250
+ from synapse_sdk.plugins.types import YOLODataset, ModelWeights
251
+
252
+ class TrainAction(BaseAction[TrainParams]):
253
+ """Train a YOLO model with comprehensive features."""
254
+
255
+ # Optional class attributes
256
+ action_name = 'train'
257
+ category = PluginCategory.NEURAL_NET
258
+ input_type = YOLODataset # Semantic input type
259
+ output_type = ModelWeights # Semantic output type
260
+ result_model = TrainResult # Typed result schema
261
+
262
+ def execute(self) -> TrainResult:
263
+ # Enable automatic logging for Ultralytics
264
+ self.autolog('ultralytics')
265
+
266
+ # Access environment variables
267
+ api_key = self.ctx.env.get('API_KEY', '')
268
+
269
+ # Use the logger
270
+ self.logger.info('Starting training')
271
+
272
+ # Training implementation
273
+ model = train_model(self.params)
274
+
275
+ return TrainResult(
276
+ weights_path=model.path,
277
+ final_loss=model.loss,
278
+ )
279
+ ```
280
+
281
+ ### Function-Based Actions (Simple Actions)
282
+
283
+ Use `@action` decorator for:
284
+ - Simple, stateless operations
285
+ - Quick prototyping
286
+ - Actions without complex dependencies
287
+
288
+ ```python
289
+ from synapse_sdk.plugins import action
290
+ from synapse_sdk.plugins.context import RuntimeContext
291
+ from pydantic import BaseModel
292
+
293
+ class ConvertParams(BaseModel):
294
+ input_format: str
295
+ output_format: str
296
+ file_path: str
297
+
298
+ class ConvertResult(BaseModel):
299
+ output_path: str
300
+ converted: bool
301
+
302
+ @action(
303
+ name='convert',
304
+ description='Convert file between formats',
305
+ params=ConvertParams,
306
+ result=ConvertResult,
307
+ )
308
+ def convert(params: ConvertParams, context: RuntimeContext) -> ConvertResult:
309
+ """Convert a file from one format to another."""
310
+
311
+ # Log progress
312
+ context.set_progress(0, 100)
313
+
314
+ # Conversion logic
315
+ output_path = convert_file(
316
+ params.file_path,
317
+ params.input_format,
318
+ params.output_format,
319
+ )
320
+
321
+ context.set_progress(100, 100)
322
+
323
+ return ConvertResult(
324
+ output_path=output_path,
325
+ converted=True,
326
+ )
327
+ ```
328
+
329
+ ### Comparison: When to Use Each
330
+
331
+ | Aspect | Class-Based (`BaseAction`) | Function-Based (`@action`) |
332
+ |--------|---------------------------|---------------------------|
333
+ | Complexity | Complex, multi-method | Simple, single function |
334
+ | State | Can have instance state | Stateless |
335
+ | Type declarations | `input_type`, `output_type` | Not supported |
336
+ | Autolog | `self.autolog()` | Not available |
337
+ | Step workflows | Supported via mixins | Not supported |
338
+ | Testing | Easier mocking | Direct function calls |
339
+ | Config discovery | Full introspection | Limited metadata |
340
+
341
+ ---
342
+
343
+ ## Plugin Categories
344
+
345
+ Plugins are organized into categories for management and UI presentation:
346
+
347
+ | Category | Value | Description | Example Use Cases |
348
+ |----------|-------|-------------|-------------------|
349
+ | Neural Net | `neural_net` | ML model training | YOLO training, classification |
350
+ | Export | `export` | Model conversion/export | ONNX export, TensorRT |
351
+ | Upload | `upload` | Data/model uploads | S3 upload, model registry |
352
+ | Smart Tool | `smart_tool` | Interactive annotation | Auto-labeling, SAM |
353
+ | Pre-Annotation | `pre_annotation` | Before annotation | Data preprocessing |
354
+ | Post-Annotation | `post_annotation` | After annotation | QA checks, format conversion |
355
+ | Data Validation | `data_validation` | Data quality checks | Schema validation |
356
+ | Custom | `custom` | Custom functionality | Anything else |
357
+
358
+ Usage in actions:
359
+
360
+ ```python
361
+ from synapse_sdk.plugins.enums import PluginCategory
362
+
363
+ class MyAction(BaseAction[MyParams]):
364
+ category = PluginCategory.NEURAL_NET
365
+ ```
366
+
367
+ ---
368
+
369
+ ## Execution Modes
370
+
371
+ ### Local Execution
372
+
373
+ Best for development and testing. Runs in the current process:
374
+
375
+ ```python
376
+ from synapse_sdk.plugins import run_plugin
377
+
378
+ result = run_plugin(
379
+ plugin_code='my_plugin',
380
+ action='train',
381
+ params={'epochs': 10},
382
+ mode='local',
383
+ )
384
+ ```
385
+
386
+ Or using the executor directly:
387
+
388
+ ```python
389
+ from synapse_sdk.plugins.executors import LocalExecutor
390
+
391
+ executor = LocalExecutor(
392
+ env={'DEBUG': 'true'}, # Environment variables
393
+ job_id='test-123', # Optional job tracking ID
394
+ )
395
+
396
+ result = executor.execute(
397
+ action_cls=TrainAction,
398
+ params={'epochs': 10},
399
+ )
400
+ ```
401
+
402
+ ### Ray Task Execution
403
+
404
+ For parallel tasks with fast startup. Uses Ray Actors:
405
+
406
+ ```python
407
+ from synapse_sdk.plugins.executors.ray import RayActorExecutor
408
+
409
+ executor = RayActorExecutor(
410
+ working_dir='/path/to/plugin', # Plugin code directory
411
+ num_gpus=1, # GPU allocation
412
+ num_cpus=4, # CPU allocation
413
+ )
414
+
415
+ result = executor.execute(
416
+ action_cls=TrainAction,
417
+ params={'epochs': 10},
418
+ )
419
+
420
+ # Clean up when done
421
+ executor.shutdown()
422
+ ```
423
+
424
+ ### Ray Job Execution
425
+
426
+ For heavy workloads requiring full isolation:
427
+
428
+ ```python
429
+ from synapse_sdk.plugins.executors.ray import RayJobExecutor
430
+
431
+ executor = RayJobExecutor(
432
+ dashboard_url='http://localhost:8265',
433
+ working_dir='/path/to/plugin',
434
+ )
435
+
436
+ # Submit job (async)
437
+ job_id = executor.submit('train', {'epochs': 100})
438
+
439
+ # Check status
440
+ status = executor.get_status(job_id)
441
+ print(f"Status: {status}") # PENDING, RUNNING, SUCCEEDED, FAILED
442
+
443
+ # Get logs
444
+ logs = executor.get_logs(job_id)
445
+
446
+ # Wait for completion
447
+ result = executor.wait(job_id, timeout_seconds=3600)
448
+ ```
449
+
450
+ ### Execution Mode Comparison
451
+
452
+ | Mode | Startup | Isolation | Best For |
453
+ |------|---------|-----------|----------|
454
+ | `local` | Instant | None | Development, testing |
455
+ | `task` | <1s | Process | Light parallel tasks |
456
+ | `job` | ~30s | Full | Production, heavy workloads |
457
+
458
+ ---
459
+
460
+ ## RuntimeContext Reference
461
+
462
+ All actions receive a `RuntimeContext` with these capabilities:
463
+
464
+ ```python
465
+ def execute(self) -> dict:
466
+ # Access the logger
467
+ self.ctx.logger.info('Processing started')
468
+
469
+ # Access environment variables
470
+ api_key = self.ctx.env.get('API_KEY')
471
+ debug = self.ctx.env.get('DEBUG', 'false') == 'true'
472
+
473
+ # Log structured events
474
+ self.ctx.log('event_name', {'key': 'value'})
475
+
476
+ # Track progress
477
+ self.ctx.set_progress(current=50, total=100, category='training')
478
+
479
+ # Record metrics
480
+ self.ctx.set_metrics({'loss': 0.05, 'accuracy': 0.95}, category='train')
481
+
482
+ # Log user-visible messages
483
+ self.ctx.log_message('Training complete!')
484
+
485
+ # Log developer debug events
486
+ self.ctx.log_dev_event('checkpoint_saved', {'path': '/model.pt'})
487
+
488
+ # Access job ID for tracking
489
+ job_id = self.ctx.job_id
490
+
491
+ # Access backend client (if available)
492
+ if self.ctx.client:
493
+ self.ctx.client.upload_file(...)
494
+ ```
495
+
496
+ ---
497
+
498
+ ## PluginEnvironment
499
+
500
+ Load configuration from environment variables or files:
501
+
502
+ ```python
503
+ from synapse_sdk.plugins.context.env import PluginEnvironment
504
+
505
+ # From environment variables with prefix
506
+ env = PluginEnvironment.from_environ(prefix='PLUGIN_')
507
+
508
+ # From TOML file
509
+ env = PluginEnvironment.from_file('config.toml')
510
+
511
+ # Type-safe getters
512
+ api_key = env.get_str('API_KEY')
513
+ batch_size = env.get_int('BATCH_SIZE', default=32)
514
+ learning_rate = env.get_float('LEARNING_RATE', default=0.001)
515
+ debug = env.get_bool('DEBUG', default=False)
516
+ tags = env.get_list('TAGS', default=[])
517
+
518
+ # Merge multiple environments
519
+ merged = env.merge(another_env)
520
+ ```
521
+
522
+ ---
523
+
524
+ ## Next Steps
525
+
526
+ - **[ACTION_DEV_GUIDE.md](ACTION_DEV_GUIDE.md)**: Complete action development guide
527
+ - **[ARCHITECTURE.md](ARCHITECTURE.md)**: Deep dive into system architecture
528
+ - **[STEP.md](STEP.md)**: Step implementations guide
529
+ - **[LOGGING_SYSTEM.md](LOGGING_SYSTEM.md)**: Logging and progress tracking
530
+ - **[README.md](README.md)**: Quick reference and extension guide
531
+ - **[PIPELINE_GUIDE.md](PIPELINE_GUIDE.md)**: Multi-action pipelines
@@ -0,0 +1,145 @@
1
+ # Remote Pipeline Execution
2
+
3
+ Multi-action pipeline execution on Ray clusters with progress tracking and checkpointing.
4
+
5
+ ## Architecture
6
+
7
+ ```mermaid
8
+ flowchart LR
9
+ subgraph Local["SDK (local)"]
10
+ pipeline["ActionPipeline<br/>.submit()<br/>.wait()"]
11
+ executor["RayPipelineExecutor<br/>- get_progress()<br/>- get_result()"]
12
+ end
13
+
14
+ subgraph Ray["Ray Cluster"]
15
+ actor["PipelineActor<br/>- run_pipeline<br/>- checkpoints"]
16
+ end
17
+
18
+ subgraph Backend["Backend Service"]
19
+ devapi["Backend Service<br/>/api/v1/runs/<br/>/api/v1/progress/"]
20
+ end
21
+
22
+ pipeline -->|"submit()"| actor
23
+ executor -->|"poll"| devapi
24
+ actor -->|"report"| devapi
25
+ devapi <-->|"HTTP"| executor
26
+
27
+ style Local fill:#e1f5fe
28
+ style Ray fill:#f3e5f5
29
+ style Backend fill:#fff3e0
30
+ ```
31
+
32
+ **Key Design Decision:** Ray Workflows is deprecated. We use a single persistent Ray actor + custom orchestration via a backend service.
33
+
34
+ ## Quick Start
35
+
36
+ ```python
37
+ from synapse_sdk.plugins.pipelines import ActionPipeline
38
+ from synapse_sdk.plugins.executors.ray import RayPipelineExecutor
39
+
40
+ pipeline = ActionPipeline([DownloadAction, ConvertAction, TrainAction])
41
+
42
+ executor = RayPipelineExecutor(
43
+ ray_address='auto',
44
+ working_dir='/path/to/plugin',
45
+ pipeline_service_url='http://localhost:8100',
46
+ )
47
+
48
+ # Remote execution
49
+ run_id = pipeline.submit({'dataset_id': 123}, executor)
50
+ progress = executor.get_progress(run_id)
51
+ result = pipeline.wait(run_id, executor)
52
+
53
+ # Stream progress with Rich display (sync)
54
+ from synapse_sdk.plugins.pipelines import display_progress
55
+ final = display_progress(executor.stream_progress(run_id))
56
+
57
+ # Stream progress with Rich display (async)
58
+ from synapse_sdk.plugins.pipelines import display_progress_async
59
+ final = await display_progress_async(executor.stream_progress_async(run_id))
60
+
61
+ # Resume from a failed run
62
+ new_run_id = pipeline.submit({'dataset_id': 123}, executor, resume_from=run_id)
63
+
64
+ # Local execution (unchanged)
65
+ result = pipeline.execute(params, ctx)
66
+ ```
67
+
68
+ ## File Structure
69
+
70
+ ```
71
+ synapse_sdk/
72
+ ├── plugins/pipelines/
73
+ │ ├── action_pipeline.py # ActionPipeline with submit()/wait()
74
+ │ ├── context.py # PipelineContext (shared working dir)
75
+ │ ├── display.py # Rich console progress display
76
+ │ └── models.py # PipelineProgress, ActionProgress, RunStatus
77
+ ├── clients/pipeline/
78
+ │ └── client.py # PipelineServiceClient (backend client, SSE streaming)
79
+ └── plugins/executors/ray/
80
+ └── pipeline.py # RayPipelineExecutor, _PipelineExecutorActor
81
+ ```
82
+
83
+ ## API Reference
84
+
85
+ ### SDK Classes
86
+
87
+ | Class/Function | Location | Purpose |
88
+ |----------------|----------|---------|
89
+ | `ActionPipeline` | `plugins/pipelines/action_pipeline.py` | Chain actions, local or remote |
90
+ | `RayPipelineExecutor` | `plugins/executors/ray/pipeline.py` | Submit to Ray, track progress |
91
+ | `PipelineServiceClient` | `clients/pipeline/client.py` | Communicate with backend service |
92
+ | `PipelineContext` | `plugins/pipelines/context.py` | Shared working directory |
93
+ | `PipelineProgress` | `plugins/pipelines/models.py` | Progress state model |
94
+ | `display_progress()` | `plugins/pipelines/display.py` | Rich console progress (sync) |
95
+ | `display_progress_async()` | `plugins/pipelines/display.py` | Rich console progress (async) |
96
+ | `stream_progress()` | `RayPipelineExecutor` method | SSE progress generator (sync) |
97
+ | `stream_progress_async()` | `RayPipelineExecutor` method | SSE progress generator (async) |
98
+
99
+ ## Design Decisions
100
+
101
+ | Decision | Choice | Rationale |
102
+ |----------|--------|-----------|
103
+ | Orchestration | Custom (not Ray Workflows) | Ray Workflows deprecated |
104
+ | Execution | Single persistent Ray actor | Shared filesystem, simpler state |
105
+ | Working dir | `/tmp/synapse_pipelines/{id}` | Ephemeral, auto-cleanup on reboot |
106
+ | Progress store | External backend service | Decoupled from Ray, queryable |
107
+ | Checkpointing | Yes | Enable resume on failure |
108
+
109
+ ## Remaining Work
110
+
111
+ ### Phase 2: Progress Streaming (Complete)
112
+ - [x] SSE endpoint: `GET /runs/{id}/progress/stream`
113
+ - [x] `executor.stream_progress()` generator
114
+ - [x] Rich console progress display (`display_progress()`)
115
+
116
+ ### Phase 3: Checkpointing & Resume (Complete)
117
+ - [x] `submit(resume_from=run_id)` - Resume from latest checkpoint of a previous run
118
+ - [x] Skip completed actions on resume (marks them as SKIPPED)
119
+ - [x] Restore accumulated params from checkpoint's `params_snapshot`
120
+
121
+ ### Phase 4: DAG Pipelines (Future)
122
+ - [ ] Parallel action branches
123
+ - [ ] Per-action resource requirements
124
+ - [ ] Dependency graph execution
125
+
126
+ ## Troubleshooting
127
+
128
+ **Ray actor fails to import actions:**
129
+ - Ensure `working_dir` contains the plugin code
130
+ - Check `include_sdk=True` if using local SDK changes
131
+ - Actions must be in a proper module (not `__main__`), importable on the remote worker
132
+
133
+ **Remote cluster connectivity:**
134
+ - Use `actor_pipeline_service_url` parameter for the URL the actor should use
135
+ - The local SDK uses `pipeline_service_url` (e.g., `localhost:8100`)
136
+ - The remote actor uses `actor_pipeline_service_url` (e.g., internal network address)
137
+
138
+ ```python
139
+ executor = RayPipelineExecutor(
140
+ ray_address="ray://remote-cluster:10001",
141
+ pipeline_service_url="http://localhost:8100", # Local SDK access
142
+ actor_pipeline_service_url="http://internal-service:8100", # Actor access
143
+ include_sdk=True,
144
+ )
145
+ ```