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
@@ -1,235 +0,0 @@
1
- import inspect
2
- import json
3
- import os
4
- from functools import cached_property
5
- from pprint import pprint
6
-
7
- import ray
8
- import requests
9
- from pydantic import ValidationError
10
- from ray.dashboard.modules.job.sdk import JobSubmissionClient
11
- from ray.exceptions import RayTaskError
12
-
13
- from synapse_sdk.clients.ray import RayClient
14
- from synapse_sdk.plugins.enums import RunMethod
15
- from synapse_sdk.plugins.exceptions import ActionError
16
- from synapse_sdk.plugins.models import PluginRelease, Run
17
- from synapse_sdk.plugins.upload import archive_and_upload, build_and_upload, download_and_upload
18
- from synapse_sdk.utils.module_loading import import_string
19
- from synapse_sdk.utils.pydantic.errors import pydantic_to_drf_error
20
-
21
-
22
- class Action:
23
- # class 변수
24
- name = None
25
- category = None
26
- method = None
27
- run_class = Run
28
- params_model = None
29
- progress_categories = None
30
-
31
- # init 변수
32
- params = None
33
- plugin_config = None
34
- plugin_release = None
35
- config = None
36
- job_id = None
37
- direct = None
38
- debug = None
39
- envs = None
40
- run = None
41
-
42
- default_envs = [
43
- 'RAY_ADDRESS',
44
- 'RAY_DASHBOARD_URL',
45
- 'RAY_SERVE_ADDRESS',
46
- 'SYNAPSE_PLUGIN_STORAGE',
47
- 'SYNAPSE_DEBUG_PLUGIN_PATH',
48
- 'SYNAPSE_DEBUG_MODULES',
49
- 'SYNAPSE_PLUGIN_RUN_HOST',
50
- 'SYNAPSE_PLUGIN_RUN_USER_TOKEN',
51
- 'SYNAPSE_PLUGIN_RUN_TENANT',
52
- ]
53
-
54
- def __init__(self, params, plugin_config, envs=None, job_id=None, direct=False, debug=False):
55
- self.params = params
56
- self.plugin_config = plugin_config
57
- self.plugin_release = PluginRelease(config=plugin_config)
58
- self.config = self.plugin_release.get_action_config(self.name)
59
- self.job_id = job_id
60
- self.direct = direct
61
- self.debug = debug
62
- self.envs = {**self.get_default_envs(), **envs} if envs else self.get_default_envs()
63
- self.run = self.get_run()
64
-
65
- @cached_property
66
- def entrypoint(self):
67
- return import_string(self.config['entrypoint'])
68
-
69
- @property
70
- def plugin_storage_url(self):
71
- return self.envs['SYNAPSE_PLUGIN_STORAGE']
72
-
73
- @property
74
- def client(self):
75
- return self.run.client
76
-
77
- @property
78
- def ray_client(self):
79
- return RayClient(self.envs['RAY_DASHBOARD_URL'])
80
-
81
- @property
82
- def plugin_url(self):
83
- if self.debug:
84
- plugin_path = self.envs.get('SYNAPSE_DEBUG_PLUGIN_PATH') or '.'
85
- if plugin_path.startswith('https://'): # TODO ray에서 지원하는 remote uri 형식 (https, s3, gs) 모두 지원
86
- plugin_url = plugin_path
87
- elif plugin_path.startswith('http://'):
88
- plugin_url = download_and_upload(plugin_path, self.plugin_storage_url)
89
- else:
90
- plugin_url = archive_and_upload(plugin_path, self.plugin_storage_url)
91
- self.envs['SYNAPSE_DEBUG_PLUGIN_PATH'] = plugin_url
92
- return plugin_url
93
- return self.plugin_release.get_url(self.plugin_storage_url)
94
-
95
- @property
96
- def debug_modules(self):
97
- debug_modules = []
98
- for module_path in self.envs.get('SYNAPSE_DEBUG_MODULES', '').split(','):
99
- if module_path.startswith('https://'): # TODO ray에서 지원하는 remote uri 형식 (https, s3, gs) 모두 지원
100
- module_url = module_path
101
- else:
102
- module_url = build_and_upload(module_path, self.plugin_storage_url)
103
- debug_modules.append(module_url)
104
- self.envs['SYNAPSE_DEBUG_MODULES'] = ','.join(debug_modules)
105
- return debug_modules
106
-
107
- def get_run(self):
108
- context = {
109
- 'plugin_release': self.plugin_release,
110
- 'progress_categories': self.progress_categories,
111
- 'params': self.params,
112
- 'envs': self.envs,
113
- 'debug': self.debug,
114
- }
115
- return self.run_class(self.job_id, context)
116
-
117
- def get_default_envs(self):
118
- return {env: os.environ[env] for env in self.default_envs if env in os.environ}
119
-
120
- def get_runtime_env(self):
121
- runtime_env = {
122
- 'pip': ['-r ${RAY_RUNTIME_ENV_CREATE_WORKING_DIR}/requirements.txt'],
123
- 'working_dir': self.plugin_url,
124
- }
125
-
126
- if self.debug:
127
- runtime_env['pip'] += self.debug_modules
128
-
129
- # 맨 마지막에 진행되어야 함
130
- runtime_env['env_vars'] = self.envs
131
-
132
- if self.debug:
133
- pprint(runtime_env)
134
- return runtime_env
135
-
136
- def validate_params(self):
137
- if self.params_model:
138
- try:
139
- self.params_model.model_validate(self.params, context={'action': self})
140
- except ValidationError as e:
141
- raise ActionError({'params': pydantic_to_drf_error(e)})
142
-
143
- def run_action(self):
144
- self.validate_params()
145
-
146
- if not ray.is_initialized():
147
- ray.init(address=self.envs['RAY_ADDRESS'], ignore_reinit_error=True)
148
-
149
- if self.direct:
150
- if self.method == RunMethod.RESTAPI:
151
- return self.start_by_restapi()
152
- else:
153
- result = self.start()
154
- self.post_action_by_job(result)
155
- return result
156
- return getattr(self, f'start_by_{self.method.value}')()
157
-
158
- def start(self):
159
- if self.method == RunMethod.JOB:
160
- return self.entrypoint(self.run, **self.params)
161
- return self.entrypoint(**self.params)
162
-
163
- def start_by_task(self):
164
- @ray.remote(runtime_env=self.get_runtime_env())
165
- def run_task(category, action, *args, **kwargs):
166
- from synapse_sdk.plugins.utils import get_action_class
167
-
168
- action = get_action_class(category, action)(*args, **kwargs)
169
- return action.run_action()
170
-
171
- init_signature = inspect.signature(self.__class__.__init__)
172
-
173
- args = []
174
- kwargs = {}
175
-
176
- for param in init_signature.parameters.values():
177
- if param.name == 'self':
178
- continue
179
- if param.default == param.empty:
180
- args.append(getattr(self, param.name))
181
- else:
182
- kwargs[param.name] = getattr(self, param.name)
183
-
184
- kwargs['direct'] = True
185
- try:
186
- return ray.get(run_task.remote(self.category.value, self.name, *args, **kwargs))
187
- except RayTaskError as e:
188
- raise ActionError(e.cause)
189
-
190
- def start_by_job(self):
191
- main_options = []
192
- options = ['run', '--direct']
193
- arguments = [self.name, f'{json.dumps(json.dumps(self.params))}']
194
-
195
- if self.debug:
196
- main_options.append('--debug')
197
-
198
- if self.job_id:
199
- options.append(f'--job-id={self.job_id}')
200
-
201
- cmd = ' '.join(main_options + options + arguments)
202
-
203
- client = self.get_job_client()
204
- return client.submit_job(
205
- submission_id=self.job_id,
206
- entrypoint=f'python main.py {cmd}',
207
- runtime_env=self.get_runtime_env(),
208
- )
209
-
210
- def start_by_restapi(self):
211
- path = self.params.pop('path', '')
212
- method = self.params.pop('method')
213
-
214
- url = self.plugin_release.get_serve_url(self.envs['RAY_SERVE_ADDRESS'], path)
215
- try:
216
- response = getattr(requests, method)(url, **self.params)
217
- try:
218
- response_body = response.json()
219
- except ValueError:
220
- response_body = response.text
221
- if response.ok:
222
- return response_body
223
- else:
224
- raise ActionError({'status': response.status_code, 'reason': response.reason, 'message': response_body})
225
- except requests.ConnectionError:
226
- raise ActionError('Unable to connect to serve application')
227
-
228
- def post_action_by_job(self, result):
229
- if self.client:
230
- job_client = self.get_job_client()
231
- logs = job_client.get_job_logs(self.job_id).split('\n')
232
- self.client.update_job(self.job_id, data={'result': result or {}, 'console_logs': logs})
233
-
234
- def get_job_client(self):
235
- return JobSubmissionClient(address=self.envs.get('RAY_DASHBOARD_URL'))
@@ -1,10 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.decorators import register_action
3
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
4
-
5
-
6
- @register_action
7
- class ValidationAction(Action):
8
- name = 'validation'
9
- category = PluginCategory.DATA_VALIDATION
10
- method = RunMethod.TASK
@@ -1,3 +0,0 @@
1
- actions:
2
- validation:
3
- entrypoint: plugin.validation.validate
@@ -1,5 +0,0 @@
1
- def validate(data, assignment_id, **kwargs):
2
- errors = []
3
- if data.get('errors'):
4
- errors += data['errors']
5
- return errors
@@ -1,13 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.registry import _REGISTERED_ACTIONS
3
-
4
-
5
- def register_action(action_class):
6
- if not issubclass(action_class, Action):
7
- raise ValueError('Wrapped class must subclass Action class.')
8
-
9
- try:
10
- _REGISTERED_ACTIONS[action_class.category.value][action_class.name] = action_class
11
- except KeyError:
12
- _REGISTERED_ACTIONS[action_class.category.value] = {action_class.name: action_class}
13
- return action_class
File without changes
File without changes
@@ -1,10 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.decorators import register_action
3
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
4
-
5
-
6
- @register_action
7
- class ExportAction(Action):
8
- name = 'export'
9
- category = PluginCategory.EXPORT
10
- method = RunMethod.JOB
File without changes
File without changes
@@ -1,10 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.decorators import register_action
3
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
4
-
5
-
6
- @register_action
7
- class ImportAction(Action):
8
- name = 'import'
9
- category = PluginCategory.IMPORT
10
- method = RunMethod.JOB
File without changes
@@ -1,45 +0,0 @@
1
- from ray import serve
2
-
3
- from synapse_sdk.clients.exceptions import ClientError
4
- from synapse_sdk.plugins.categories.base import Action
5
- from synapse_sdk.plugins.categories.decorators import register_action
6
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
7
-
8
-
9
- @register_action
10
- class DeploymentAction(Action):
11
- name = 'deployment'
12
- category = PluginCategory.NEURAL_NET
13
- method = RunMethod.JOB
14
-
15
- def get_deployment(self):
16
- return serve.deployment(ray_actor_options=self.get_actor_options())(self.entrypoint)
17
-
18
- def get_actor_options(self):
19
- return {'runtime_env': self.get_runtime_env()}
20
-
21
- def start(self):
22
- deployment = self.get_deployment()
23
- serve.delete(self.plugin_release.code)
24
- # TODO add run object
25
- serve.run(deployment.bind(), name=self.plugin_release.code, route_prefix=f'/{self.plugin_release.checksum}')
26
-
27
- # 백엔드에 ServeApplication 추가
28
- serve_application = self.create_serve_application()
29
- return {'serve_application': serve_application['id'] if serve_application else None}
30
-
31
- def create_serve_application(self):
32
- if self.client:
33
- try:
34
- job = self.client.get_job(self.job_id)
35
- serve_application = self.ray_client.get_serve_application(self.plugin_release.code)
36
- return self.client.create_serve_application({
37
- 'plugin': self.plugin_release.plugin,
38
- 'version': self.plugin_release.version,
39
- 'agent': job['agent'],
40
- 'status': serve_application['status'],
41
- 'data': serve_application,
42
- })
43
- except ClientError:
44
- pass
45
- return None
@@ -1,18 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.decorators import register_action
3
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
4
-
5
-
6
- @register_action
7
- class InferenceAction(Action):
8
- name = 'inference'
9
- category = PluginCategory.NEURAL_NET
10
- method = RunMethod.RESTAPI
11
-
12
- def __init__(self, *args, **kwargs):
13
- super().__init__(*args, **kwargs)
14
- headers = {'serve_multiplexed_model_id': str(self.params.pop('model'))}
15
- if 'headers' in self.params:
16
- self.params['headers'].update(headers)
17
- else:
18
- self.params['headers'] = headers
@@ -1,10 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.decorators import register_action
3
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
4
-
5
-
6
- @register_action
7
- class TestAction(Action):
8
- name = 'test'
9
- category = PluginCategory.NEURAL_NET
10
- method = RunMethod.JOB
@@ -1,143 +0,0 @@
1
- import copy
2
- import tempfile
3
- from decimal import Decimal
4
- from pathlib import Path
5
- from typing import Annotated
6
-
7
- from pydantic import AfterValidator, BaseModel, field_validator
8
- from pydantic_core import PydanticCustomError
9
-
10
- from synapse_sdk.clients.exceptions import ClientError
11
- from synapse_sdk.plugins.categories.base import Action
12
- from synapse_sdk.plugins.categories.decorators import register_action
13
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
14
- from synapse_sdk.plugins.models import Run
15
- from synapse_sdk.utils.file import archive
16
- from synapse_sdk.utils.pydantic.validators import non_blank
17
-
18
-
19
- class TrainRun(Run):
20
- def log_metric(self, key, value, **metrics):
21
- self.log('metric', {'key': key, 'value': value, 'metrics': metrics})
22
-
23
-
24
- class Hyperparameter(BaseModel):
25
- batch_size: int
26
- iterations: int
27
- learning_rate: Decimal
28
-
29
-
30
- class TrainParams(BaseModel):
31
- name: Annotated[str, AfterValidator(non_blank)]
32
- description: str
33
- checkpoint: int | None
34
- dataset: int
35
- hyperparameter: Hyperparameter
36
-
37
- @field_validator('name')
38
- @staticmethod
39
- def unique_name(value, info):
40
- action = info.context['action']
41
- client = action.client
42
- try:
43
- model_exists = client.exists('list_models', params={'name': value})
44
- job_exists = client.exists(
45
- 'list_jobs',
46
- params={
47
- 'ids_ex': action.job_id,
48
- 'category': 'neural_net',
49
- 'action': 'train',
50
- 'is_active': True,
51
- 'params': f'name:{value}',
52
- },
53
- )
54
- assert not model_exists and not job_exists, '존재하는 학습 이름입니다.'
55
- except ClientError:
56
- raise PydanticCustomError('client_error', '')
57
- return value
58
-
59
-
60
- @register_action
61
- class TrainAction(Action):
62
- name = 'train'
63
- category = PluginCategory.NEURAL_NET
64
- method = RunMethod.JOB
65
- run_class = TrainRun
66
- params_model = TrainParams
67
- progress_categories = {
68
- 'dataset': {
69
- 'proportion': 20,
70
- },
71
- 'train': {
72
- 'proportion': 75,
73
- },
74
- 'model_upload': {
75
- 'proportion': 5,
76
- },
77
- }
78
-
79
- def start(self):
80
- hyperparameter = self.params['hyperparameter']
81
-
82
- # download dataset
83
- self.run.log_message('Preparing dataset for training.')
84
- input_dataset = self.get_dataset()
85
-
86
- # train dataset
87
- self.run.log_message('Starting model training.')
88
-
89
- result = self.entrypoint(self.run, input_dataset, hyperparameter)
90
-
91
- # upload model_data
92
- self.run.log_message('Registering model data.')
93
- self.run.set_progress(0, 1, category='model_upload')
94
- model = self.create_model(result)
95
- self.run.set_progress(1, 1, category='model_upload')
96
-
97
- self.run.end_log()
98
- return {'model_id': model['id'] if model else None}
99
-
100
- def get_dataset(self):
101
- client = self.run.client
102
- assert bool(client)
103
-
104
- input_dataset = {}
105
-
106
- ground_truths, count_dataset = client.list_ground_truth_events(
107
- params={
108
- 'fields': ['category', 'files', 'data'],
109
- 'ground_truth_dataset_versions': self.params['dataset'],
110
- },
111
- list_all=True,
112
- )
113
- self.run.set_progress(0, count_dataset, category='dataset')
114
- for i, ground_truth in enumerate(ground_truths, start=1):
115
- self.run.set_progress(i, count_dataset, category='dataset')
116
- try:
117
- input_dataset[ground_truth['category']].append(ground_truth)
118
- except KeyError:
119
- input_dataset[ground_truth['category']] = [ground_truth]
120
-
121
- return input_dataset
122
-
123
- def create_model(self, path):
124
- if not self.client:
125
- print(path)
126
- return None
127
-
128
- params = copy.deepcopy(self.params)
129
- configuration_fields = ['hyperparameter']
130
- configuration = {field: params.pop(field) for field in configuration_fields}
131
-
132
- with tempfile.TemporaryDirectory() as temp_path:
133
- input_path = Path(path)
134
- archive_path = Path(temp_path, 'archive.zip')
135
- archive(input_path, archive_path)
136
-
137
- return self.client.create_model({
138
- 'plugin': self.plugin_release.plugin,
139
- 'version': self.plugin_release.version,
140
- 'file': str(archive_path),
141
- 'configuration': configuration,
142
- **params,
143
- })
@@ -1,12 +0,0 @@
1
- actions:
2
- train:
3
- dataset: datamaker
4
- entrypoint: plugin.train.train
5
- deployment:
6
- entrypoint: plugin.inference.InferenceDeployment
7
- inference:
8
- method: restapi
9
- endpoints:
10
- - method: get
11
- test:
12
- entrypoint: plugin.test.test
@@ -1,4 +0,0 @@
1
- class InferenceDeployment:
2
- def __call__(self):
3
- message = 'hello datamaker'
4
- return {'message': message}
@@ -1,2 +0,0 @@
1
- def test(run):
2
- return 'this is neural net test!'
@@ -1,14 +0,0 @@
1
- import time
2
-
3
-
4
- def train(run, dataset, hyperparameter, checkpoint=None):
5
- count_iterations = hyperparameter['iterations']
6
-
7
- for i in range(1, count_iterations + 1):
8
- time.sleep(0.5)
9
- loss = float(round((count_iterations - i) / count_iterations, 2))
10
- miou = 1 - loss
11
- run.log_metric('iteration', i, loss=loss, miou=miou)
12
- run.set_progress(i, count_iterations, category='train')
13
-
14
- return {'weight': '/tmp/agent/test/a.txt', 'config': '/tmp/agent/test/b.txt'}
@@ -1,10 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.decorators import register_action
3
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
4
-
5
-
6
- @register_action
7
- class PostAnnotationAction(Action):
8
- name = 'post_annotation'
9
- category = PluginCategory.POST_ANNOTATION
10
- method = RunMethod.TASK
@@ -1,3 +0,0 @@
1
- actions:
2
- post_annotation:
3
- entrypoint: plugin.post_annotation.post_annotate
@@ -1,3 +0,0 @@
1
- def post_annotate(data, assignment_id, **kwargs):
2
- data['post_annotate'] = 'hello world'
3
- return data
File without changes
@@ -1,10 +0,0 @@
1
- from synapse_sdk.plugins.categories.base import Action
2
- from synapse_sdk.plugins.categories.decorators import register_action
3
- from synapse_sdk.plugins.enums import PluginCategory, RunMethod
4
-
5
-
6
- @register_action
7
- class PreAnnotationAction(Action):
8
- name = 'pre_annotation'
9
- category = PluginCategory.PRE_ANNOTATION
10
- method = RunMethod.TASK
@@ -1,3 +0,0 @@
1
- actions:
2
- pre_annotation:
3
- entrypoint: plugin.pre_annotation.pre_annotate
@@ -1,3 +0,0 @@
1
- def pre_annotate(data, assignment_id, **kwargs):
2
- data['pre_annotate'] = 'hello world'
3
- return data
@@ -1,16 +0,0 @@
1
- import pkgutil
2
- from importlib import import_module
3
-
4
- from synapse_sdk.plugins.enums import PluginCategory
5
-
6
- _REGISTERED_ACTIONS = {}
7
-
8
-
9
- def register_actions():
10
- if not _REGISTERED_ACTIONS:
11
- for category in PluginCategory:
12
- plugin_category_module_name = f'synapse_sdk.plugins.categories.{category.value}.actions'
13
- plugin_category_module = import_module(plugin_category_module_name)
14
- for _, action_name, _ in pkgutil.iter_modules(plugin_category_module.__path__):
15
- action_module_name = f'{plugin_category_module_name}.{action_name}'
16
- import_module(action_module_name)
File without changes