synapse-sdk 0.1.2a0__py3-none-any.whl → 1.0.0a1__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.
- {synapse → synapse_sdk}/client/__init__.py +6 -6
- synapse_sdk/client/mixins/integration.py +29 -0
- {synapse → synapse_sdk}/loggers.py +1 -1
- synapse_sdk/plugins/__init__.py +13 -0
- synapse_sdk/plugins/categories/base.py +178 -0
- synapse_sdk/plugins/categories/data_validation/actions/validation.py +10 -0
- synapse_sdk/plugins/categories/decorators.py +13 -0
- synapse_sdk/plugins/categories/export/actions/export.py +10 -0
- synapse_sdk/plugins/categories/import/actions/import.py +10 -0
- synapse_sdk/plugins/categories/neural_net/actions/deployment.py +23 -0
- synapse_sdk/plugins/categories/neural_net/actions/inference.py +10 -0
- synapse_sdk/plugins/categories/neural_net/actions/test.py +10 -0
- {synapse → synapse_sdk}/plugins/categories/neural_net/actions/train.py +9 -4
- synapse_sdk/plugins/categories/post_annotation/__init__.py +0 -0
- synapse_sdk/plugins/categories/post_annotation/actions/__init__.py +0 -0
- synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py +10 -0
- synapse_sdk/plugins/categories/pre_annotation/__init__.py +0 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py +0 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py +10 -0
- synapse_sdk/plugins/categories/registry.py +16 -0
- synapse_sdk/plugins/cli/__init__.py +19 -0
- synapse_sdk/plugins/cli/publish.py +24 -0
- synapse_sdk/plugins/cli/run.py +18 -0
- synapse_sdk/plugins/enums.py +16 -0
- synapse_sdk/plugins/job.py +5 -0
- synapse_sdk/plugins/upload.py +72 -0
- synapse_sdk/plugins/utils.py +44 -0
- synapse_sdk/utils/__init__.py +0 -0
- synapse_sdk/utils/debug.py +2 -0
- {synapse → synapse_sdk}/utils/file.py +13 -1
- synapse_sdk/utils/storage.py +92 -0
- {synapse → synapse_sdk}/utils/string.py +4 -0
- {synapse_sdk-0.1.2a0.dist-info → synapse_sdk-1.0.0a1.dist-info}/METADATA +4 -1
- synapse_sdk-1.0.0a1.dist-info/RECORD +55 -0
- {synapse_sdk-0.1.2a0.dist-info → synapse_sdk-1.0.0a1.dist-info}/WHEEL +1 -1
- synapse_sdk-1.0.0a1.dist-info/top_level.txt +1 -0
- synapse/client/mixins/integration.py +0 -12
- synapse/plugins/__init__.py +0 -32
- synapse/plugins/categories/__init__.py +0 -11
- synapse/plugins/categories/base.py +0 -51
- synapse/plugins/categories/neural_net/actions/deployment.py +0 -24
- synapse/plugins/categories/neural_net/actions/test.py +0 -6
- synapse/plugins/utils.py +0 -26
- synapse_sdk-0.1.2a0.dist-info/RECORD +0 -35
- synapse_sdk-0.1.2a0.dist-info/top_level.txt +0 -1
- {synapse → synapse_sdk}/__init__.py +0 -0
- {synapse → synapse_sdk}/client/exceptions.py +0 -0
- {synapse → synapse_sdk}/client/mixins/__init__.py +0 -0
- {synapse → synapse_sdk}/client/mixins/annotation.py +0 -0
- {synapse → synapse_sdk}/client/mixins/dataset.py +0 -0
- {synapse → synapse_sdk}/client/mixins/ml.py +0 -0
- {synapse → synapse_sdk}/client/utils.py +0 -0
- {synapse → synapse_sdk}/config.py +0 -0
- {synapse/plugins/categories/custom_script → synapse_sdk/plugins/categories}/__init__.py +0 -0
- {synapse/plugins/categories/custom_script/actions → synapse_sdk/plugins/categories/data_validation}/__init__.py +0 -0
- {synapse/plugins/categories/export → synapse_sdk/plugins/categories/data_validation/actions}/__init__.py +0 -0
- {synapse/plugins/categories/export/actions → synapse_sdk/plugins/categories/export}/__init__.py +0 -0
- {synapse/plugins/categories/import → synapse_sdk/plugins/categories/export/actions}/__init__.py +0 -0
- {synapse/plugins/categories/import/actions → synapse_sdk/plugins/categories/import}/__init__.py +0 -0
- {synapse/plugins/categories/neural_net → synapse_sdk/plugins/categories/import/actions}/__init__.py +0 -0
- {synapse/plugins/categories/neural_net/actions → synapse_sdk/plugins/categories/neural_net}/__init__.py +0 -0
- {synapse/utils → synapse_sdk/plugins/categories/neural_net/actions}/__init__.py +0 -0
- {synapse → synapse_sdk}/utils/module_loading.py +0 -0
- {synapse_sdk-0.1.2a0.dist-info → synapse_sdk-1.0.0a1.dist-info}/LICENSE +0 -0
|
@@ -15,13 +15,13 @@ from ..utils.file import files_url_to_path_from_objs
|
|
|
15
15
|
class Client(AnnotationClientMixin, DatasetClientMixin, IntegrationClientMixin, MLClientMixin):
|
|
16
16
|
base_url = None
|
|
17
17
|
token = None
|
|
18
|
-
|
|
18
|
+
tenant = None
|
|
19
19
|
|
|
20
|
-
def __init__(self, base_url, token,
|
|
20
|
+
def __init__(self, base_url, token, tenant=None):
|
|
21
21
|
self.base_url = base_url
|
|
22
22
|
self.token = token
|
|
23
|
-
if
|
|
24
|
-
self.
|
|
23
|
+
if tenant:
|
|
24
|
+
self.tenant = tenant
|
|
25
25
|
requests_session = requests.Session()
|
|
26
26
|
self.requests_session = requests_session
|
|
27
27
|
|
|
@@ -32,8 +32,8 @@ class Client(AnnotationClientMixin, DatasetClientMixin, IntegrationClientMixin,
|
|
|
32
32
|
|
|
33
33
|
def _get_headers(self):
|
|
34
34
|
headers = {'Authorization': f'Token {self.token}'}
|
|
35
|
-
if self.
|
|
36
|
-
headers['
|
|
35
|
+
if self.tenant:
|
|
36
|
+
headers['SYNAPSE-Tenant'] = f'Token {self.tenant}'
|
|
37
37
|
return headers
|
|
38
38
|
|
|
39
39
|
def _request(self, method, path, **kwargs):
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
class IntegrationClientMixin:
|
|
2
|
+
def get_plugin(self, pk):
|
|
3
|
+
path = f'plugins/{pk}/'
|
|
4
|
+
return self._get(path)
|
|
5
|
+
|
|
6
|
+
def create_plugin(self, data):
|
|
7
|
+
path = 'plugins/'
|
|
8
|
+
return self._post(path, payload=data)
|
|
9
|
+
|
|
10
|
+
def update_plugin(self, pk, data):
|
|
11
|
+
path = f'plugins/{pk}/'
|
|
12
|
+
return self._put(path, payload=data)
|
|
13
|
+
|
|
14
|
+
def get_plugin_release(self, pk, params=None):
|
|
15
|
+
path = f'plugin_releases/{pk}/'
|
|
16
|
+
return self._get(path, payload=params)
|
|
17
|
+
|
|
18
|
+
def create_plugin_release(self, data):
|
|
19
|
+
path = 'plugin_releases/'
|
|
20
|
+
files = {'file': data.pop('file')}
|
|
21
|
+
return self._post(path, payload=data, files=files)
|
|
22
|
+
|
|
23
|
+
def create_logs(self, data):
|
|
24
|
+
path = 'logs/'
|
|
25
|
+
return self._post(path, payload=data)
|
|
26
|
+
|
|
27
|
+
def create_task(self, data):
|
|
28
|
+
path = 'agent_tasks/'
|
|
29
|
+
return self._post(path, payload=data)
|
|
@@ -0,0 +1,178 @@
|
|
|
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 ray.dashboard.modules.job.sdk import JobSubmissionClient
|
|
10
|
+
|
|
11
|
+
from synapse_sdk.loggers import ConsoleLogger
|
|
12
|
+
from synapse_sdk.plugins.enums import RunMethod
|
|
13
|
+
from synapse_sdk.plugins.upload import build_and_upload, archive_and_upload
|
|
14
|
+
from synapse_sdk.plugins.utils import get_plugin_checksum
|
|
15
|
+
from synapse_sdk.utils.module_loading import import_string
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Action:
|
|
19
|
+
name = None
|
|
20
|
+
category = None
|
|
21
|
+
method = None
|
|
22
|
+
params = None
|
|
23
|
+
plugin_config = None
|
|
24
|
+
config = None
|
|
25
|
+
client = None
|
|
26
|
+
logger = None
|
|
27
|
+
debug = False
|
|
28
|
+
|
|
29
|
+
default_envs = [
|
|
30
|
+
'RAY_DASHBOARD_URL',
|
|
31
|
+
'RAY_SERVE_ADDRESS',
|
|
32
|
+
'SYNAPSE_PLUGIN_URL',
|
|
33
|
+
'SYNAPSE_PLUGIN_PATH',
|
|
34
|
+
'SYNAPSE_PLUGIN_BASE_URL',
|
|
35
|
+
'SYNAPSE_PLUGIN_STORAGE',
|
|
36
|
+
'SYNAPSE_DEBUG_MODULES',
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
def __init__(self, params, plugin_config, envs=None, job_id=None, direct=False, debug=False):
|
|
40
|
+
self.params = params
|
|
41
|
+
self.plugin_config = plugin_config
|
|
42
|
+
self.config = plugin_config['actions'][self.name]
|
|
43
|
+
self.job_id = job_id
|
|
44
|
+
self.direct = direct
|
|
45
|
+
self.debug = debug
|
|
46
|
+
if envs:
|
|
47
|
+
self.envs = {**envs, **self.get_default_envs()}
|
|
48
|
+
else:
|
|
49
|
+
self.envs = self.get_default_envs()
|
|
50
|
+
|
|
51
|
+
# TODO logger 지정 방식 개선
|
|
52
|
+
self.logger = ConsoleLogger()
|
|
53
|
+
|
|
54
|
+
@cached_property
|
|
55
|
+
def plugin_id(self):
|
|
56
|
+
code = self.plugin_config['code']
|
|
57
|
+
version = self.plugin_config['version']
|
|
58
|
+
return f'{code}@{version}'
|
|
59
|
+
|
|
60
|
+
@cached_property
|
|
61
|
+
def plugin_checksum(self):
|
|
62
|
+
return get_plugin_checksum(self.plugin_id)
|
|
63
|
+
|
|
64
|
+
@cached_property
|
|
65
|
+
def plugin_url(self):
|
|
66
|
+
if self.debug:
|
|
67
|
+
plugin_url = self.envs.get('SYNAPSE_PLUGIN_URL')
|
|
68
|
+
if not plugin_url:
|
|
69
|
+
plugin_url = archive_and_upload(
|
|
70
|
+
self.envs.get('SYNAPSE_PLUGIN_PATH', '.'),
|
|
71
|
+
self.envs['SYNAPSE_PLUGIN_STORAGE'],
|
|
72
|
+
)
|
|
73
|
+
self.envs['SYNAPSE_PLUGIN_URL'] = plugin_url
|
|
74
|
+
return plugin_url
|
|
75
|
+
base_url = self.envs['SYNAPSE_PLUGIN_BASE_URL']
|
|
76
|
+
return str(os.path.join(base_url, f'{self.plugin_checksum}.zip'))
|
|
77
|
+
|
|
78
|
+
@cached_property
|
|
79
|
+
def entrypoint(self):
|
|
80
|
+
return import_string(self.config['entrypoint'])
|
|
81
|
+
|
|
82
|
+
def get_default_envs(self):
|
|
83
|
+
return {env: os.environ[env] for env in self.default_envs if env in os.environ}
|
|
84
|
+
|
|
85
|
+
def get_debug_modules(self):
|
|
86
|
+
debug_modules = []
|
|
87
|
+
for module_path in self.envs.get('SYNAPSE_DEBUG_MODULES', '').split(','):
|
|
88
|
+
if module_path.startswith('http'):
|
|
89
|
+
module_url = module_path
|
|
90
|
+
else:
|
|
91
|
+
module_url = build_and_upload(module_path, self.envs['SYNAPSE_PLUGIN_STORAGE'])
|
|
92
|
+
debug_modules.append(module_url)
|
|
93
|
+
self.envs['SYNAPSE_DEBUG_MODULES'] = ','.join(debug_modules)
|
|
94
|
+
return debug_modules
|
|
95
|
+
|
|
96
|
+
def get_runtime_env(self):
|
|
97
|
+
runtime_env = {
|
|
98
|
+
'pip': ['-r ${RAY_RUNTIME_ENV_CREATE_WORKING_DIR}/requirements.txt'],
|
|
99
|
+
'working_dir': self.plugin_url,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if self.debug:
|
|
103
|
+
runtime_env['pip'] += self.get_debug_modules()
|
|
104
|
+
|
|
105
|
+
# 맨 마지막에 진행되어야 함
|
|
106
|
+
runtime_env['env_vars'] = self.envs
|
|
107
|
+
|
|
108
|
+
if self.debug:
|
|
109
|
+
pprint(runtime_env)
|
|
110
|
+
return runtime_env
|
|
111
|
+
|
|
112
|
+
def run(self):
|
|
113
|
+
return self.entrypoint(self, **self.params)
|
|
114
|
+
|
|
115
|
+
def run_action(self):
|
|
116
|
+
if self.direct:
|
|
117
|
+
if self.method == RunMethod.RESTAPI:
|
|
118
|
+
return self.run_by_restapi()
|
|
119
|
+
else:
|
|
120
|
+
return self.run()
|
|
121
|
+
return getattr(self, f'run_by_{self.method.value}')()
|
|
122
|
+
|
|
123
|
+
def run_by_task(self):
|
|
124
|
+
@ray.remote(runtime_env=self.get_runtime_env())
|
|
125
|
+
def run_task(category, action, *args, **kwargs):
|
|
126
|
+
from synapse_sdk.plugins.utils import get_action_class
|
|
127
|
+
|
|
128
|
+
action = get_action_class(category, action)(*args, **kwargs)
|
|
129
|
+
return action.run_action()
|
|
130
|
+
|
|
131
|
+
init_signature = inspect.signature(self.__class__.__init__)
|
|
132
|
+
|
|
133
|
+
args = []
|
|
134
|
+
kwargs = {}
|
|
135
|
+
|
|
136
|
+
for param in init_signature.parameters.values():
|
|
137
|
+
if param.name == 'self':
|
|
138
|
+
continue
|
|
139
|
+
if param.default == param.empty:
|
|
140
|
+
args.append(getattr(self, param.name))
|
|
141
|
+
else:
|
|
142
|
+
kwargs[param.name] = getattr(self, param.name)
|
|
143
|
+
|
|
144
|
+
kwargs['direct'] = True
|
|
145
|
+
return ray.get(run_task.remote(self.category.value, self.name, *args, **kwargs))
|
|
146
|
+
|
|
147
|
+
def run_by_job(self):
|
|
148
|
+
entrypoint_args = ['run', self.name, f'"{json.dumps(self.params)}"', '--direct']
|
|
149
|
+
if self.debug:
|
|
150
|
+
entrypoint_args.insert(0, '--debug')
|
|
151
|
+
|
|
152
|
+
client = JobSubmissionClient(address=self.envs.get('RAY_DASHBOARD_URL'))
|
|
153
|
+
return client.submit_job(
|
|
154
|
+
submission_id=self.job_id,
|
|
155
|
+
entrypoint=f'python main.py {" ".join(entrypoint_args)}',
|
|
156
|
+
runtime_env=self.get_runtime_env(),
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
def run_by_restapi(self):
|
|
160
|
+
path = self.params.pop('path', '')
|
|
161
|
+
method = self.params.pop('method')
|
|
162
|
+
|
|
163
|
+
url = os.path.join(self.envs['RAY_SERVE_ADDRESS'], self.plugin_checksum, path)
|
|
164
|
+
response = getattr(requests, method)(url, **self.params)
|
|
165
|
+
# TODO ok response가 아닌 경우 대응하기
|
|
166
|
+
return response.json()
|
|
167
|
+
|
|
168
|
+
def set_progress(self, current, total, category=''):
|
|
169
|
+
self.logger.set_progress(current, total, category)
|
|
170
|
+
|
|
171
|
+
def log(self, action, data):
|
|
172
|
+
self.logger.log(action, data)
|
|
173
|
+
|
|
174
|
+
def log_event(self, message):
|
|
175
|
+
self.logger.log('event', {'content': message})
|
|
176
|
+
|
|
177
|
+
def end_log(self):
|
|
178
|
+
self.log_event('Plugin run is complete.')
|
|
@@ -0,0 +1,10 @@
|
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_action
|
|
7
|
+
class ValidationAction(Action):
|
|
8
|
+
name = 'validation'
|
|
9
|
+
category = PluginCategory.DATA_VALIDATION
|
|
10
|
+
method = RunMethod.TASK
|
|
@@ -0,0 +1,13 @@
|
|
|
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
|
|
@@ -0,0 +1,10 @@
|
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_action
|
|
7
|
+
class ExportAction(Action):
|
|
8
|
+
name = 'export'
|
|
9
|
+
category = PluginCategory.EXPORT
|
|
10
|
+
method = RunMethod.JOB
|
|
@@ -0,0 +1,10 @@
|
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_action
|
|
7
|
+
class ImportAction(Action):
|
|
8
|
+
name = 'import'
|
|
9
|
+
category = PluginCategory.IMPORT
|
|
10
|
+
method = RunMethod.JOB
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from ray import serve
|
|
2
|
+
|
|
3
|
+
from synapse_sdk.plugins.categories.base import Action
|
|
4
|
+
from synapse_sdk.plugins.categories.decorators import register_action
|
|
5
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@register_action
|
|
9
|
+
class DeploymentAction(Action):
|
|
10
|
+
name = 'deployment'
|
|
11
|
+
category = PluginCategory.NEURAL_NET
|
|
12
|
+
method = RunMethod.JOB
|
|
13
|
+
|
|
14
|
+
def get_deployment(self):
|
|
15
|
+
return serve.deployment(ray_actor_options=self.get_actor_options())(self.entrypoint)
|
|
16
|
+
|
|
17
|
+
def get_actor_options(self):
|
|
18
|
+
return {'runtime_env': self.get_runtime_env()}
|
|
19
|
+
|
|
20
|
+
def run(self):
|
|
21
|
+
deployment = self.get_deployment()
|
|
22
|
+
serve.delete(self.plugin_id)
|
|
23
|
+
serve.run(deployment.bind(), name=self.plugin_id, route_prefix=f'/{self.plugin_checksum}')
|
|
@@ -0,0 +1,10 @@
|
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_action
|
|
7
|
+
class InferenceAction(Action):
|
|
8
|
+
name = 'inference'
|
|
9
|
+
category = PluginCategory.NEURAL_NET
|
|
10
|
+
method = RunMethod.RESTAPI
|
|
@@ -0,0 +1,10 @@
|
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_action
|
|
7
|
+
class TestAction(Action):
|
|
8
|
+
name = 'test'
|
|
9
|
+
category = PluginCategory.NEURAL_NET
|
|
10
|
+
method = RunMethod.TASK
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
3
|
-
from
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
from synapse_sdk.utils.file import get_dict_from_file, files_url_to_path_from_objs
|
|
5
|
+
from synapse_sdk.utils.module_loading import import_string
|
|
4
6
|
|
|
5
7
|
|
|
8
|
+
@register_action
|
|
6
9
|
class TrainAction(Action):
|
|
7
|
-
|
|
10
|
+
name = 'train'
|
|
11
|
+
category = PluginCategory.NEURAL_NET
|
|
12
|
+
method = RunMethod.JOB
|
|
8
13
|
|
|
9
14
|
def get_input_dataset_for_training(self, model_id=None):
|
|
10
15
|
"""
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_action
|
|
7
|
+
class PostAnnotationAction(Action):
|
|
8
|
+
name = 'post_annotation'
|
|
9
|
+
category = PluginCategory.POST_ANNOTATION
|
|
10
|
+
method = RunMethod.TASK
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
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 RunMethod, PluginCategory
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@register_action
|
|
7
|
+
class PreAnnotationAction(Action):
|
|
8
|
+
name = 'pre_annotation'
|
|
9
|
+
category = PluginCategory.PRE_ANNOTATION
|
|
10
|
+
method = RunMethod.TASK
|
|
@@ -0,0 +1,16 @@
|
|
|
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)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from .publish import publish
|
|
4
|
+
from .run import run
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@click.group()
|
|
8
|
+
@click.option('--debug/--no-debug', default=False)
|
|
9
|
+
@click.pass_context
|
|
10
|
+
def cli(ctx, debug):
|
|
11
|
+
ctx.ensure_object(dict)
|
|
12
|
+
ctx.obj['DEBUG'] = debug
|
|
13
|
+
|
|
14
|
+
if debug:
|
|
15
|
+
click.echo('Debug mode is "on"')
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
cli.add_command(run)
|
|
19
|
+
cli.add_command(publish)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
|
|
5
|
+
from synapse_sdk.client import Client
|
|
6
|
+
from synapse_sdk.plugins.utils import read_config
|
|
7
|
+
|
|
8
|
+
from ..upload import archive
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.command()
|
|
12
|
+
@click.option('-h', '--host', required=True)
|
|
13
|
+
@click.option('-t', '--token', required=True)
|
|
14
|
+
@click.option('-w', '--workspace', required=True)
|
|
15
|
+
def publish(host, token, workspace):
|
|
16
|
+
client = Client(host, token, tenant=workspace)
|
|
17
|
+
config = read_config()
|
|
18
|
+
|
|
19
|
+
source_path = Path('./')
|
|
20
|
+
archive_path = source_path / 'dist' / 'archive.zip'
|
|
21
|
+
archive(source_path, archive_path)
|
|
22
|
+
|
|
23
|
+
data = {'plugin': config['code'], 'file': str(archive_path)}
|
|
24
|
+
client.create_plugin_release(data)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from synapse_sdk.plugins.utils import get_action
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@click.command()
|
|
7
|
+
@click.argument('action')
|
|
8
|
+
@click.argument('params')
|
|
9
|
+
@click.option('--direct/--no-direct', default=False)
|
|
10
|
+
@click.pass_context
|
|
11
|
+
def run(ctx, action, params, direct):
|
|
12
|
+
debug = ctx.obj['DEBUG']
|
|
13
|
+
|
|
14
|
+
action = get_action(action, params, direct=direct, debug=debug)
|
|
15
|
+
result = action.run_action()
|
|
16
|
+
|
|
17
|
+
if debug:
|
|
18
|
+
click.echo(result)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class RunMethod(Enum):
|
|
5
|
+
JOB = 'job'
|
|
6
|
+
TASK = 'task'
|
|
7
|
+
RESTAPI = 'restapi'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PluginCategory(Enum):
|
|
11
|
+
NEURAL_NET = 'neural_net'
|
|
12
|
+
EXPORT = 'export'
|
|
13
|
+
IMPORT = 'import'
|
|
14
|
+
POST_ANNOTATION = 'post_annotation'
|
|
15
|
+
PRE_ANNOTATION = 'pre_annotation'
|
|
16
|
+
DATA_VALIDATION = 'data_validation'
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import subprocess
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from synapse_sdk.utils.file import calculate_checksum
|
|
6
|
+
from synapse_sdk.utils.storage import get_storage
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def archive(source_path, archive_path):
|
|
10
|
+
archive_path.parent.mkdir(parents=True, exist_ok=True)
|
|
11
|
+
command = f'git ls-files --others --exclude-standard --cached | zip -q --names-stdin {archive_path}'
|
|
12
|
+
subprocess.run(command, cwd=source_path, shell=True, check=True, stdout=subprocess.DEVNULL)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def archive_and_upload(source_path, url):
|
|
16
|
+
storage = get_storage(url)
|
|
17
|
+
dist_path = Path(source_path, 'dist')
|
|
18
|
+
archive_path = dist_path / 'archive.zip'
|
|
19
|
+
|
|
20
|
+
archive(source_path, archive_path)
|
|
21
|
+
checksum = calculate_checksum(archive_path, prefix='dev')
|
|
22
|
+
checksum_archive_path = dist_path / f'{checksum}.zip'
|
|
23
|
+
|
|
24
|
+
if checksum_archive_path.exists():
|
|
25
|
+
# TODO 실제 스토리지 있는지 확인
|
|
26
|
+
return storage.get_url(checksum_archive_path.name)
|
|
27
|
+
|
|
28
|
+
archive_path.rename(checksum_archive_path)
|
|
29
|
+
for file_path in dist_path.glob('*.zip'):
|
|
30
|
+
if file_path.name != checksum_archive_path.name:
|
|
31
|
+
file_path.unlink()
|
|
32
|
+
return storage.upload(str(checksum_archive_path), checksum_archive_path.name)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def build_and_upload(source_path, url, virtualenv_path='.venv'):
|
|
36
|
+
storage = get_storage(url)
|
|
37
|
+
dist_path = Path(source_path, 'dist')
|
|
38
|
+
archive_path = dist_path / 'archive.zip'
|
|
39
|
+
|
|
40
|
+
archive(source_path, archive_path)
|
|
41
|
+
checksum = calculate_checksum(archive_path, prefix='dev')
|
|
42
|
+
checksum_archive_path = dist_path / f'{checksum}.zip'
|
|
43
|
+
|
|
44
|
+
if checksum_archive_path.exists():
|
|
45
|
+
# TODO 실제 스토리지 있는지 확인
|
|
46
|
+
wheel_path = next(dist_path.glob('*.whl'), None)
|
|
47
|
+
return storage.get_url(wheel_path.name)
|
|
48
|
+
|
|
49
|
+
# wheel file 빌드 진행
|
|
50
|
+
for file_path in dist_path.glob('*.whl'):
|
|
51
|
+
file_path.unlink()
|
|
52
|
+
|
|
53
|
+
print(f'Building {Path(source_path).name}...')
|
|
54
|
+
subprocess.run(
|
|
55
|
+
f'{virtualenv_path}/bin/python -m build --wheel',
|
|
56
|
+
cwd=source_path,
|
|
57
|
+
shell=True,
|
|
58
|
+
check=True,
|
|
59
|
+
stdout=subprocess.DEVNULL,
|
|
60
|
+
)
|
|
61
|
+
wheel_path = next(dist_path.glob('*.whl'), None)
|
|
62
|
+
|
|
63
|
+
archive_path.rename(checksum_archive_path)
|
|
64
|
+
for file_path in dist_path.glob('*.zip'):
|
|
65
|
+
if file_path.name != checksum_archive_path.name:
|
|
66
|
+
file_path.unlink()
|
|
67
|
+
return storage.upload(str(wheel_path), wheel_path.name)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def change_whl_version(whl_name, new_version):
|
|
71
|
+
pattern = r'^(?P<distribution>.+?)-(?P<version>[\d\.\w]+(\+[\w\.]+)?)(?P<rest>-.+\.whl)$'
|
|
72
|
+
return re.sub(pattern, rf'\g<distribution>-{new_version}\g<rest>', whl_name)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from synapse_sdk.plugins.categories.registry import _REGISTERED_ACTIONS, register_actions
|
|
4
|
+
from synapse_sdk.utils.file import get_dict_from_file
|
|
5
|
+
from synapse_sdk.utils.string import hash_text
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_action(action, params_data, *args, **kwargs):
|
|
9
|
+
if isinstance(params_data, str):
|
|
10
|
+
try:
|
|
11
|
+
params = json.loads(params_data)
|
|
12
|
+
except json.JSONDecodeError:
|
|
13
|
+
params = get_dict_from_file(params_data)
|
|
14
|
+
else:
|
|
15
|
+
params = params_data
|
|
16
|
+
|
|
17
|
+
config_data = kwargs.pop('config', False)
|
|
18
|
+
if config_data:
|
|
19
|
+
if isinstance(config_data, str):
|
|
20
|
+
config = get_dict_from_file(config_data)
|
|
21
|
+
else:
|
|
22
|
+
config = config_data
|
|
23
|
+
else:
|
|
24
|
+
config = read_config()
|
|
25
|
+
category = config['category']
|
|
26
|
+
return get_action_class(category, action)(params, config, *args, **kwargs)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_action_class(category, action):
|
|
30
|
+
register_actions()
|
|
31
|
+
return _REGISTERED_ACTIONS[category][action]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_available_actions(category):
|
|
35
|
+
register_actions()
|
|
36
|
+
return list(_REGISTERED_ACTIONS[category].keys())
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_plugin_checksum(plugin_id):
|
|
40
|
+
return hash_text(plugin_id)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def read_config():
|
|
44
|
+
return get_dict_from_file('config.yaml')
|
|
File without changes
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import hashlib
|
|
1
2
|
import json
|
|
2
3
|
import operator
|
|
3
4
|
from functools import reduce
|
|
@@ -13,7 +14,7 @@ def download_file(url, path_download, name=None, coerce=None):
|
|
|
13
14
|
else:
|
|
14
15
|
name = Path(url).name
|
|
15
16
|
|
|
16
|
-
path = path_download / name
|
|
17
|
+
path = Path(path_download) / name
|
|
17
18
|
if not path.is_file():
|
|
18
19
|
r = requests.get(url, allow_redirects=True)
|
|
19
20
|
open(str(path), 'wb').write(r.content)
|
|
@@ -56,3 +57,14 @@ def get_dict_from_file(file_path):
|
|
|
56
57
|
return yaml.safe_load(f)
|
|
57
58
|
else:
|
|
58
59
|
return json.load(f)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def calculate_checksum(file_path, prefix=''):
|
|
63
|
+
md5_hash = hashlib.md5()
|
|
64
|
+
with open(file_path, 'rb') as f:
|
|
65
|
+
for byte_block in iter(lambda: f.read(4096), b''):
|
|
66
|
+
md5_hash.update(byte_block)
|
|
67
|
+
checksum = md5_hash.hexdigest()
|
|
68
|
+
if prefix:
|
|
69
|
+
return f'dev-{checksum}'
|
|
70
|
+
return checksum
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from urllib.parse import urlparse, parse_qs
|
|
3
|
+
|
|
4
|
+
import boto3
|
|
5
|
+
from botocore.exceptions import ClientError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseStorage:
|
|
9
|
+
url = None
|
|
10
|
+
options = None
|
|
11
|
+
OPTION_CASTS = {}
|
|
12
|
+
|
|
13
|
+
def __init__(self, url):
|
|
14
|
+
self.url = urlparse(url)
|
|
15
|
+
self.query_params = self.url_querystring_to_dict()
|
|
16
|
+
self.options = self.get_options()
|
|
17
|
+
|
|
18
|
+
def url_querystring_to_dict(self):
|
|
19
|
+
query_string = self.url.query
|
|
20
|
+
|
|
21
|
+
query_dict = parse_qs(query_string)
|
|
22
|
+
|
|
23
|
+
for key, value in query_dict.items():
|
|
24
|
+
if len(value) == 1:
|
|
25
|
+
query_dict[key] = value[0]
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
key: self.OPTION_CASTS[key](value) if key in self.OPTION_CASTS else value
|
|
29
|
+
for key, value in query_dict.items()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
def get_options(self):
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
def upload(self, source, target):
|
|
36
|
+
raise NotImplementedError
|
|
37
|
+
|
|
38
|
+
def exists(self, target):
|
|
39
|
+
raise NotImplementedError
|
|
40
|
+
|
|
41
|
+
def get_url(self, target):
|
|
42
|
+
raise NotImplementedError
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class S3Storage(BaseStorage):
|
|
46
|
+
def __init__(self, url):
|
|
47
|
+
super().__init__(url)
|
|
48
|
+
self.client = boto3.client(
|
|
49
|
+
's3',
|
|
50
|
+
endpoint_url=self.options['endpoint_url'],
|
|
51
|
+
aws_access_key_id=self.options['access_key'],
|
|
52
|
+
aws_secret_access_key=self.options['secret_key'],
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def get_options(self):
|
|
56
|
+
base_url = f'https://{self.url.hostname}'
|
|
57
|
+
local_endpoint = self.query_params.get('local_endpoint')
|
|
58
|
+
endpoint_url = f'http://{local_endpoint}' if local_endpoint else base_url
|
|
59
|
+
return {
|
|
60
|
+
'base_url': base_url,
|
|
61
|
+
'endpoint_url': endpoint_url,
|
|
62
|
+
'bucket_name': self.url.path[1:],
|
|
63
|
+
'access_key': self.url.username,
|
|
64
|
+
'secret_key': self.url.password,
|
|
65
|
+
**self.query_params,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
def upload(self, source, target):
|
|
69
|
+
object_name = os.path.join(self.options['location'], target)
|
|
70
|
+
self.client.upload_file(source, self.options['bucket_name'], object_name)
|
|
71
|
+
return self.get_url(target)
|
|
72
|
+
|
|
73
|
+
def exists(self, target):
|
|
74
|
+
try:
|
|
75
|
+
self.client.head_object(Bucket=self.options['bucket_name'], Key=target)
|
|
76
|
+
return True
|
|
77
|
+
except ClientError:
|
|
78
|
+
return False
|
|
79
|
+
|
|
80
|
+
def get_url(self, target):
|
|
81
|
+
object_name = os.path.join(self.options['location'], target)
|
|
82
|
+
return f'{self.options["base_url"]}/{self.options["bucket_name"]}/{object_name}'
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
STORAGE_STORAGES = {
|
|
86
|
+
's3': S3Storage,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def get_storage(url):
|
|
91
|
+
storage_scheme = urlparse(url).scheme
|
|
92
|
+
return STORAGE_STORAGES[storage_scheme](url)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: synapse-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0a1
|
|
4
4
|
Summary: synapse sdk
|
|
5
5
|
Author-email: datamaker <developer@datamaker.io>
|
|
6
6
|
License: MIT
|
|
@@ -8,8 +8,11 @@ Classifier: Programming Language :: Python :: 3
|
|
|
8
8
|
Requires-Python: >=3.11
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
+
Requires-Dist: boto3
|
|
12
|
+
Requires-Dist: click
|
|
11
13
|
Requires-Dist: requests
|
|
12
14
|
Requires-Dist: tqdm
|
|
15
|
+
Requires-Dist: python-dotenv
|
|
13
16
|
Requires-Dist: pyyaml
|
|
14
17
|
Requires-Dist: pydantic
|
|
15
18
|
Requires-Dist: ray[all]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
synapse_sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
synapse_sdk/config.py,sha256=AHyTHtzkkCZb9DLu1_R99VOwPgWATZj4K7yzHaPijfA,149
|
|
3
|
+
synapse_sdk/loggers.py,sha256=W4KPq-QOK4ECBL0HxxGUGWCNR3FKbHOUMqnVrwz-Ihg,1331
|
|
4
|
+
synapse_sdk/client/__init__.py,sha256=STq4STOQC5hhxKsAxhMYP6q3f4J1yJd1JUlz_db_130,3339
|
|
5
|
+
synapse_sdk/client/exceptions.py,sha256=LzgzPKRPhNUpLh-jBQHKze8c3CQoVA22jSfjUMBZCuU,405
|
|
6
|
+
synapse_sdk/client/utils.py,sha256=8pPJTdzHiRPSbZMoQYHAgR2BAMO6u_R_jMV6a2p34iQ,392
|
|
7
|
+
synapse_sdk/client/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
synapse_sdk/client/mixins/annotation.py,sha256=69xblc0RLokKlpSfIzoJ5dVRvw3VpPIVgbQKV3L5Xx4,905
|
|
9
|
+
synapse_sdk/client/mixins/dataset.py,sha256=KXsen7-vdSzdR09uxD88lT604ItJKuCOSLR3fEU5ud0,1666
|
|
10
|
+
synapse_sdk/client/mixins/integration.py,sha256=iCBjoz7GjzerhxGM0cPunauohs9Vq4_98EtTwxBMdYs,880
|
|
11
|
+
synapse_sdk/client/mixins/ml.py,sha256=xkfO95k6p_nQVyai2zBO-z4b9nh6YIryN4iakDGiPsE,891
|
|
12
|
+
synapse_sdk/plugins/__init__.py,sha256=9vsbYhxah4_ofTaG0x0qLFID_raHNkO57Y8A31Ws-lU,222
|
|
13
|
+
synapse_sdk/plugins/enums.py,sha256=lQZqO2bEeBKdk6q-SMjfOLDlgxv7BuIPk3fXeUFfHRs,327
|
|
14
|
+
synapse_sdk/plugins/job.py,sha256=UzFKA8o_F6RzY_PwyI4dlF3kSfmMG0xEYIyKLfdqSP8,91
|
|
15
|
+
synapse_sdk/plugins/upload.py,sha256=lImaecAz5NG8puT5PwVNkV3kT0d6b7DNBD0jUMaVcBI,2600
|
|
16
|
+
synapse_sdk/plugins/utils.py,sha256=RFxFtmjj-uBK03wUwLhtUecfn_IOKRJupudmsguc2Sc,1212
|
|
17
|
+
synapse_sdk/plugins/categories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
synapse_sdk/plugins/categories/base.py,sha256=4pltsAR7RkCm9vaV-1TkVmJSi9w78KsBlVv9v7fFO6U,5823
|
|
19
|
+
synapse_sdk/plugins/categories/decorators.py,sha256=Gw6T-UHwpCKrSt596X-g2sZbY_Z1zbbogowClj7Pr5Q,518
|
|
20
|
+
synapse_sdk/plugins/categories/registry.py,sha256=KdQR8SUlLT-3kgYzDNWawS1uJnAhrcw2j4zFaTpilRs,636
|
|
21
|
+
synapse_sdk/plugins/categories/data_validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
synapse_sdk/plugins/categories/data_validation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
synapse_sdk/plugins/categories/data_validation/actions/validation.py,sha256=NbEGFytxjakawglZR_Sf9UAjQyuzRxpdwEI1GDbEBW0,338
|
|
24
|
+
synapse_sdk/plugins/categories/export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
synapse_sdk/plugins/categories/export/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
+
synapse_sdk/plugins/categories/export/actions/export.py,sha256=zpvVB0Dac9ytshJrN2ouDpsGHMuJlap-Ymz4qEw_Hzo,320
|
|
27
|
+
synapse_sdk/plugins/categories/import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
synapse_sdk/plugins/categories/import/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
synapse_sdk/plugins/categories/import/actions/import.py,sha256=bkB8x-x7jJfcCnzbz5bOJJy7mPhTKYfIWUdmCoHvpdM,320
|
|
30
|
+
synapse_sdk/plugins/categories/neural_net/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
synapse_sdk/plugins/categories/neural_net/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
synapse_sdk/plugins/categories/neural_net/actions/deployment.py,sha256=afqgD_mzErcWdW3xdbrKIOL13fUPO0biZk8_l4l2j84,767
|
|
33
|
+
synapse_sdk/plugins/categories/neural_net/actions/inference.py,sha256=erM2z7aUTwyzJZqWBlxhTP8dm8cOraI_vUYAqcXkdSY,334
|
|
34
|
+
synapse_sdk/plugins/categories/neural_net/actions/test.py,sha256=dAW1zfodlUhoL-sD17tG-CQT0RBxIcHWJ8f1eeZ00M4,321
|
|
35
|
+
synapse_sdk/plugins/categories/neural_net/actions/train.py,sha256=sg-PDU_RnAtQGCwI6XnfC63lyPE2fRY6qEUv-_VKu8A,3283
|
|
36
|
+
synapse_sdk/plugins/categories/post_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
+
synapse_sdk/plugins/categories/post_annotation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
+
synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py,sha256=1tutwNDHpnrCPHzMTsMEk29WPajnZikjBE83j7Z-Xt0,347
|
|
39
|
+
synapse_sdk/plugins/categories/pre_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
|
+
synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
+
synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py,sha256=YYQt9HsgXlBclE4Sn0c7p1zqCxWHkIHAwyA-tbqrmPQ,344
|
|
42
|
+
synapse_sdk/plugins/cli/__init__.py,sha256=8ogaOhN-RbDNYHqziW8nLsNUxKkZwGkHBdKxTahcm3U,334
|
|
43
|
+
synapse_sdk/plugins/cli/publish.py,sha256=ws4vuXPWiwKq6czIjg__eWE2-vBgquXnsYFdGyI42vs,663
|
|
44
|
+
synapse_sdk/plugins/cli/run.py,sha256=_Lb-Jeh3NHUwui_y34-7lRXp7Ek_rP8BgBM5wqxLdeU,418
|
|
45
|
+
synapse_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
synapse_sdk/utils/debug.py,sha256=46sMFQLg_JSRUCymnT3wgszG1QsgrocRGiBjVX38r50,53
|
|
47
|
+
synapse_sdk/utils/file.py,sha256=Iptk_DCPsmJzqAABCD3vC6z1yG74fKb5x81LnUCZzYo,1916
|
|
48
|
+
synapse_sdk/utils/module_loading.py,sha256=chHpU-BZjtYaTBD_q0T7LcKWtqKvYBS4L0lPlKkoMQ8,1020
|
|
49
|
+
synapse_sdk/utils/storage.py,sha256=6L3pgno3Luw6GuSRPdiIvS4ZFzjwGP6sLDKMy719pBw,2622
|
|
50
|
+
synapse_sdk/utils/string.py,sha256=rEwuZ9SAaZLcQ8TYiwNKr1h2u4CfnrQx7SUL8NWmChg,216
|
|
51
|
+
synapse_sdk-1.0.0a1.dist-info/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
|
|
52
|
+
synapse_sdk-1.0.0a1.dist-info/METADATA,sha256=zGbciSdYPvJ1Vl_sk5D0pmTNMqTuemSgkF9QbaVBXec,503
|
|
53
|
+
synapse_sdk-1.0.0a1.dist-info/WHEEL,sha256=a7TGlA-5DaHMRrarXjVbQagU3Man_dCnGIWMJr5kRWo,91
|
|
54
|
+
synapse_sdk-1.0.0a1.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
|
|
55
|
+
synapse_sdk-1.0.0a1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
synapse_sdk
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
class IntegrationClientMixin:
|
|
2
|
-
def get_plugin(self, pk):
|
|
3
|
-
path = f'plugins/{pk}/'
|
|
4
|
-
return self._get(path)
|
|
5
|
-
|
|
6
|
-
def create_logs(self, data):
|
|
7
|
-
path = 'logs/'
|
|
8
|
-
return self._post(path, payload=data)
|
|
9
|
-
|
|
10
|
-
def create_task(self, data):
|
|
11
|
-
path = 'agent_tasks/'
|
|
12
|
-
return self._post(path, payload=data)
|
synapse/plugins/__init__.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
|
|
3
|
-
from synapse.plugins.utils import get_action
|
|
4
|
-
|
|
5
|
-
action = None
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def init():
|
|
9
|
-
global action
|
|
10
|
-
parser = argparse.ArgumentParser(description='synapse plugin runner')
|
|
11
|
-
|
|
12
|
-
# Add arguments
|
|
13
|
-
parser.add_argument('action', help='action to run on this plugin')
|
|
14
|
-
parser.add_argument('params', help='parameter of the action')
|
|
15
|
-
|
|
16
|
-
# Parse arguments
|
|
17
|
-
args = parser.parse_args()
|
|
18
|
-
|
|
19
|
-
# Access parsed arguments
|
|
20
|
-
action = args.action
|
|
21
|
-
params = args.params
|
|
22
|
-
|
|
23
|
-
action = get_action(action, params)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def run():
|
|
27
|
-
global action
|
|
28
|
-
assert action is not None
|
|
29
|
-
action.run()
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
__all__ = ['init', 'run']
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
from synapse.plugins.categories.neural_net.actions.deployment import DeploymentAction
|
|
2
|
-
from synapse.plugins.categories.neural_net.actions.test import TestAction
|
|
3
|
-
from synapse.plugins.categories.neural_net.actions.train import TrainAction
|
|
4
|
-
|
|
5
|
-
ACTIONS = {
|
|
6
|
-
'neural_net': {
|
|
7
|
-
'deployment': DeploymentAction,
|
|
8
|
-
'train': TrainAction,
|
|
9
|
-
'test': TestAction,
|
|
10
|
-
},
|
|
11
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from functools import cached_property
|
|
3
|
-
|
|
4
|
-
from synapse.loggers import ConsoleLogger
|
|
5
|
-
from synapse.plugins.utils import get_plugin_checksum
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Action:
|
|
9
|
-
params = None
|
|
10
|
-
config = None
|
|
11
|
-
client = None
|
|
12
|
-
logger = None
|
|
13
|
-
|
|
14
|
-
def __init__(self, params, config):
|
|
15
|
-
self.params = params
|
|
16
|
-
self.config = config
|
|
17
|
-
|
|
18
|
-
# TODO logger 지정 방식 개선
|
|
19
|
-
self.logger = ConsoleLogger()
|
|
20
|
-
|
|
21
|
-
@cached_property
|
|
22
|
-
def plugin_id(self):
|
|
23
|
-
code = self.config['code']
|
|
24
|
-
version = self.config['version']
|
|
25
|
-
return f'{code}@{version}'
|
|
26
|
-
|
|
27
|
-
@cached_property
|
|
28
|
-
def plugin_checksum(self):
|
|
29
|
-
return get_plugin_checksum(self.plugin_id)
|
|
30
|
-
|
|
31
|
-
def get_plugin_url(self):
|
|
32
|
-
base_url = os.getenv('SYNAPSE_PLUGIN_BASE_URL')
|
|
33
|
-
return str(os.path.join(base_url, f'{self.plugin_checksum}.zip'))
|
|
34
|
-
|
|
35
|
-
def get_runtime_env(self):
|
|
36
|
-
return {'working_dir': self.get_plugin_url()}
|
|
37
|
-
|
|
38
|
-
def run(self):
|
|
39
|
-
raise NotImplementedError
|
|
40
|
-
|
|
41
|
-
def set_progress(self, current, total, category=''):
|
|
42
|
-
self.logger.set_progress(current, total, category)
|
|
43
|
-
|
|
44
|
-
def log(self, action, data):
|
|
45
|
-
self.logger.log(action, data)
|
|
46
|
-
|
|
47
|
-
def log_event(self, message):
|
|
48
|
-
self.logger.log('event', {'content': message})
|
|
49
|
-
|
|
50
|
-
def end_log(self):
|
|
51
|
-
self.log_event('Plugin run is complete.')
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
from ray import serve
|
|
2
|
-
|
|
3
|
-
from synapse.plugins.categories.base import Action
|
|
4
|
-
from synapse.utils.module_loading import import_string
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class DeploymentAction(Action):
|
|
8
|
-
deployment = None
|
|
9
|
-
|
|
10
|
-
def __init__(self, *args, **kwargs):
|
|
11
|
-
super().__init__(*args, **kwargs)
|
|
12
|
-
self.deployment = self.get_deployment()
|
|
13
|
-
|
|
14
|
-
def get_deployment(self):
|
|
15
|
-
entrypoint = self.config['actions']['deployment']['entrypoint']
|
|
16
|
-
deployment = import_string(entrypoint)
|
|
17
|
-
return serve.deployment(ray_actor_options=self.get_actor_options())(deployment)
|
|
18
|
-
|
|
19
|
-
def get_actor_options(self):
|
|
20
|
-
return {'runtime_env': self.get_runtime_env()}
|
|
21
|
-
|
|
22
|
-
def run(self):
|
|
23
|
-
serve.delete(self.plugin_id)
|
|
24
|
-
serve.run(self.deployment.bind(), name=self.plugin_id, route_prefix=f'/{self.plugin_checksum}')
|
synapse/plugins/utils.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
|
|
3
|
-
from synapse.utils.file import get_dict_from_file
|
|
4
|
-
from synapse.utils.string import hash_text
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def get_action(action, json_or_path):
|
|
8
|
-
from synapse.plugins.categories import ACTIONS
|
|
9
|
-
|
|
10
|
-
try:
|
|
11
|
-
params = json.loads(json_or_path)
|
|
12
|
-
except json.JSONDecodeError:
|
|
13
|
-
params = get_dict_from_file(json_or_path)
|
|
14
|
-
config = get_dict_from_file('config.yaml')
|
|
15
|
-
category = config['category']
|
|
16
|
-
return ACTIONS[category][action](params, config)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def get_available_actions(category):
|
|
20
|
-
from synapse.plugins.categories import ACTIONS
|
|
21
|
-
|
|
22
|
-
return list(ACTIONS[category].keys())
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def get_plugin_checksum(plugin_id):
|
|
26
|
-
return hash_text(plugin_id)
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
synapse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
synapse/config.py,sha256=AHyTHtzkkCZb9DLu1_R99VOwPgWATZj4K7yzHaPijfA,149
|
|
3
|
-
synapse/loggers.py,sha256=xFZl1sHffhRShtZoTwlNG7zAtkrG9FDxZDMz8xdvzyg,1327
|
|
4
|
-
synapse/client/__init__.py,sha256=zX2xGXMkcXLQ0zs96K6oQYvNkMlh4P1Xpmw-fvg6MEE,3400
|
|
5
|
-
synapse/client/exceptions.py,sha256=LzgzPKRPhNUpLh-jBQHKze8c3CQoVA22jSfjUMBZCuU,405
|
|
6
|
-
synapse/client/utils.py,sha256=8pPJTdzHiRPSbZMoQYHAgR2BAMO6u_R_jMV6a2p34iQ,392
|
|
7
|
-
synapse/client/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
synapse/client/mixins/annotation.py,sha256=69xblc0RLokKlpSfIzoJ5dVRvw3VpPIVgbQKV3L5Xx4,905
|
|
9
|
-
synapse/client/mixins/dataset.py,sha256=KXsen7-vdSzdR09uxD88lT604ItJKuCOSLR3fEU5ud0,1666
|
|
10
|
-
synapse/client/mixins/integration.py,sha256=LfMgPsP_OBNCZmSTpEThlLcSnOHv1-H8EhhryPNriCE,336
|
|
11
|
-
synapse/client/mixins/ml.py,sha256=xkfO95k6p_nQVyai2zBO-z4b9nh6YIryN4iakDGiPsE,891
|
|
12
|
-
synapse/plugins/__init__.py,sha256=OCcxzbGsQ68zPbz3Nyd21_oqL1W9ocJU_e5wNbS9wUc,623
|
|
13
|
-
synapse/plugins/utils.py,sha256=G5Ife0tveVbKpMjAI7sBFTLO5Kul8sAS--SFhlMy_1M,669
|
|
14
|
-
synapse/plugins/categories/__init__.py,sha256=jIL3HdMQVliX7IMWUnKW1ttp0kyVL9YwsXAXFMeRK9Q,376
|
|
15
|
-
synapse/plugins/categories/base.py,sha256=cqBGGPLHNqczdvsRNKiLSceQkFVVHH1zYaMschEBBG8,1330
|
|
16
|
-
synapse/plugins/categories/custom_script/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
-
synapse/plugins/categories/custom_script/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
synapse/plugins/categories/export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
synapse/plugins/categories/export/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
-
synapse/plugins/categories/import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
-
synapse/plugins/categories/import/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
synapse/plugins/categories/neural_net/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
-
synapse/plugins/categories/neural_net/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
-
synapse/plugins/categories/neural_net/actions/deployment.py,sha256=B86zjVbxLO7WsSqPGNgReTetAilt2wRj4VI3TS38UXo,805
|
|
25
|
-
synapse/plugins/categories/neural_net/actions/test.py,sha256=XX2dcwNAEkn7mFliwPb70cx7wn0LL_QcDQ7EW6n-H2w,111
|
|
26
|
-
synapse/plugins/categories/neural_net/actions/train.py,sha256=lQvqVyC8lqVcs8x6v4bD1vTQyDrUz15gSiodEOPGcQc,3100
|
|
27
|
-
synapse/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
synapse/utils/file.py,sha256=kwNoOAzJqT6v2fBHUhhs9sW2mdziUJmYHOxPzIodhmE,1578
|
|
29
|
-
synapse/utils/module_loading.py,sha256=chHpU-BZjtYaTBD_q0T7LcKWtqKvYBS4L0lPlKkoMQ8,1020
|
|
30
|
-
synapse/utils/string.py,sha256=FMH1vlh7BsDcawCiov3HtQEcjp3KSHmjcZ2wZ9EeGu0,141
|
|
31
|
-
synapse_sdk-0.1.2a0.dist-info/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
|
|
32
|
-
synapse_sdk-0.1.2a0.dist-info/METADATA,sha256=I093h4TrY-MzSy5apNzHgxcRAXn6QcLxqHgji2qMtyo,432
|
|
33
|
-
synapse_sdk-0.1.2a0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
34
|
-
synapse_sdk-0.1.2a0.dist-info/top_level.txt,sha256=v_1YsqjmoSCzCKs7oIhzTNmWtSYoORiBMv1TJkOhx8A,8
|
|
35
|
-
synapse_sdk-0.1.2a0.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
synapse
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{synapse/plugins/categories/export/actions → synapse_sdk/plugins/categories/export}/__init__.py
RENAMED
|
File without changes
|
{synapse/plugins/categories/import → synapse_sdk/plugins/categories/export/actions}/__init__.py
RENAMED
|
File without changes
|
{synapse/plugins/categories/import/actions → synapse_sdk/plugins/categories/import}/__init__.py
RENAMED
|
File without changes
|
{synapse/plugins/categories/neural_net → synapse_sdk/plugins/categories/import/actions}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|