synapse-sdk 1.0.0a6__py3-none-any.whl → 1.0.0a8__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_sdk/clients/backend/annotation.py +10 -10
- synapse_sdk/clients/backend/dataset.py +6 -5
- synapse_sdk/clients/backend/integration.py +8 -0
- synapse_sdk/clients/backend/ml.py +8 -7
- synapse_sdk/clients/base.py +7 -1
- synapse_sdk/loggers.py +74 -12
- synapse_sdk/plugins/categories/base.py +54 -38
- synapse_sdk/plugins/categories/data_validation/actions/validation.py +1 -1
- synapse_sdk/plugins/categories/data_validation/templates/config.yaml +3 -0
- synapse_sdk/plugins/categories/data_validation/templates/plugin/__init__.py +0 -0
- synapse_sdk/plugins/categories/data_validation/templates/plugin/validation.py +5 -0
- synapse_sdk/plugins/categories/export/actions/export.py +1 -1
- synapse_sdk/plugins/categories/import/actions/import.py +1 -1
- synapse_sdk/plugins/categories/neural_net/actions/deployment.py +2 -1
- synapse_sdk/plugins/categories/neural_net/actions/inference.py +1 -1
- synapse_sdk/plugins/categories/neural_net/actions/test.py +2 -2
- synapse_sdk/plugins/categories/neural_net/actions/train.py +120 -15
- synapse_sdk/plugins/categories/neural_net/templates/plugin/train.py +1 -1
- synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py +1 -1
- synapse_sdk/plugins/categories/post_annotation/templates/config.yaml +3 -0
- synapse_sdk/plugins/categories/post_annotation/templates/plugin/__init__.py +0 -0
- synapse_sdk/plugins/categories/post_annotation/templates/plugin/post_annotation.py +3 -0
- synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py +1 -1
- synapse_sdk/plugins/categories/pre_annotation/templates/config.yaml +3 -0
- synapse_sdk/plugins/categories/pre_annotation/templates/plugin/__init__.py +0 -0
- synapse_sdk/plugins/categories/pre_annotation/templates/plugin/pre_annotation.py +3 -0
- synapse_sdk/plugins/categories/smart_tool/__init__.py +0 -0
- synapse_sdk/plugins/categories/smart_tool/actions/__init__.py +0 -0
- synapse_sdk/plugins/categories/smart_tool/actions/auto_label.py +22 -0
- synapse_sdk/plugins/categories/smart_tool/templates/config.yaml +6 -0
- synapse_sdk/plugins/categories/smart_tool/templates/plugin/__init__.py +0 -0
- synapse_sdk/plugins/categories/smart_tool/templates/plugin/auto_label.py +11 -0
- synapse_sdk/plugins/enums.py +5 -0
- synapse_sdk/plugins/exceptions.py +6 -0
- synapse_sdk/plugins/models.py +40 -4
- synapse_sdk/plugins/templates/hooks/pre_prompt.py +1 -0
- synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml +0 -12
- synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml +1 -1
- synapse_sdk/utils/file.py +15 -0
- synapse_sdk/utils/pydantic/__init__.py +0 -0
- synapse_sdk/utils/pydantic/config.py +4 -0
- synapse_sdk/utils/pydantic/errors.py +33 -0
- synapse_sdk/utils/pydantic/validators.py +7 -0
- synapse_sdk/utils/storage.py +1 -1
- {synapse_sdk-1.0.0a6.dist-info → synapse_sdk-1.0.0a8.dist-info}/METADATA +2 -2
- {synapse_sdk-1.0.0a6.dist-info → synapse_sdk-1.0.0a8.dist-info}/RECORD +50 -30
- {synapse_sdk-1.0.0a6.dist-info → synapse_sdk-1.0.0a8.dist-info}/WHEEL +1 -1
- {synapse_sdk-1.0.0a6.dist-info → synapse_sdk-1.0.0a8.dist-info}/LICENSE +0 -0
- {synapse_sdk-1.0.0a6.dist-info → synapse_sdk-1.0.0a8.dist-info}/entry_points.txt +0 -0
- {synapse_sdk-1.0.0a6.dist-info → synapse_sdk-1.0.0a8.dist-info}/top_level.txt +0 -0
|
@@ -7,23 +7,23 @@ class AnnotationClientMixin(BaseClient):
|
|
|
7
7
|
path = f'projects/{pk}/'
|
|
8
8
|
return self._get(path)
|
|
9
9
|
|
|
10
|
-
def
|
|
11
|
-
path = f'
|
|
10
|
+
def get_task_tag(self, pk):
|
|
11
|
+
path = f'task_tags/{pk}/'
|
|
12
12
|
return self._get(path)
|
|
13
13
|
|
|
14
|
-
def
|
|
15
|
-
path = '
|
|
14
|
+
def list_task_tags(self, data):
|
|
15
|
+
path = 'task_tags/'
|
|
16
16
|
return self._list(path, data=data)
|
|
17
17
|
|
|
18
|
-
def
|
|
19
|
-
path = '
|
|
18
|
+
def list_tasks(self, data, url_conversion=None, list_all=False):
|
|
19
|
+
path = 'tasks/'
|
|
20
20
|
url_conversion = get_default_url_conversion(url_conversion, files_fields=['files'])
|
|
21
21
|
return self._list(path, data=data, url_conversion=url_conversion, list_all=list_all)
|
|
22
22
|
|
|
23
|
-
def
|
|
24
|
-
path = '
|
|
23
|
+
def create_tasks(self, data):
|
|
24
|
+
path = 'tasks/'
|
|
25
25
|
return self._post(path, data=data)
|
|
26
26
|
|
|
27
|
-
def
|
|
28
|
-
path = '
|
|
27
|
+
def set_tags_tasks(self, data, params=None):
|
|
28
|
+
path = 'tasks/set_tags/'
|
|
29
29
|
return self._post(path, data=data, params=params)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from multiprocessing import Pool
|
|
2
|
+
|
|
2
3
|
from tqdm import tqdm
|
|
3
4
|
|
|
4
5
|
from synapse_sdk.clients.base import BaseClient
|
|
@@ -32,15 +33,15 @@ class DatasetClientMixin(BaseClient):
|
|
|
32
33
|
data_units = self.create_data_units(batch)
|
|
33
34
|
|
|
34
35
|
if project_id:
|
|
35
|
-
|
|
36
|
+
tasks_data = []
|
|
36
37
|
for data, data_unit in zip(batch, data_units):
|
|
37
|
-
|
|
38
|
+
task_data = {'project': project_id, 'data_unit': data_unit['id']}
|
|
38
39
|
if 'ground_truth' in data:
|
|
39
|
-
|
|
40
|
+
task_data['ground_truth'] = data['ground_truth']
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
tasks_data.append(task_data)
|
|
42
43
|
|
|
43
|
-
self.
|
|
44
|
+
self.create_tasks(tasks_data)
|
|
44
45
|
|
|
45
46
|
def import_data_file(self, data, dataset_id):
|
|
46
47
|
for name, path in data['files'].items():
|
|
@@ -27,6 +27,14 @@ class IntegrationClientMixin(BaseClient):
|
|
|
27
27
|
files = {'file': data.pop('file')}
|
|
28
28
|
return self._post(path, data=data, files=files)
|
|
29
29
|
|
|
30
|
+
def list_jobs(self, params=None):
|
|
31
|
+
path = 'jobs/'
|
|
32
|
+
return self._get(path, params=params)
|
|
33
|
+
|
|
34
|
+
def update_job(self, pk, data):
|
|
35
|
+
path = f'jobs/{pk}/'
|
|
36
|
+
return self._patch(path, data=data)
|
|
37
|
+
|
|
30
38
|
def list_job_console_logs(self, pk):
|
|
31
39
|
path = f'jobs/{pk}/console_logs/'
|
|
32
40
|
return self._get(path)
|
|
@@ -3,6 +3,10 @@ from synapse_sdk.clients.utils import get_default_url_conversion
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class MLClientMixin(BaseClient):
|
|
6
|
+
def list_models(self, params=None):
|
|
7
|
+
path = 'models/'
|
|
8
|
+
return self._get(path, params=params)
|
|
9
|
+
|
|
6
10
|
def get_model(self, pk, params=None, url_conversion=None):
|
|
7
11
|
path = f'models/{pk}/'
|
|
8
12
|
url_conversion = get_default_url_conversion(
|
|
@@ -12,13 +16,10 @@ class MLClientMixin(BaseClient):
|
|
|
12
16
|
|
|
13
17
|
def create_model(self, data):
|
|
14
18
|
path = 'models/'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def update_model(self, pk, data, files=None):
|
|
18
|
-
path = f'models/{pk}/'
|
|
19
|
-
return self._patch(path, data=data, files=files)
|
|
19
|
+
files = {'file': data.pop('file')}
|
|
20
|
+
return self._post(path, data=data, files=files)
|
|
20
21
|
|
|
21
|
-
def
|
|
22
|
-
path = '
|
|
22
|
+
def list_ground_truth_events(self, params=None, url_conversion=None, list_all=False):
|
|
23
|
+
path = 'ground_truth_events/'
|
|
23
24
|
url_conversion = get_default_url_conversion(url_conversion, files_fields=['files'])
|
|
24
25
|
return self._list(path, params=params, url_conversion=url_conversion, list_all=list_all)
|
synapse_sdk/clients/base.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import json
|
|
2
|
+
import os
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
5
|
import requests
|
|
@@ -33,6 +33,9 @@ class BaseClient:
|
|
|
33
33
|
if kwargs.get('files') is not None:
|
|
34
34
|
for name, file in kwargs['files'].items():
|
|
35
35
|
kwargs['files'][name] = Path(str(file)).open(mode='rb')
|
|
36
|
+
for name, value in kwargs['data'].items():
|
|
37
|
+
if isinstance(value, dict):
|
|
38
|
+
kwargs['data'][name] = json.dumps(value)
|
|
36
39
|
else:
|
|
37
40
|
headers['Content-Type'] = 'application/json'
|
|
38
41
|
if 'data' in kwargs:
|
|
@@ -79,3 +82,6 @@ class BaseClient:
|
|
|
79
82
|
yield from response['results']
|
|
80
83
|
if response['next']:
|
|
81
84
|
yield from self._list_all(response['next'], url_conversion, **kwargs)
|
|
85
|
+
|
|
86
|
+
def exists(self, api, *args, **kwargs):
|
|
87
|
+
return getattr(self, api)(*args, **kwargs)['count'] > 0
|
synapse_sdk/loggers.py
CHANGED
|
@@ -1,24 +1,78 @@
|
|
|
1
1
|
import datetime
|
|
2
|
+
import time
|
|
2
3
|
|
|
3
4
|
from synapse_sdk.clients.exceptions import ClientError
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class BaseLogger:
|
|
7
|
-
|
|
8
|
+
progress_record = {}
|
|
9
|
+
progress_categories = None
|
|
10
|
+
current_category = None
|
|
11
|
+
time_begin_per_category = {}
|
|
8
12
|
|
|
9
|
-
def
|
|
10
|
-
|
|
11
|
-
if
|
|
12
|
-
|
|
13
|
-
percent = float(round(percent, 2))
|
|
13
|
+
def __init__(self, progress_categories=None):
|
|
14
|
+
self.progress_categories = progress_categories
|
|
15
|
+
if progress_categories:
|
|
16
|
+
self.progress_record['categories'] = progress_categories
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
def set_progress(self, current, total, category=None):
|
|
19
|
+
assert 0 <= current <= total and total > 0
|
|
20
|
+
assert category is not None or 'categories' not in self.progress_record
|
|
21
|
+
|
|
22
|
+
percent = (current / total) * 100
|
|
23
|
+
percent = round(percent, 2)
|
|
24
|
+
# TODO current 0 으로 시작하지 않아도 작동되도록 수정
|
|
25
|
+
if current == 0:
|
|
26
|
+
self.time_begin_per_category[category] = time.time()
|
|
27
|
+
time_remaining = None
|
|
28
|
+
else:
|
|
29
|
+
seconds_per_item = (time.time() - self.time_begin_per_category[category]) / current
|
|
30
|
+
time_remaining = round(seconds_per_item * (total - current), 2)
|
|
31
|
+
|
|
32
|
+
current_progress = {'percent': percent, 'time_remaining': time_remaining}
|
|
33
|
+
|
|
34
|
+
if category:
|
|
35
|
+
self.current_category = category
|
|
36
|
+
self.progress_record['categories'][category].update(current_progress)
|
|
37
|
+
else:
|
|
38
|
+
self.progress_record.update(current_progress)
|
|
39
|
+
|
|
40
|
+
def get_current_progress(self):
|
|
41
|
+
categories = self.progress_record.get('categories')
|
|
42
|
+
|
|
43
|
+
if categories:
|
|
44
|
+
category_progress = None
|
|
45
|
+
|
|
46
|
+
overall = 0
|
|
47
|
+
for category, category_record in categories.items():
|
|
48
|
+
if category == self.current_category:
|
|
49
|
+
break
|
|
50
|
+
overall += category_record['proportion']
|
|
51
|
+
|
|
52
|
+
category_record = categories[self.current_category]
|
|
53
|
+
category_percent = category_record.get('percent', 0)
|
|
54
|
+
if not category_progress and 'percent' in category_record:
|
|
55
|
+
category_progress = {
|
|
56
|
+
'category': self.current_category,
|
|
57
|
+
'percent': category_percent,
|
|
58
|
+
'time_remaining': category_record.get('time_remaining'),
|
|
59
|
+
}
|
|
60
|
+
if category_percent > 0:
|
|
61
|
+
overall += round(category_record['proportion'] / 100 * category_percent, 2)
|
|
62
|
+
progress = {'overall': overall, **category_progress}
|
|
63
|
+
else:
|
|
64
|
+
progress = {
|
|
65
|
+
'overall': self.progress_record.get('percent'),
|
|
66
|
+
'time_remaining': self.progress_record.get('time_remaining'),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return progress
|
|
16
70
|
|
|
17
71
|
|
|
18
72
|
class ConsoleLogger(BaseLogger):
|
|
19
|
-
def set_progress(self, current, total, category=
|
|
73
|
+
def set_progress(self, current, total, category=None):
|
|
20
74
|
super().set_progress(current, total, category=category)
|
|
21
|
-
print(self.
|
|
75
|
+
print(self.get_current_progress())
|
|
22
76
|
|
|
23
77
|
def log(self, action, data):
|
|
24
78
|
print(action, data)
|
|
@@ -29,13 +83,21 @@ class BackendLogger(BaseLogger):
|
|
|
29
83
|
client = None
|
|
30
84
|
job_id = None
|
|
31
85
|
|
|
32
|
-
def __init__(self, client, job_id):
|
|
86
|
+
def __init__(self, client, job_id, **kwargs):
|
|
87
|
+
super().__init__(**kwargs)
|
|
33
88
|
self.client = client
|
|
34
89
|
self.job_id = job_id
|
|
35
90
|
|
|
36
|
-
def set_progress(self, current, total, category=
|
|
91
|
+
def set_progress(self, current, total, category=None):
|
|
37
92
|
super().set_progress(current, total, category=category)
|
|
38
|
-
|
|
93
|
+
try:
|
|
94
|
+
progress_record = {
|
|
95
|
+
'record': self.progress_record,
|
|
96
|
+
'current_progress': self.get_current_progress(),
|
|
97
|
+
}
|
|
98
|
+
self.client.update_job(self.job_id, data={'progress_record': progress_record})
|
|
99
|
+
except ClientError:
|
|
100
|
+
pass
|
|
39
101
|
|
|
40
102
|
def log(self, action, data):
|
|
41
103
|
print(action, data)
|
|
@@ -6,27 +6,36 @@ from pprint import pprint
|
|
|
6
6
|
|
|
7
7
|
import ray
|
|
8
8
|
import requests
|
|
9
|
+
from pydantic import ValidationError
|
|
9
10
|
from ray.dashboard.modules.job.sdk import JobSubmissionClient
|
|
10
11
|
|
|
11
|
-
from synapse_sdk.clients.backend import BackendClient
|
|
12
|
-
from synapse_sdk.loggers import ConsoleLogger, BackendLogger
|
|
13
12
|
from synapse_sdk.plugins.enums import RunMethod
|
|
14
|
-
from synapse_sdk.plugins.
|
|
15
|
-
from synapse_sdk.plugins.
|
|
13
|
+
from synapse_sdk.plugins.exceptions import ActionValidationError
|
|
14
|
+
from synapse_sdk.plugins.models import PluginRelease, Run
|
|
15
|
+
from synapse_sdk.plugins.upload import archive_and_upload, build_and_upload, download_and_upload
|
|
16
16
|
from synapse_sdk.utils.module_loading import import_string
|
|
17
|
+
from synapse_sdk.utils.pydantic.errors import pydantic_to_drf_error
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class Action:
|
|
21
|
+
# class 변수
|
|
20
22
|
name = None
|
|
21
23
|
category = None
|
|
22
24
|
method = None
|
|
25
|
+
run_class = Run
|
|
26
|
+
params_model = None
|
|
27
|
+
progress_categories = None
|
|
28
|
+
|
|
29
|
+
# init 변수
|
|
23
30
|
params = None
|
|
24
31
|
plugin_config = None
|
|
25
32
|
plugin_release = None
|
|
26
33
|
config = None
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
debug =
|
|
34
|
+
job_id = None
|
|
35
|
+
direct = None
|
|
36
|
+
debug = None
|
|
37
|
+
envs = None
|
|
38
|
+
run = None
|
|
30
39
|
|
|
31
40
|
default_envs = [
|
|
32
41
|
'RAY_DASHBOARD_URL',
|
|
@@ -48,7 +57,7 @@ class Action:
|
|
|
48
57
|
self.direct = direct
|
|
49
58
|
self.debug = debug
|
|
50
59
|
self.envs = {**envs, **self.get_default_envs()} if envs else self.get_default_envs()
|
|
51
|
-
self.
|
|
60
|
+
self.run = self.get_run()
|
|
52
61
|
|
|
53
62
|
@cached_property
|
|
54
63
|
def entrypoint(self):
|
|
@@ -58,6 +67,10 @@ class Action:
|
|
|
58
67
|
def plugin_storage_url(self):
|
|
59
68
|
return self.envs['SYNAPSE_PLUGIN_STORAGE']
|
|
60
69
|
|
|
70
|
+
@property
|
|
71
|
+
def client(self):
|
|
72
|
+
return self.run.client
|
|
73
|
+
|
|
61
74
|
@property
|
|
62
75
|
def plugin_url(self):
|
|
63
76
|
if self.debug:
|
|
@@ -84,16 +97,15 @@ class Action:
|
|
|
84
97
|
self.envs['SYNAPSE_DEBUG_MODULES'] = ','.join(debug_modules)
|
|
85
98
|
return debug_modules
|
|
86
99
|
|
|
87
|
-
def
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
self.logger = ConsoleLogger()
|
|
100
|
+
def get_run(self):
|
|
101
|
+
context = {
|
|
102
|
+
'plugin_release': self.plugin_release,
|
|
103
|
+
'progress_categories': self.progress_categories,
|
|
104
|
+
'params': self.params,
|
|
105
|
+
'envs': self.envs,
|
|
106
|
+
'debug': self.debug,
|
|
107
|
+
}
|
|
108
|
+
return self.run_class(self.job_id, context)
|
|
97
109
|
|
|
98
110
|
def get_default_envs(self):
|
|
99
111
|
return {env: os.environ[env] for env in self.default_envs if env in os.environ}
|
|
@@ -105,7 +117,7 @@ class Action:
|
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
if self.debug:
|
|
108
|
-
runtime_env['pip']
|
|
120
|
+
runtime_env['pip'] += self.debug_modules
|
|
109
121
|
|
|
110
122
|
# 맨 마지막에 진행되어야 함
|
|
111
123
|
runtime_env['env_vars'] = self.envs
|
|
@@ -114,18 +126,30 @@ class Action:
|
|
|
114
126
|
pprint(runtime_env)
|
|
115
127
|
return runtime_env
|
|
116
128
|
|
|
117
|
-
def
|
|
118
|
-
|
|
129
|
+
def validate_params(self):
|
|
130
|
+
if self.params_model:
|
|
131
|
+
try:
|
|
132
|
+
self.params_model.model_validate(self.params, context={'action': self})
|
|
133
|
+
except ValidationError as e:
|
|
134
|
+
raise ActionValidationError({'params': pydantic_to_drf_error(e)})
|
|
119
135
|
|
|
120
136
|
def run_action(self):
|
|
137
|
+
self.validate_params()
|
|
121
138
|
if self.direct:
|
|
122
139
|
if self.method == RunMethod.RESTAPI:
|
|
123
|
-
return self.
|
|
140
|
+
return self.start_by_restapi()
|
|
124
141
|
else:
|
|
125
|
-
|
|
126
|
-
|
|
142
|
+
result = self.start()
|
|
143
|
+
self.post_action_by_job(result)
|
|
144
|
+
return result
|
|
145
|
+
return getattr(self, f'start_by_{self.method.value}')()
|
|
127
146
|
|
|
128
|
-
def
|
|
147
|
+
def start(self):
|
|
148
|
+
if self.method == RunMethod.JOB:
|
|
149
|
+
return self.entrypoint(self.run, **self.params)
|
|
150
|
+
return self.entrypoint(**self.params)
|
|
151
|
+
|
|
152
|
+
def start_by_task(self):
|
|
129
153
|
@ray.remote(runtime_env=self.get_runtime_env())
|
|
130
154
|
def run_task(category, action, *args, **kwargs):
|
|
131
155
|
from synapse_sdk.plugins.utils import get_action_class
|
|
@@ -149,7 +173,7 @@ class Action:
|
|
|
149
173
|
kwargs['direct'] = True
|
|
150
174
|
return ray.get(run_task.remote(self.category.value, self.name, *args, **kwargs))
|
|
151
175
|
|
|
152
|
-
def
|
|
176
|
+
def start_by_job(self):
|
|
153
177
|
main_options = []
|
|
154
178
|
options = ['run', '--direct']
|
|
155
179
|
arguments = [self.name, f'{json.dumps(json.dumps(self.params))}']
|
|
@@ -169,7 +193,7 @@ class Action:
|
|
|
169
193
|
runtime_env=self.get_runtime_env(),
|
|
170
194
|
)
|
|
171
195
|
|
|
172
|
-
def
|
|
196
|
+
def start_by_restapi(self):
|
|
173
197
|
path = self.params.pop('path', '')
|
|
174
198
|
method = self.params.pop('method')
|
|
175
199
|
|
|
@@ -178,14 +202,6 @@ class Action:
|
|
|
178
202
|
# TODO ok response가 아닌 경우 대응하기
|
|
179
203
|
return response.json()
|
|
180
204
|
|
|
181
|
-
def
|
|
182
|
-
self.
|
|
183
|
-
|
|
184
|
-
def log(self, action, data):
|
|
185
|
-
self.logger.log(action, data)
|
|
186
|
-
|
|
187
|
-
def log_event(self, message):
|
|
188
|
-
self.logger.log('event', {'content': message})
|
|
189
|
-
|
|
190
|
-
def end_log(self):
|
|
191
|
-
self.log_event('Plugin run is complete.')
|
|
205
|
+
def post_action_by_job(self, result):
|
|
206
|
+
if self.client:
|
|
207
|
+
self.client.update_job(self.job_id, data={'result': result})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
2
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
3
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@register_action
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
2
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
3
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@register_action
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
2
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
3
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@register_action
|
|
@@ -17,7 +17,8 @@ class DeploymentAction(Action):
|
|
|
17
17
|
def get_actor_options(self):
|
|
18
18
|
return {'runtime_env': self.get_runtime_env()}
|
|
19
19
|
|
|
20
|
-
def
|
|
20
|
+
def start(self):
|
|
21
21
|
deployment = self.get_deployment()
|
|
22
22
|
serve.delete(self.plugin_release.code)
|
|
23
|
+
# TODO add run object
|
|
23
24
|
serve.run(deployment.bind(), name=self.plugin_release.code, route_prefix=f'/{self.plugin_release.checksum}')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
2
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
3
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@register_action
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
2
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
3
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@register_action
|
|
7
7
|
class TestAction(Action):
|
|
8
8
|
name = 'test'
|
|
9
9
|
category = PluginCategory.NEURAL_NET
|
|
10
|
-
method = RunMethod.
|
|
10
|
+
method = RunMethod.JOB
|
|
@@ -1,6 +1,60 @@
|
|
|
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
|
|
1
11
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
12
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
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, x, i, **kwargs):
|
|
21
|
+
self.log(x, {x: i, **kwargs})
|
|
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
|
|
4
58
|
|
|
5
59
|
|
|
6
60
|
@register_action
|
|
@@ -8,30 +62,81 @@ class TrainAction(Action):
|
|
|
8
62
|
name = 'train'
|
|
9
63
|
category = PluginCategory.NEURAL_NET
|
|
10
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
|
+
}
|
|
11
78
|
|
|
12
|
-
def
|
|
13
|
-
return {}
|
|
14
|
-
|
|
15
|
-
def run(self):
|
|
79
|
+
def start(self):
|
|
16
80
|
hyperparameter = self.params['hyperparameter']
|
|
17
81
|
|
|
18
82
|
# download dataset
|
|
19
|
-
self.log_event('Preparing dataset for training.')
|
|
83
|
+
self.run.log_event('Preparing dataset for training.')
|
|
20
84
|
input_dataset = self.get_dataset()
|
|
21
85
|
|
|
22
86
|
# train dataset
|
|
23
|
-
self.log_event('Starting model training.')
|
|
87
|
+
self.run.log_event('Starting model training.')
|
|
24
88
|
|
|
25
|
-
|
|
89
|
+
result = self.entrypoint(self.run, input_dataset, hyperparameter)
|
|
26
90
|
|
|
27
91
|
# upload model_data
|
|
28
|
-
self.log_event('Registering model data.')
|
|
92
|
+
self.run.log_event('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')
|
|
29
96
|
|
|
30
|
-
self.end_log()
|
|
31
|
-
return
|
|
97
|
+
self.run.end_log()
|
|
98
|
+
return {'model_id': model['id']}
|
|
32
99
|
|
|
33
|
-
def
|
|
34
|
-
self.
|
|
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
|
+
|
|
127
|
+
params = copy.deepcopy(self.params)
|
|
128
|
+
configuration_fields = ['hyperparameter']
|
|
129
|
+
configuration = {field: params.pop(field) for field in configuration_fields}
|
|
130
|
+
|
|
131
|
+
with tempfile.TemporaryDirectory() as temp_path:
|
|
132
|
+
input_path = Path(path)
|
|
133
|
+
archive_path = Path(temp_path, 'archive.zip')
|
|
134
|
+
archive(input_path, archive_path)
|
|
35
135
|
|
|
36
|
-
|
|
37
|
-
|
|
136
|
+
return self.client.create_model({
|
|
137
|
+
'plugin': self.plugin_release.plugin,
|
|
138
|
+
'version': self.plugin_release.version,
|
|
139
|
+
'file': str(archive_path),
|
|
140
|
+
'configuration': configuration,
|
|
141
|
+
**params,
|
|
142
|
+
})
|
|
@@ -9,6 +9,6 @@ def train(run, dataset, hyperparameter, checkpoint=None):
|
|
|
9
9
|
loss = float(round((count_iterations - i) / count_iterations, 2))
|
|
10
10
|
miou = 1 - loss
|
|
11
11
|
run.log_metric('iteration', i, loss=loss, miou=miou)
|
|
12
|
-
run.set_progress(i, count_iterations, category='
|
|
12
|
+
run.set_progress(i, count_iterations, category='train')
|
|
13
13
|
|
|
14
14
|
return {'weight': '/tmp/agent/test/a.txt', 'config': '/tmp/agent/test/b.txt'}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
2
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
3
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@register_action
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from synapse_sdk.plugins.categories.base import Action
|
|
2
2
|
from synapse_sdk.plugins.categories.decorators import register_action
|
|
3
|
-
from synapse_sdk.plugins.enums import
|
|
3
|
+
from synapse_sdk.plugins.enums import PluginCategory, RunMethod
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
@register_action
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
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 AutoLabelAction(Action):
|
|
8
|
+
name = 'label'
|
|
9
|
+
category = PluginCategory.SMART_TOOL
|
|
10
|
+
method = RunMethod.TASK
|
|
11
|
+
|
|
12
|
+
def get_auto_label(self):
|
|
13
|
+
return self.entrypoint(**self.params)
|
|
14
|
+
|
|
15
|
+
def run_model(self, input_data):
|
|
16
|
+
return {}
|
|
17
|
+
|
|
18
|
+
def start(self):
|
|
19
|
+
auto_label = self.get_auto_label()
|
|
20
|
+
input_data = auto_label.handle_input(self.params['input_data'])
|
|
21
|
+
output_data = self.run_model(input_data)
|
|
22
|
+
return auto_label.handle_output(output_data)
|
|
File without changes
|
synapse_sdk/plugins/enums.py
CHANGED
|
@@ -11,6 +11,11 @@ class PluginCategory(Enum):
|
|
|
11
11
|
NEURAL_NET = 'neural_net'
|
|
12
12
|
EXPORT = 'export'
|
|
13
13
|
IMPORT = 'import'
|
|
14
|
+
SMART_TOOL = 'smart_tool'
|
|
14
15
|
POST_ANNOTATION = 'post_annotation'
|
|
15
16
|
PRE_ANNOTATION = 'pre_annotation'
|
|
16
17
|
DATA_VALIDATION = 'data_validation'
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def choices(cls):
|
|
21
|
+
return [(member.value, member.name.replace('_', ' ').title()) for member in cls]
|
synapse_sdk/plugins/models.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from functools import cached_property
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import Any, Dict
|
|
4
4
|
|
|
5
|
+
from synapse_sdk.clients.backend import BackendClient
|
|
6
|
+
from synapse_sdk.loggers import BackendLogger, ConsoleLogger
|
|
5
7
|
from synapse_sdk.plugins.utils import read_plugin_config
|
|
6
8
|
from synapse_sdk.utils.storage import get_storage
|
|
7
9
|
from synapse_sdk.utils.string import hash_text
|
|
@@ -9,12 +11,14 @@ from synapse_sdk.utils.string import hash_text
|
|
|
9
11
|
|
|
10
12
|
class PluginRelease:
|
|
11
13
|
config: Dict[str, Any]
|
|
14
|
+
envs = None
|
|
12
15
|
|
|
13
|
-
def __init__(self, config=None, plugin_path=None):
|
|
16
|
+
def __init__(self, config=None, plugin_path=None, envs=None):
|
|
14
17
|
if config:
|
|
15
18
|
self.config = config
|
|
16
19
|
else:
|
|
17
20
|
self.config = read_plugin_config(plugin_path=plugin_path)
|
|
21
|
+
self.envs = envs
|
|
18
22
|
|
|
19
23
|
@cached_property
|
|
20
24
|
def plugin(self):
|
|
@@ -59,8 +63,40 @@ class PluginRelease:
|
|
|
59
63
|
return os.path.join(serve_address, self.checksum, path)
|
|
60
64
|
|
|
61
65
|
|
|
62
|
-
class
|
|
66
|
+
class Run:
|
|
67
|
+
logger = None
|
|
63
68
|
job_id = None
|
|
69
|
+
context = None
|
|
64
70
|
|
|
65
|
-
def __init__(self, job_id):
|
|
71
|
+
def __init__(self, job_id, context):
|
|
66
72
|
self.job_id = job_id
|
|
73
|
+
self.context = context
|
|
74
|
+
self.set_logger()
|
|
75
|
+
|
|
76
|
+
def set_logger(self):
|
|
77
|
+
kwargs = {'progress_categories': self.context['progress_categories']}
|
|
78
|
+
if self.job_id:
|
|
79
|
+
client = BackendClient(
|
|
80
|
+
self.context['envs']['SYNAPSE_PLUGIN_RUN_HOST'],
|
|
81
|
+
self.context['envs']['SYNAPSE_PLUGIN_RUN_USER_TOKEN'],
|
|
82
|
+
self.context['envs']['SYNAPSE_PLUGIN_RUN_TENANT'],
|
|
83
|
+
)
|
|
84
|
+
self.logger = BackendLogger(client, self.job_id, **kwargs)
|
|
85
|
+
else:
|
|
86
|
+
self.logger = ConsoleLogger(**kwargs)
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def client(self):
|
|
90
|
+
return getattr(self.logger, 'client', None)
|
|
91
|
+
|
|
92
|
+
def set_progress(self, current, total, category=''):
|
|
93
|
+
self.logger.set_progress(current, total, category)
|
|
94
|
+
|
|
95
|
+
def log(self, action, data):
|
|
96
|
+
self.logger.log(action, data)
|
|
97
|
+
|
|
98
|
+
def log_event(self, message):
|
|
99
|
+
self.logger.log('event', {'content': message})
|
|
100
|
+
|
|
101
|
+
def end_log(self):
|
|
102
|
+
self.log_event('Plugin run is complete.')
|
|
@@ -4,15 +4,3 @@ version: {{ cookiecutter.version }}
|
|
|
4
4
|
readme: README.md
|
|
5
5
|
description: {{ cookiecutter.description }}
|
|
6
6
|
category: {{ cookiecutter.category }}
|
|
7
|
-
actions:
|
|
8
|
-
train:
|
|
9
|
-
dataset: datamaker
|
|
10
|
-
entrypoint: plugin.train.train
|
|
11
|
-
deployment:
|
|
12
|
-
entrypoint: plugin.inference.MockNetInference
|
|
13
|
-
inference:
|
|
14
|
-
method: restapi
|
|
15
|
-
endpoints:
|
|
16
|
-
- method: get
|
|
17
|
-
test:
|
|
18
|
-
entrypoint: plugin.test.test
|
synapse_sdk/utils/file.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import hashlib
|
|
2
2
|
import json
|
|
3
3
|
import operator
|
|
4
|
+
import zipfile
|
|
4
5
|
from functools import reduce
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
@@ -68,3 +69,17 @@ def calculate_checksum(file_path, prefix=''):
|
|
|
68
69
|
if prefix:
|
|
69
70
|
return f'dev-{checksum}'
|
|
70
71
|
return checksum
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def archive(input_path, output_path):
|
|
75
|
+
input_path = Path(input_path)
|
|
76
|
+
output_path = Path(output_path)
|
|
77
|
+
|
|
78
|
+
with zipfile.ZipFile(output_path, mode='w', compression=zipfile.ZIP_DEFLATED) as zipf:
|
|
79
|
+
if input_path.is_file():
|
|
80
|
+
zipf.write(input_path, input_path.name)
|
|
81
|
+
else:
|
|
82
|
+
for file_path in input_path.rglob('*'):
|
|
83
|
+
if file_path.is_file(): # Only add files, skip directories
|
|
84
|
+
arcname = file_path.relative_to(input_path.parent)
|
|
85
|
+
zipf.write(file_path, arcname)
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from typing import Any, Dict
|
|
2
|
+
|
|
3
|
+
from synapse_sdk.utils.pydantic.config import ERROR_MESSAGES
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def pydantic_to_drf_error(e):
|
|
7
|
+
"""
|
|
8
|
+
Convert a pydantic ValidationError into a DRF-style error response.
|
|
9
|
+
"""
|
|
10
|
+
drf_errors: Dict[str, Any] = {}
|
|
11
|
+
|
|
12
|
+
for error in e.errors():
|
|
13
|
+
field_path = error['loc']
|
|
14
|
+
context_error = error.get('ctx', {}).get('error')
|
|
15
|
+
|
|
16
|
+
error_msg = context_error or ERROR_MESSAGES.get(error['type'], error['msg'])
|
|
17
|
+
|
|
18
|
+
# Convert the field path into a nested dictionary structure
|
|
19
|
+
current = drf_errors
|
|
20
|
+
for i, key in enumerate(field_path[:-1]):
|
|
21
|
+
current = current.setdefault(str(key), {})
|
|
22
|
+
|
|
23
|
+
# Set the error message at the final location
|
|
24
|
+
final_key = str(field_path[-1])
|
|
25
|
+
if final_key in current:
|
|
26
|
+
if isinstance(current[final_key], list):
|
|
27
|
+
current[final_key].append(error_msg)
|
|
28
|
+
else:
|
|
29
|
+
current[final_key] = [current[final_key], error_msg]
|
|
30
|
+
else:
|
|
31
|
+
current[final_key] = [error_msg]
|
|
32
|
+
|
|
33
|
+
return drf_errors
|
synapse_sdk/utils/storage.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: synapse-sdk
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.0a8
|
|
4
4
|
Summary: synapse sdk
|
|
5
5
|
Author-email: datamaker <developer@datamaker.io>
|
|
6
6
|
License: MIT
|
|
@@ -17,6 +17,6 @@ Requires-Dist: python-dotenv
|
|
|
17
17
|
Requires-Dist: pyyaml
|
|
18
18
|
Requires-Dist: pydantic
|
|
19
19
|
Provides-Extra: all
|
|
20
|
-
Requires-Dist: ray[all]
|
|
20
|
+
Requires-Dist: ray[all]; extra == "all"
|
|
21
21
|
|
|
22
22
|
This is the SDK to develop synapse plugins
|
|
@@ -1,77 +1,97 @@
|
|
|
1
1
|
synapse_sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
synapse_sdk/loggers.py,sha256=
|
|
2
|
+
synapse_sdk/loggers.py,sha256=avoceBBu9VuSNS_CC3M5X8rWmAlk5xCTYEAVqxAXzBM,4008
|
|
3
3
|
synapse_sdk/cli/__init__.py,sha256=WmYGW1qZEXXIGJe3SGr8QjOStY4svuZKK1Lp_aPvtPs,140
|
|
4
4
|
synapse_sdk/cli/create_plugin.py,sha256=egbW_92WwxfHz50Gy4znX5Bf5fxDdQj3GFyd0l3Y3SY,228
|
|
5
5
|
synapse_sdk/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
synapse_sdk/clients/base.py,sha256=
|
|
6
|
+
synapse_sdk/clients/base.py,sha256=HfUJDP5FerRkiCJ0eaAZvs4F_kv73PtZ5FSnz_lKV0o,3069
|
|
7
7
|
synapse_sdk/clients/exceptions.py,sha256=ylv7x10eOp4aA3a48jwonnvqvkiYwzJYXjkVkRTAjwk,220
|
|
8
8
|
synapse_sdk/clients/utils.py,sha256=8pPJTdzHiRPSbZMoQYHAgR2BAMO6u_R_jMV6a2p34iQ,392
|
|
9
9
|
synapse_sdk/clients/agent/__init__.py,sha256=n4exZwc8gwuH6zqZUhstcD_sqIdm-ZoPvUcAxnCrnOQ,609
|
|
10
10
|
synapse_sdk/clients/agent/service.py,sha256=NnRu0XPVRqry6PWN_8-3iuzdXx20zO1lPXw-yVWQbdg,1433
|
|
11
11
|
synapse_sdk/clients/backend/__init__.py,sha256=850EjxNoGWXJpVZLRIaajrymBuW0MXiP3M3onRHDGbQ,800
|
|
12
|
-
synapse_sdk/clients/backend/annotation.py,sha256=
|
|
13
|
-
synapse_sdk/clients/backend/dataset.py,sha256=
|
|
14
|
-
synapse_sdk/clients/backend/integration.py,sha256=
|
|
15
|
-
synapse_sdk/clients/backend/ml.py,sha256=
|
|
12
|
+
synapse_sdk/clients/backend/annotation.py,sha256=eZc5EidgR_RfMGwvv1r1_mLkPdRd8e52c4zuuMjMX34,979
|
|
13
|
+
synapse_sdk/clients/backend/dataset.py,sha256=X8R71vff1gLytlEaOnKhBWjVQaZcIG_WYy32new4Vq0,1737
|
|
14
|
+
synapse_sdk/clients/backend/integration.py,sha256=wYfxRI2miZIwC1n7JoVRuSeq1cw5FkNIpKMxcMjj-b0,1628
|
|
15
|
+
synapse_sdk/clients/backend/ml.py,sha256=SwA4_noRCZ1dVIzyXfrs2zHuRlQZdZt17o1We5QOxl8,1053
|
|
16
16
|
synapse_sdk/plugins/__init__.py,sha256=9vsbYhxah4_ofTaG0x0qLFID_raHNkO57Y8A31Ws-lU,222
|
|
17
|
-
synapse_sdk/plugins/enums.py,sha256=
|
|
18
|
-
synapse_sdk/plugins/
|
|
17
|
+
synapse_sdk/plugins/enums.py,sha256=s59P6Oz2WAK9IX-kLVhNOvNKYJifKlWBhPpZbc9-ttE,486
|
|
18
|
+
synapse_sdk/plugins/exceptions.py,sha256=RFRz2SIHc4WmTd7sKZOMrQtD5nm4ldtb8CzG9VG65OE,167
|
|
19
|
+
synapse_sdk/plugins/models.py,sha256=pzzJl9zKL8v2XjBQC0UR-W9rG4Vyp95DzJ9MMG2W5L0,2835
|
|
19
20
|
synapse_sdk/plugins/upload.py,sha256=SSCHUR4HJ_mdLN7mUkk5UlXmL9028SKP6tpBS2rpf0A,3175
|
|
20
21
|
synapse_sdk/plugins/utils.py,sha256=n3s-zFnj4hrGWFtaBTJFbaupI8qUQL6S8_5YcbxOmeY,1482
|
|
21
22
|
synapse_sdk/plugins/categories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
synapse_sdk/plugins/categories/base.py,sha256=
|
|
23
|
+
synapse_sdk/plugins/categories/base.py,sha256=QBC96T0VIe-Lp63itjh0E13dgRriU7FT4_xZw7-7Zw8,7060
|
|
23
24
|
synapse_sdk/plugins/categories/decorators.py,sha256=Gw6T-UHwpCKrSt596X-g2sZbY_Z1zbbogowClj7Pr5Q,518
|
|
24
25
|
synapse_sdk/plugins/categories/registry.py,sha256=KdQR8SUlLT-3kgYzDNWawS1uJnAhrcw2j4zFaTpilRs,636
|
|
25
26
|
synapse_sdk/plugins/categories/templates.py,sha256=FF5FerhkZMeW1YcKLY5cylC0SkWSYdJODA_Qcm4OGYQ,887
|
|
26
27
|
synapse_sdk/plugins/categories/data_validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
28
|
synapse_sdk/plugins/categories/data_validation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
synapse_sdk/plugins/categories/data_validation/actions/validation.py,sha256=
|
|
29
|
+
synapse_sdk/plugins/categories/data_validation/actions/validation.py,sha256=U1lA36RyGmtRuF1AIpr1mE30z0cByCAC_PDKtEptDTc,338
|
|
30
|
+
synapse_sdk/plugins/categories/data_validation/templates/config.yaml,sha256=Hijb-b3hy0msZsTV_bbr3Hvlk8ok-Rk0a05mlLGTCAg,66
|
|
31
|
+
synapse_sdk/plugins/categories/data_validation/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
synapse_sdk/plugins/categories/data_validation/templates/plugin/validation.py,sha256=90I5boUpEXvO3mEuKKBs528ls2A4h8Iw4ReOID2h00Y,139
|
|
29
33
|
synapse_sdk/plugins/categories/export/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
34
|
synapse_sdk/plugins/categories/export/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
-
synapse_sdk/plugins/categories/export/actions/export.py,sha256=
|
|
35
|
+
synapse_sdk/plugins/categories/export/actions/export.py,sha256=GboGbFAUFPFqEedqO65L8IbX3AczrIFDoHbHBPaFCN0,320
|
|
32
36
|
synapse_sdk/plugins/categories/import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
37
|
synapse_sdk/plugins/categories/import/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
-
synapse_sdk/plugins/categories/import/actions/import.py,sha256=
|
|
38
|
+
synapse_sdk/plugins/categories/import/actions/import.py,sha256=URn6TOp081odMT5D4NlZ2XEcyKelJx8fxzdoKSkXSAI,320
|
|
35
39
|
synapse_sdk/plugins/categories/neural_net/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
40
|
synapse_sdk/plugins/categories/neural_net/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
-
synapse_sdk/plugins/categories/neural_net/actions/deployment.py,sha256=
|
|
38
|
-
synapse_sdk/plugins/categories/neural_net/actions/inference.py,sha256=
|
|
39
|
-
synapse_sdk/plugins/categories/neural_net/actions/test.py,sha256=
|
|
40
|
-
synapse_sdk/plugins/categories/neural_net/actions/train.py,sha256=
|
|
41
|
+
synapse_sdk/plugins/categories/neural_net/actions/deployment.py,sha256=U44sv_5UN2awfkbpyYPH9zOTEBhYn0FfcZwV7ywi-cA,827
|
|
42
|
+
synapse_sdk/plugins/categories/neural_net/actions/inference.py,sha256=qavUxayUDgN5E5Ht0x3cqWF0uPNkwUiZlCmfo574xHE,334
|
|
43
|
+
synapse_sdk/plugins/categories/neural_net/actions/test.py,sha256=JY25eg-Fo6WbgtMkGoo_qNqoaZkp3AQNEypJmeGzEog,320
|
|
44
|
+
synapse_sdk/plugins/categories/neural_net/actions/train.py,sha256=pE0RTruXqX1Jdp4iWDpsRH80V7TnvMnZnAlLOYkRusA,4463
|
|
41
45
|
synapse_sdk/plugins/categories/neural_net/templates/config.yaml,sha256=pvJFh_NHGZHHFfqrvZm6fHO5lsS7CudaIGboP6wbtY8,252
|
|
42
46
|
synapse_sdk/plugins/categories/neural_net/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
47
|
synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py,sha256=glYYdRybG3vRe48bYIxvue7bCFGPlEZmYWRoyBsLdZw,123
|
|
44
48
|
synapse_sdk/plugins/categories/neural_net/templates/plugin/test.py,sha256=kYyk7l4UtcDUAH4nkdVUGrHHHjxI4p1U13HSLnmGPyE,53
|
|
45
|
-
synapse_sdk/plugins/categories/neural_net/templates/plugin/train.py,sha256
|
|
49
|
+
synapse_sdk/plugins/categories/neural_net/templates/plugin/train.py,sha256=-QzWrfJGOk6EagQZmC1MMmiOEIr3X1sVGszMJjv5dFg,500
|
|
46
50
|
synapse_sdk/plugins/categories/post_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
51
|
synapse_sdk/plugins/categories/post_annotation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
|
-
synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py,sha256=
|
|
52
|
+
synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py,sha256=dkPqOPPMUoxn7h1e-momdhqezhTJ7wLf-Dyx04zKfjw,347
|
|
53
|
+
synapse_sdk/plugins/categories/post_annotation/templates/config.yaml,sha256=2g9S-eVnqteKY9E-GWtHZOengb4LdQ3Yt9hDb4S89HA,81
|
|
54
|
+
synapse_sdk/plugins/categories/post_annotation/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
|
+
synapse_sdk/plugins/categories/post_annotation/templates/plugin/post_annotation.py,sha256=GTsGq6zOZDWQSgP-XPr74qVWil480sYrLIBdk28ZMvQ,108
|
|
49
56
|
synapse_sdk/plugins/categories/pre_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
57
|
synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
|
-
synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py,sha256=
|
|
58
|
+
synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py,sha256=6ib3RmnGrjpsQ0e_G-mRH1lfFunQ3gh2M831vuDn7HU,344
|
|
59
|
+
synapse_sdk/plugins/categories/pre_annotation/templates/config.yaml,sha256=bUaibKbb-kai3QAHWbCYbO8nT-DQpV-KhuBszB7i-hI,78
|
|
60
|
+
synapse_sdk/plugins/categories/pre_annotation/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
+
synapse_sdk/plugins/categories/pre_annotation/templates/plugin/pre_annotation.py,sha256=HBHxHuv2gMBzDB2alFfrzI_SZ1Ztk6mo7eFbR5GqHKw,106
|
|
62
|
+
synapse_sdk/plugins/categories/smart_tool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
|
+
synapse_sdk/plugins/categories/smart_tool/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
|
+
synapse_sdk/plugins/categories/smart_tool/actions/auto_label.py,sha256=MZKpLsCGzO1FJsE32D7O3gC2rrTpYZKP1x0oE-Uu8Mc,699
|
|
65
|
+
synapse_sdk/plugins/categories/smart_tool/templates/config.yaml,sha256=lTixdat8b3LZi_JeiUZfAN5oM5iFnqLD5M-xR_xF7M4,145
|
|
66
|
+
synapse_sdk/plugins/categories/smart_tool/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
|
+
synapse_sdk/plugins/categories/smart_tool/templates/plugin/auto_label.py,sha256=eevNg0nOcYFR4z_L_R-sCvVOYoLWSAH1jwDkAf3YCjY,320
|
|
52
68
|
synapse_sdk/plugins/cli/__init__.py,sha256=8ogaOhN-RbDNYHqziW8nLsNUxKkZwGkHBdKxTahcm3U,334
|
|
53
69
|
synapse_sdk/plugins/cli/publish.py,sha256=ecX5vne2MuULon7JvH6NfiNcn7ccdv2SZUd9TakQzCI,1145
|
|
54
70
|
synapse_sdk/plugins/cli/run.py,sha256=lw1KbsL-xTGllF4NtD2cq-Rh6HMbhi-sO862_Ds-sUo,2330
|
|
55
71
|
synapse_sdk/plugins/templates/cookiecutter.json,sha256=NxOWk9A_v1pO0Ny4IYT9Cj5iiJ16--cIQrGC67QdR0I,396
|
|
56
72
|
synapse_sdk/plugins/templates/hooks/post_gen_project.py,sha256=jqlYkY1O2TxIR-Vh3gnwILYy8k-D39Xx66d2KNQVMCs,147
|
|
57
|
-
synapse_sdk/plugins/templates/hooks/pre_prompt.py,sha256=
|
|
73
|
+
synapse_sdk/plugins/templates/hooks/pre_prompt.py,sha256=aOAMM623s0sKFGjTZaotAOYFvsNMxeii4tPyhOAFKVE,539
|
|
58
74
|
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.env.dist,sha256=YlAG5YKwFEiwKm5NUbPsqvOJ9FJKoN0lbT3sxymBJpE,551
|
|
59
75
|
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.gitignore,sha256=RvBmUbwmzgv0vYzYk2aQ0HpvKyPj6sCpBqsrthCuA4s,243
|
|
60
76
|
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.pre-commit-config.yaml,sha256=p0yZwCUC8tYS1B0GPkjKiXYoRY9EZlq_ejFP98hB50g,154
|
|
61
77
|
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/README.md,sha256=ETBZv_2Ocgzn4Fe3o5Y842mZiz00ABuAalrXpNVnWU0,56
|
|
62
|
-
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml,sha256=
|
|
63
|
-
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml,sha256=
|
|
78
|
+
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml,sha256=CRfKjPJ6K2UlYbcHMSAYUGzn2TGmV7kDbZmKHwNuq3w,210
|
|
79
|
+
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml,sha256=Usgd80tHZAD1Ug5MAjPfETUZxtKKgZW-xovFEAEbQDo,317
|
|
64
80
|
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/requirements.txt,sha256=F5UwinpTLQFfyakFGTFxgBOo4H-EKD9d4e77WKOPHhk,17
|
|
65
81
|
synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
82
|
synapse_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
83
|
synapse_sdk/utils/debug.py,sha256=46sMFQLg_JSRUCymnT3wgszG1QsgrocRGiBjVX38r50,53
|
|
68
|
-
synapse_sdk/utils/file.py,sha256=
|
|
84
|
+
synapse_sdk/utils/file.py,sha256=nuU6POe0F6_WvIB26X9Q6dpcwgys8unt5Qv66n0Bmg4,2482
|
|
69
85
|
synapse_sdk/utils/module_loading.py,sha256=chHpU-BZjtYaTBD_q0T7LcKWtqKvYBS4L0lPlKkoMQ8,1020
|
|
70
|
-
synapse_sdk/utils/storage.py,sha256=
|
|
86
|
+
synapse_sdk/utils/storage.py,sha256=a8OVbd38ATr0El4G4kuV07lr_tJZrpIJBSy4GHb0qZ8,2581
|
|
71
87
|
synapse_sdk/utils/string.py,sha256=rEwuZ9SAaZLcQ8TYiwNKr1h2u4CfnrQx7SUL8NWmChg,216
|
|
72
|
-
synapse_sdk
|
|
73
|
-
synapse_sdk
|
|
74
|
-
synapse_sdk
|
|
75
|
-
synapse_sdk
|
|
76
|
-
synapse_sdk-1.0.
|
|
77
|
-
synapse_sdk-1.0.
|
|
88
|
+
synapse_sdk/utils/pydantic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
89
|
+
synapse_sdk/utils/pydantic/config.py,sha256=1vYOcUI35GslfD1rrqhFkNXXJOXt4IDqOPSx9VWGfNE,123
|
|
90
|
+
synapse_sdk/utils/pydantic/errors.py,sha256=0v0T12eQBr1KrFiEOBu6KMaPK4aPEGEC6etPJGoR5b4,1061
|
|
91
|
+
synapse_sdk/utils/pydantic/validators.py,sha256=G47P8ObPhsePmd_QZDK8EdPnik2CbaYzr_N4Z6En8dc,193
|
|
92
|
+
synapse_sdk-1.0.0a8.dist-info/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
|
|
93
|
+
synapse_sdk-1.0.0a8.dist-info/METADATA,sha256=-qf5IZO1tU5DNWmiT4BMVD_26XoKjF3KaFsAfceIRx8,567
|
|
94
|
+
synapse_sdk-1.0.0a8.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
95
|
+
synapse_sdk-1.0.0a8.dist-info/entry_points.txt,sha256=VNptJoGoNJI8yLXfBmhgUefMsmGI0m3-0YoMvrOgbxo,48
|
|
96
|
+
synapse_sdk-1.0.0a8.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
|
|
97
|
+
synapse_sdk-1.0.0a8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|