synapse-sdk 1.0.0a4__py3-none-any.whl → 1.0.0a5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of synapse-sdk might be problematic. Click here for more details.

Files changed (33) hide show
  1. synapse_sdk/cli/__init__.py +11 -0
  2. synapse_sdk/cli/create_plugin.py +10 -0
  3. synapse_sdk/plugins/categories/base.py +7 -17
  4. synapse_sdk/plugins/categories/neural_net/actions/deployment.py +2 -2
  5. synapse_sdk/plugins/categories/neural_net/templates/config.yaml +12 -0
  6. synapse_sdk/plugins/categories/neural_net/templates/plugin/__init__.py +0 -0
  7. synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py +4 -0
  8. synapse_sdk/plugins/categories/neural_net/templates/plugin/test.py +2 -0
  9. synapse_sdk/plugins/categories/neural_net/templates/plugin/train.py +14 -0
  10. synapse_sdk/plugins/categories/templates.py +32 -0
  11. synapse_sdk/plugins/cli/publish.py +4 -4
  12. synapse_sdk/plugins/cli/run.py +10 -7
  13. synapse_sdk/plugins/models.py +66 -0
  14. synapse_sdk/plugins/templates/cookiecutter.json +11 -0
  15. synapse_sdk/plugins/templates/hooks/post_gen_project.py +3 -0
  16. synapse_sdk/plugins/templates/hooks/pre_prompt.py +20 -0
  17. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.env.dist +24 -0
  18. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.gitignore +27 -0
  19. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.pre-commit-config.yaml +7 -0
  20. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/README.md +5 -0
  21. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/config.yaml +18 -0
  22. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/plugin/__init__.py +0 -0
  23. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml +13 -0
  24. synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/requirements.txt +1 -0
  25. synapse_sdk/plugins/upload.py +17 -11
  26. synapse_sdk/plugins/utils.py +13 -7
  27. {synapse_sdk-1.0.0a4.dist-info → synapse_sdk-1.0.0a5.dist-info}/METADATA +4 -2
  28. {synapse_sdk-1.0.0a4.dist-info → synapse_sdk-1.0.0a5.dist-info}/RECORD +32 -12
  29. synapse_sdk-1.0.0a5.dist-info/entry_points.txt +2 -0
  30. synapse_sdk/plugins/job.py +0 -5
  31. {synapse_sdk-1.0.0a4.dist-info → synapse_sdk-1.0.0a5.dist-info}/LICENSE +0 -0
  32. {synapse_sdk-1.0.0a4.dist-info → synapse_sdk-1.0.0a5.dist-info}/WHEEL +0 -0
  33. {synapse_sdk-1.0.0a4.dist-info → synapse_sdk-1.0.0a5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,11 @@
1
+ import click
2
+
3
+ from synapse_sdk.cli.create_plugin import create_plugin
4
+
5
+
6
+ @click.group()
7
+ def cli():
8
+ pass
9
+
10
+
11
+ cli.add_command(create_plugin)
@@ -0,0 +1,10 @@
1
+ from pathlib import Path
2
+
3
+ import click
4
+ from cookiecutter.main import cookiecutter
5
+
6
+
7
+ @click.command()
8
+ def create_plugin():
9
+ project_root = Path(__file__).parent.parent
10
+ cookiecutter(str(project_root / 'plugins/templates'))
@@ -11,10 +11,9 @@ from ray.dashboard.modules.job.sdk import JobSubmissionClient
11
11
  from synapse_sdk.clients.backend import BackendClient
12
12
  from synapse_sdk.loggers import ConsoleLogger, BackendLogger
13
13
  from synapse_sdk.plugins.enums import RunMethod
14
+ from synapse_sdk.plugins.models import PluginRelease
14
15
  from synapse_sdk.plugins.upload import build_and_upload, archive_and_upload, download_and_upload
15
- from synapse_sdk.plugins.utils import get_plugin_checksum
16
16
  from synapse_sdk.utils.module_loading import import_string
17
- from synapse_sdk.utils.storage import get_storage
18
17
 
19
18
 
20
19
  class Action:
@@ -23,6 +22,7 @@ class Action:
23
22
  method = None
24
23
  params = None
25
24
  plugin_config = None
25
+ plugin_release = None
26
26
  config = None
27
27
  client = None
28
28
  logger = None
@@ -42,23 +42,14 @@ class Action:
42
42
  def __init__(self, params, plugin_config, envs=None, job_id=None, direct=False, debug=False):
43
43
  self.params = params
44
44
  self.plugin_config = plugin_config
45
- self.config = plugin_config['actions'][self.name]
45
+ self.plugin_release = PluginRelease(config=plugin_config)
46
+ self.config = self.plugin_release.get_action_config(self.name)
46
47
  self.job_id = job_id
47
48
  self.direct = direct
48
49
  self.debug = debug
49
50
  self.envs = {**envs, **self.get_default_envs()} if envs else self.get_default_envs()
50
51
  self.set_logger()
51
52
 
52
- @cached_property
53
- def plugin_id(self):
54
- code = self.plugin_config['code']
55
- version = self.plugin_config['version']
56
- return f'{code}@{version}'
57
-
58
- @cached_property
59
- def plugin_checksum(self):
60
- return get_plugin_checksum(self.plugin_id)
61
-
62
53
  @cached_property
63
54
  def entrypoint(self):
64
55
  return import_string(self.config['entrypoint'])
@@ -79,8 +70,7 @@ class Action:
79
70
  plugin_url = archive_and_upload(plugin_path, self.plugin_storage_url)
80
71
  self.envs['SYNAPSE_DEBUG_PLUGIN_PATH'] = plugin_url
81
72
  return plugin_url
82
- storage = get_storage(self.plugin_storage_url)
83
- return storage.get_url(f'{self.plugin_checksum}.zip')
73
+ return self.plugin_release.get_url(self.plugin_storage_url)
84
74
 
85
75
  @property
86
76
  def debug_modules(self):
@@ -115,7 +105,7 @@ class Action:
115
105
  }
116
106
 
117
107
  if self.debug:
118
- runtime_env['pip'] += self.debug_modules
108
+ runtime_env['pip'] = self.debug_modules + runtime_env['pip']
119
109
 
120
110
  # 맨 마지막에 진행되어야 함
121
111
  runtime_env['env_vars'] = self.envs
@@ -183,7 +173,7 @@ class Action:
183
173
  path = self.params.pop('path', '')
184
174
  method = self.params.pop('method')
185
175
 
186
- url = os.path.join(self.envs['RAY_SERVE_ADDRESS'], self.plugin_checksum, path)
176
+ url = self.plugin_release.get_serve_url(self.envs['RAY_SERVE_ADDRESS'], path)
187
177
  response = getattr(requests, method)(url, **self.params)
188
178
  # TODO ok response가 아닌 경우 대응하기
189
179
  return response.json()
@@ -19,5 +19,5 @@ class DeploymentAction(Action):
19
19
 
20
20
  def run(self):
21
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}')
22
+ serve.delete(self.plugin_release.code)
23
+ serve.run(deployment.bind(), name=self.plugin_release.code, route_prefix=f'/{self.plugin_release.checksum}')
@@ -0,0 +1,12 @@
1
+ actions:
2
+ train:
3
+ dataset: datamaker
4
+ entrypoint: plugin.train.train
5
+ deployment:
6
+ entrypoint: plugin.inference.InferenceDeployment
7
+ inference:
8
+ method: restapi
9
+ endpoints:
10
+ - method: get
11
+ test:
12
+ entrypoint: plugin.test.test
@@ -0,0 +1,4 @@
1
+ class InferenceDeployment:
2
+ def __call__(self):
3
+ message = 'hello datamaker'
4
+ return {'message': message}
@@ -0,0 +1,2 @@
1
+ def test(run):
2
+ return 'this is neural net test!'
@@ -0,0 +1,14 @@
1
+ import time
2
+
3
+
4
+ def train(run, dataset, hyperparameter, checkpoint=None):
5
+ count_iterations = hyperparameter['iterations']
6
+
7
+ for i in range(1, count_iterations + 1):
8
+ time.sleep(0.5)
9
+ loss = float(round((count_iterations - i) / count_iterations, 2))
10
+ miou = 1 - loss
11
+ run.log_metric('iteration', i, loss=loss, miou=miou)
12
+ run.set_progress(i, count_iterations, category='iteration')
13
+
14
+ return {'weight': '/tmp/agent/test/a.txt', 'config': '/tmp/agent/test/b.txt'}
@@ -0,0 +1,32 @@
1
+ import shutil
2
+ from pathlib import Path
3
+
4
+ import yaml
5
+
6
+
7
+ def copy_project_category_template(category):
8
+ copy_plugin(category)
9
+ merge_config(category)
10
+
11
+
12
+ def copy_plugin(category):
13
+ template_path = Path(__file__).parent / category / 'templates' / 'plugin'
14
+ if not template_path.exists():
15
+ return
16
+
17
+ output_path = Path('plugin')
18
+ shutil.copytree(template_path, output_path, dirs_exist_ok=True)
19
+
20
+
21
+ def merge_config(category):
22
+ config_path = Path(__file__).parent / category / 'templates' / 'config.yaml'
23
+ if not config_path.exists():
24
+ return
25
+
26
+ config_base_path = Path('config.yaml')
27
+
28
+ config_base = yaml.safe_load(config_base_path.read_text(encoding='utf-8'))
29
+ config = yaml.safe_load(config_path.read_text(encoding='utf-8'))
30
+
31
+ config_base.update(config)
32
+ config_base_path.write_text(yaml.dump(config_base, sort_keys=False), encoding='utf-8')
@@ -4,8 +4,8 @@ from pathlib import Path
4
4
  import click
5
5
 
6
6
  from synapse_sdk.clients.backend import BackendClient
7
+ from synapse_sdk.plugins.models import PluginRelease
7
8
  from synapse_sdk.plugins.upload import archive
8
- from synapse_sdk.plugins.utils import read_config
9
9
 
10
10
 
11
11
  @click.command()
@@ -17,20 +17,20 @@ from synapse_sdk.plugins.utils import read_config
17
17
  def publish(ctx, host, user_token, tenant, debug_modules):
18
18
  debug = ctx.obj['DEBUG']
19
19
 
20
- config = read_config()
20
+ plugin_release = PluginRelease()
21
21
 
22
22
  source_path = Path('./')
23
23
  archive_path = source_path / 'dist' / 'archive.zip'
24
24
  archive(source_path, archive_path)
25
25
 
26
- data = {'plugin': config['code'], 'file': str(archive_path), 'debug': debug}
26
+ data = {'plugin': plugin_release.plugin, 'file': str(archive_path), 'debug': debug}
27
27
  if debug:
28
28
  data['debug_meta'] = json.dumps({'modules': debug_modules.split(',')})
29
29
 
30
30
  client = BackendClient(host, user_token, tenant=tenant)
31
31
  client.create_plugin_release(data)
32
32
  click.secho(
33
- f'Successfully published "{config["name"]}" ({config["code"]}@{config["version"]}) to synapse backend!',
33
+ f'Successfully published "{plugin_release.name}" ({plugin_release.code}) to synapse backend!',
34
34
  fg='green',
35
35
  bold=True,
36
36
  )
@@ -4,7 +4,8 @@ import click
4
4
 
5
5
  from synapse_sdk.clients.agent import AgentClient
6
6
  from synapse_sdk.clients.backend import BackendClient
7
- from synapse_sdk.plugins.utils import get_action, read_config
7
+ from synapse_sdk.plugins.models import PluginRelease
8
+ from synapse_sdk.plugins.utils import get_action
8
9
 
9
10
 
10
11
  @click.command()
@@ -41,7 +42,9 @@ def run_by_script(action, params, job_id, direct, debug):
41
42
 
42
43
  def run_by_agent(action, params, job_id, agent_host, agent_token, user_token, tenant, debug):
43
44
  client = AgentClient(agent_host, agent_token, user_token, tenant)
44
- data = {'action': action, 'params': params, 'job_id': job_id}
45
+ data = {'action': action, 'params': params}
46
+ if job_id:
47
+ data['job_id'] = job_id
45
48
  if debug:
46
49
  data.update({
47
50
  'plugin_path': os.getcwd(),
@@ -49,16 +52,16 @@ def run_by_agent(action, params, job_id, agent_host, agent_token, user_token, te
49
52
  })
50
53
  result = client.run_debug_plugin_release(data=data)
51
54
  else:
52
- config = read_config()
53
- result = client.run_plugin_release(code=f'{config["code"]}@{config["version"]}', data=data)
55
+ plugin_release = PluginRelease()
56
+ result = client.run_plugin_release(code=plugin_release.code, data=data)
54
57
 
55
58
  click.echo(result)
56
59
 
57
60
 
58
61
  def run_by_backend(action, params, agent, host, user_token, tenant):
59
62
  client = BackendClient(host, user_token, tenant=tenant)
60
- config = read_config()
61
- data = {'agent': agent, 'version': config['version'], 'action': action, 'params': params}
62
- result = client.run_plugin(config['code'], data=data)
63
+ plugin_release = PluginRelease()
64
+ data = {'agent': agent, 'version': plugin_release.version, 'action': action, 'params': params}
65
+ result = client.run_plugin(plugin_release.plugin, data=data)
63
66
 
64
67
  click.echo(result)
@@ -0,0 +1,66 @@
1
+ import os
2
+ from functools import cached_property
3
+ from typing import Dict, Any
4
+
5
+ from synapse_sdk.plugins.utils import read_plugin_config
6
+ from synapse_sdk.utils.storage import get_storage
7
+ from synapse_sdk.utils.string import hash_text
8
+
9
+
10
+ class PluginRelease:
11
+ config: Dict[str, Any]
12
+
13
+ def __init__(self, config=None, plugin_path=None):
14
+ if config:
15
+ self.config = config
16
+ else:
17
+ self.config = read_plugin_config(plugin_path=plugin_path)
18
+
19
+ @cached_property
20
+ def plugin(self):
21
+ return self.config['code']
22
+
23
+ @cached_property
24
+ def version(self):
25
+ return self.config['version']
26
+
27
+ @cached_property
28
+ def code(self):
29
+ return f'{self.plugin}@{self.version}'
30
+
31
+ @cached_property
32
+ def category(self):
33
+ return self.config['category']
34
+
35
+ @cached_property
36
+ def name(self):
37
+ return self.config['name']
38
+
39
+ @cached_property
40
+ def checksum(self):
41
+ return hash_text(self.code)
42
+
43
+ @cached_property
44
+ def actions(self):
45
+ return list(self.config['actions'].keys())
46
+
47
+ def setup_runtime_env(self):
48
+ # TODO ray에 해당 plugin release runtime env 캐싱
49
+ pass
50
+
51
+ def get_action_config(self, action):
52
+ return self.config['actions'][action]
53
+
54
+ def get_url(self, storage_url):
55
+ storage = get_storage(storage_url)
56
+ return storage.get_url(f'{self.checksum}.zip')
57
+
58
+ def get_serve_url(self, serve_address, path):
59
+ return os.path.join(serve_address, self.checksum, path)
60
+
61
+
62
+ class Job:
63
+ job_id = None
64
+
65
+ def __init__(self, job_id):
66
+ self.job_id = job_id
@@ -0,0 +1,11 @@
1
+ {
2
+ "category": null,
3
+ "plugin_name": null,
4
+ "plugin_code": "{{ cookiecutter.plugin_name.lower().replace(' ', '-') }}",
5
+ "version": "0.1.0",
6
+ "description": "This is {{ cookiecutter.plugin_name }} plugin",
7
+ "__prompts__": {
8
+ "project_name": "Plugin name",
9
+ "project_slug": "Unique identifier of your plugin. Lowercase letters, numbers, and hyphens only (e.g., 'my-plugin-name')"
10
+ }
11
+ }
@@ -0,0 +1,3 @@
1
+ from synapse_sdk.plugins.categories.templates import copy_project_category_template
2
+
3
+ copy_project_category_template('{{ cookiecutter.category }}')
@@ -0,0 +1,20 @@
1
+ import json
2
+ from pathlib import Path
3
+ from synapse_sdk.plugins.utils import get_plugin_categories
4
+ from synapse_sdk.utils.file import get_dict_from_file
5
+
6
+
7
+ def update_config(config):
8
+ config['category'] = get_plugin_categories()
9
+ return config
10
+
11
+
12
+ def main():
13
+ cookiecutter_path = Path('cookiecutter.json')
14
+ config = get_dict_from_file(cookiecutter_path)
15
+ config = update_config(config)
16
+ cookiecutter_path.write_text(json.dumps(config, indent=4, ensure_ascii=False), encoding='utf-8')
17
+
18
+
19
+ if __name__ == '__main__':
20
+ main()
@@ -0,0 +1,24 @@
1
+ # RAY 관련
2
+ RAY_ADDRESS=
3
+ RAY_DASHBOARD_ADDRESS=
4
+ RAY_SERVE_ADDRESS=
5
+
6
+ # 플러그인 관련
7
+ SYNAPSE_PLUGIN_STORAGE=
8
+
9
+ # 플러그인 디버그 관련
10
+ SYNAPSE_DEBUG_PLUGIN_PATH=
11
+ SYNAPSE_DEBUG_MODULES=
12
+
13
+ # 플러그인 PUBLISH 관련
14
+ SYNAPSE_PLUGIN_PUBLISH_HOST=https://synapse.datamaker.io
15
+ SYNAPSE_PLUGIN_PUBLISH_USER_TOKEN=
16
+ SYNAPSE_PLUGIN_PUBLISH_TENANT=
17
+
18
+ # 플러그인 RUN 관련
19
+ SYNAPSE_PLUGIN_RUN_HOST=
20
+ SYNAPSE_PLUGIN_RUN_AGENT=
21
+ SYNAPSE_PLUGIN_RUN_AGENT_HOST=
22
+ SYNAPSE_PLUGIN_RUN_AGENT_TOKEN=
23
+ SYNAPSE_PLUGIN_RUN_USER_TOKEN=
24
+ SYNAPSE_PLUGIN_RUN_TENANT=
@@ -0,0 +1,27 @@
1
+ ### Example user template template
2
+ # virtualenv
3
+ .venv
4
+
5
+ # idea
6
+ .DS_Store
7
+ *.pyc
8
+ .idea
9
+ *.iml
10
+
11
+ # http
12
+ /http/
13
+
14
+ # general things to ignore
15
+ build/
16
+ dist/
17
+ *.egg-info/
18
+ *.egg
19
+ *.py[cod]
20
+ __pycache__/
21
+ *.so
22
+ *~
23
+ .env
24
+
25
+ # due to using tox and pytest
26
+ .tox
27
+ .cache
@@ -0,0 +1,7 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.7.1
4
+ hooks:
5
+ - id: ruff
6
+ args: [ --fix ]
7
+ - id: ruff-format
@@ -0,0 +1,5 @@
1
+ # 실행방법
2
+
3
+ ```bash
4
+ $ python main.py run --help
5
+ ```
@@ -0,0 +1,18 @@
1
+ name: {{ cookiecutter.plugin_name }}
2
+ code: {{ cookiecutter.plugin_code }}
3
+ version: {{ cookiecutter.version }}
4
+ readme: README.md
5
+ description: {{ cookiecutter.description }}
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
@@ -0,0 +1,13 @@
1
+ [tool.ruff]
2
+ line-length = 120
3
+
4
+ [tool.ruff.lint]
5
+ select = ['E', 'F', 'Q']
6
+ ignore = ['W191', 'E111', 'E114', 'E117', 'D206', 'D300', 'Q000', 'Q001', 'Q002', 'Q003', 'COM812', 'COM819', 'ISC001', 'ISC002']
7
+
8
+ [tool.ruff.lint.pydocstyle]
9
+ convention = 'google'
10
+
11
+ [tool.ruff.format]
12
+ quote-style = 'single'
13
+ preview = true
@@ -1,4 +1,3 @@
1
- import re
2
1
  import subprocess
3
2
  import tempfile
4
3
  from pathlib import Path
@@ -17,9 +16,9 @@ def download_and_upload(source_url, url):
17
16
  storage = get_storage(url)
18
17
  with tempfile.TemporaryDirectory() as temp_path:
19
18
  file_path = str(download_file(source_url, temp_path))
20
- checksum = calculate_checksum(file_path, prefix='dev')
19
+ checksum = calculate_checksum(file_path)
21
20
  # TODO 중복 체크
22
- return storage.upload(file_path, f'{checksum}.zip')
21
+ return storage.upload(file_path, f'dev-{checksum}.zip')
23
22
 
24
23
 
25
24
  def archive_and_upload(source_path, url):
@@ -28,8 +27,8 @@ def archive_and_upload(source_path, url):
28
27
  archive_path = dist_path / 'archive.zip'
29
28
 
30
29
  archive(source_path, archive_path)
31
- checksum = calculate_checksum(archive_path, prefix='dev')
32
- checksum_archive_path = dist_path / f'{checksum}.zip'
30
+ checksum = calculate_checksum(archive_path)
31
+ checksum_archive_path = dist_path / f'dev-{checksum}.zip'
33
32
 
34
33
  if checksum_archive_path.exists():
35
34
  # TODO 실제 스토리지 있는지 확인
@@ -48,8 +47,8 @@ def build_and_upload(source_path, url, virtualenv_path='.venv'):
48
47
  archive_path = dist_path / 'archive.zip'
49
48
 
50
49
  archive(source_path, archive_path)
51
- checksum = calculate_checksum(archive_path, prefix='dev')
52
- checksum_archive_path = dist_path / f'{checksum}.zip'
50
+ checksum = calculate_checksum(archive_path)
51
+ checksum_archive_path = dist_path / f'dev-{checksum}.zip'
53
52
 
54
53
  if checksum_archive_path.exists():
55
54
  # TODO 실제 스토리지 있는지 확인
@@ -70,13 +69,20 @@ def build_and_upload(source_path, url, virtualenv_path='.venv'):
70
69
  )
71
70
  wheel_path = next(dist_path.glob('*.whl'), None)
72
71
 
72
+ # whl 파일 버전이 동일한 이슈를 해결하기 위해 checksum으로 build명 변경
73
+ checksum_wheel_path = wheel_path.with_name(change_build_from_whl_name(wheel_path.name, checksum))
74
+ wheel_path.rename(checksum_wheel_path)
75
+
73
76
  archive_path.rename(checksum_archive_path)
77
+
74
78
  for file_path in dist_path.glob('*.zip'):
75
79
  if file_path.name != checksum_archive_path.name:
76
80
  file_path.unlink()
77
- return storage.upload(str(wheel_path), wheel_path.name)
81
+ return storage.upload(str(checksum_wheel_path), checksum_wheel_path.name)
78
82
 
79
83
 
80
- def change_whl_version(whl_name, new_version):
81
- pattern = r'^(?P<distribution>.+?)-(?P<version>[\d\.\w]+(\+[\w\.]+)?)(?P<rest>-.+\.whl)$'
82
- return re.sub(pattern, rf'\g<distribution>-{new_version}\g<rest>', whl_name)
84
+ def change_build_from_whl_name(whl_name, build):
85
+ components = whl_name.split('-')
86
+ version = components[1].split('+')[0]
87
+ components[1] = f'{version}+{build}'
88
+ return '-'.join(components)
@@ -1,8 +1,8 @@
1
1
  import json
2
+ from pathlib import Path
2
3
 
3
4
  from synapse_sdk.plugins.categories.registry import _REGISTERED_ACTIONS, register_actions
4
5
  from synapse_sdk.utils.file import get_dict_from_file
5
- from synapse_sdk.utils.string import hash_text
6
6
 
7
7
 
8
8
  def get_action(action, params_data, *args, **kwargs):
@@ -17,11 +17,11 @@ def get_action(action, params_data, *args, **kwargs):
17
17
  config_data = kwargs.pop('config', False)
18
18
  if config_data:
19
19
  if isinstance(config_data, str):
20
- config = get_dict_from_file(config_data)
20
+ config = read_plugin_config(plugin_path=config_data)
21
21
  else:
22
22
  config = config_data
23
23
  else:
24
- config = read_config()
24
+ config = read_plugin_config()
25
25
  category = config['category']
26
26
  return get_action_class(category, action)(params, config, *args, **kwargs)
27
27
 
@@ -36,9 +36,15 @@ def get_available_actions(category):
36
36
  return list(_REGISTERED_ACTIONS[category].keys())
37
37
 
38
38
 
39
- def get_plugin_checksum(plugin_id):
40
- return hash_text(plugin_id)
39
+ def get_plugin_categories():
40
+ register_actions()
41
+ return list(_REGISTERED_ACTIONS.keys())
41
42
 
42
43
 
43
- def read_config():
44
- return get_dict_from_file('config.yaml')
44
+ def read_plugin_config(plugin_path=None):
45
+ config_file_name = 'config.yaml'
46
+ if plugin_path:
47
+ config_path = Path(plugin_path) / config_file_name
48
+ else:
49
+ config_path = config_file_name
50
+ return get_dict_from_file(config_path)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: synapse-sdk
3
- Version: 1.0.0a4
3
+ Version: 1.0.0a5
4
4
  Summary: synapse sdk
5
5
  Author-email: datamaker <developer@datamaker.io>
6
6
  License: MIT
@@ -10,11 +10,13 @@ Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: boto3
12
12
  Requires-Dist: click
13
+ Requires-Dist: cookiecutter
13
14
  Requires-Dist: requests
14
15
  Requires-Dist: tqdm
15
16
  Requires-Dist: python-dotenv
16
17
  Requires-Dist: pyyaml
17
18
  Requires-Dist: pydantic
18
- Requires-Dist: ray[all]
19
+ Provides-Extra: all
20
+ Requires-Dist: ray[all] ; extra == 'all'
19
21
 
20
22
  This is the SDK to develop synapse plugins
@@ -1,5 +1,7 @@
1
1
  synapse_sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  synapse_sdk/loggers.py,sha256=7wB18EZ092YQayNgXN_8JzS3vi0BjV5Xu0o2aTkcfNA,1468
3
+ synapse_sdk/cli/__init__.py,sha256=WmYGW1qZEXXIGJe3SGr8QjOStY4svuZKK1Lp_aPvtPs,140
4
+ synapse_sdk/cli/create_plugin.py,sha256=egbW_92WwxfHz50Gy4znX5Bf5fxDdQj3GFyd0l3Y3SY,228
3
5
  synapse_sdk/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
6
  synapse_sdk/clients/base.py,sha256=IuZY9-me62lPRgmMjXPhqy8cVLbtVSyT9acj19KMQkU,2788
5
7
  synapse_sdk/clients/exceptions.py,sha256=ylv7x10eOp4aA3a48jwonnvqvkiYwzJYXjkVkRTAjwk,220
@@ -13,13 +15,14 @@ synapse_sdk/clients/backend/integration.py,sha256=jrymq6kyoM1CwWJuh8BcJAXoVFaY5c
13
15
  synapse_sdk/clients/backend/ml.py,sha256=l4rGLBZgLUYQOBePvWAoNyz-yZgJuhC-1KCFeZOYDuQ,1012
14
16
  synapse_sdk/plugins/__init__.py,sha256=9vsbYhxah4_ofTaG0x0qLFID_raHNkO57Y8A31Ws-lU,222
15
17
  synapse_sdk/plugins/enums.py,sha256=lQZqO2bEeBKdk6q-SMjfOLDlgxv7BuIPk3fXeUFfHRs,327
16
- synapse_sdk/plugins/job.py,sha256=UzFKA8o_F6RzY_PwyI4dlF3kSfmMG0xEYIyKLfdqSP8,91
17
- synapse_sdk/plugins/upload.py,sha256=9DF-f0Or6ea4mJxuCmPlpYOG4EGeGqIRALc4ulrnQd4,2973
18
- synapse_sdk/plugins/utils.py,sha256=RFxFtmjj-uBK03wUwLhtUecfn_IOKRJupudmsguc2Sc,1212
18
+ synapse_sdk/plugins/models.py,sha256=LmhJCWfyBeTDFgw-qwkQAwRRW_zsPOHOZdhI5c8jomE,1606
19
+ synapse_sdk/plugins/upload.py,sha256=SSCHUR4HJ_mdLN7mUkk5UlXmL9028SKP6tpBS2rpf0A,3175
20
+ synapse_sdk/plugins/utils.py,sha256=atfm28tPdWrTLFX5X69xu42ld30Wh_QkwD8K0NH9sZs,1423
19
21
  synapse_sdk/plugins/categories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- synapse_sdk/plugins/categories/base.py,sha256=PxA8xfy46rT_zvlI1WZjuRsxqa2Mx6TtKVXyolNqjfk,6831
22
+ synapse_sdk/plugins/categories/base.py,sha256=mf1duSt1Kt3FrgbXVlps64D1-OmkQx_HI1Z8HKkoA1E,6575
21
23
  synapse_sdk/plugins/categories/decorators.py,sha256=Gw6T-UHwpCKrSt596X-g2sZbY_Z1zbbogowClj7Pr5Q,518
22
24
  synapse_sdk/plugins/categories/registry.py,sha256=KdQR8SUlLT-3kgYzDNWawS1uJnAhrcw2j4zFaTpilRs,636
25
+ synapse_sdk/plugins/categories/templates.py,sha256=FF5FerhkZMeW1YcKLY5cylC0SkWSYdJODA_Qcm4OGYQ,887
23
26
  synapse_sdk/plugins/categories/data_validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
27
  synapse_sdk/plugins/categories/data_validation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
28
  synapse_sdk/plugins/categories/data_validation/actions/validation.py,sha256=NbEGFytxjakawglZR_Sf9UAjQyuzRxpdwEI1GDbEBW0,338
@@ -31,10 +34,15 @@ synapse_sdk/plugins/categories/import/actions/__init__.py,sha256=47DEQpj8HBSa-_T
31
34
  synapse_sdk/plugins/categories/import/actions/import.py,sha256=bkB8x-x7jJfcCnzbz5bOJJy7mPhTKYfIWUdmCoHvpdM,320
32
35
  synapse_sdk/plugins/categories/neural_net/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
36
  synapse_sdk/plugins/categories/neural_net/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- synapse_sdk/plugins/categories/neural_net/actions/deployment.py,sha256=afqgD_mzErcWdW3xdbrKIOL13fUPO0biZk8_l4l2j84,767
37
+ synapse_sdk/plugins/categories/neural_net/actions/deployment.py,sha256=CXdsZcaxvFq0EcTT8w3Z6Ki7Qs4hXPL7Jv-ipXvXKCU,795
35
38
  synapse_sdk/plugins/categories/neural_net/actions/inference.py,sha256=erM2z7aUTwyzJZqWBlxhTP8dm8cOraI_vUYAqcXkdSY,334
36
39
  synapse_sdk/plugins/categories/neural_net/actions/test.py,sha256=dAW1zfodlUhoL-sD17tG-CQT0RBxIcHWJ8f1eeZ00M4,321
37
40
  synapse_sdk/plugins/categories/neural_net/actions/train.py,sha256=ASbqY7ZB0-bVrEOH1uvOkhrYKNt7ZC1aIbPZPfKXZGc,994
41
+ synapse_sdk/plugins/categories/neural_net/templates/config.yaml,sha256=pvJFh_NHGZHHFfqrvZm6fHO5lsS7CudaIGboP6wbtY8,252
42
+ synapse_sdk/plugins/categories/neural_net/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
+ synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py,sha256=glYYdRybG3vRe48bYIxvue7bCFGPlEZmYWRoyBsLdZw,123
44
+ 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=gtbUe6oVBNV7f_ZXQZ92rWnqRGw_rIUwNabQdgahF6w,504
38
46
  synapse_sdk/plugins/categories/post_annotation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
47
  synapse_sdk/plugins/categories/post_annotation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
48
  synapse_sdk/plugins/categories/post_annotation/actions/post_annotation.py,sha256=1tutwNDHpnrCPHzMTsMEk29WPajnZikjBE83j7Z-Xt0,347
@@ -42,16 +50,28 @@ synapse_sdk/plugins/categories/pre_annotation/__init__.py,sha256=47DEQpj8HBSa-_T
42
50
  synapse_sdk/plugins/categories/pre_annotation/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
51
  synapse_sdk/plugins/categories/pre_annotation/actions/pre_annotation.py,sha256=YYQt9HsgXlBclE4Sn0c7p1zqCxWHkIHAwyA-tbqrmPQ,344
44
52
  synapse_sdk/plugins/cli/__init__.py,sha256=8ogaOhN-RbDNYHqziW8nLsNUxKkZwGkHBdKxTahcm3U,334
45
- synapse_sdk/plugins/cli/publish.py,sha256=v9aMMMyZgftSLW63uO9ZKeGBJEBeVCfOSmsSrfpKOP4,1135
46
- synapse_sdk/plugins/cli/run.py,sha256=2_iwDCGbPNMCsEWzbeZIo4EGW-cssp3UVZNfkq6ZbHo,2249
53
+ synapse_sdk/plugins/cli/publish.py,sha256=ecX5vne2MuULon7JvH6NfiNcn7ccdv2SZUd9TakQzCI,1145
54
+ synapse_sdk/plugins/cli/run.py,sha256=lw1KbsL-xTGllF4NtD2cq-Rh6HMbhi-sO862_Ds-sUo,2330
55
+ synapse_sdk/plugins/templates/cookiecutter.json,sha256=NxOWk9A_v1pO0Ny4IYT9Cj5iiJ16--cIQrGC67QdR0I,396
56
+ synapse_sdk/plugins/templates/hooks/post_gen_project.py,sha256=jqlYkY1O2TxIR-Vh3gnwILYy8k-D39Xx66d2KNQVMCs,147
57
+ synapse_sdk/plugins/templates/hooks/pre_prompt.py,sha256=YXhPmobVr8WKv-acgYST7Qu_qXmrUYhxiHrnAUO38xs,538
58
+ synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.env.dist,sha256=YlAG5YKwFEiwKm5NUbPsqvOJ9FJKoN0lbT3sxymBJpE,551
59
+ synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.gitignore,sha256=RvBmUbwmzgv0vYzYk2aQ0HpvKyPj6sCpBqsrthCuA4s,243
60
+ synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/.pre-commit-config.yaml,sha256=p0yZwCUC8tYS1B0GPkjKiXYoRY9EZlq_ejFP98hB50g,154
61
+ 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=3Sv59w4vAgFasJEn5z7WNborTVlotrqOOVnCLEEz5JI,459
63
+ synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/pyproject.toml,sha256=HHfEE_HquaTlBPCOTQkNXphVtc3QLtU_kCEqKv6C6e8,312
64
+ synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/requirements.txt,sha256=Yu6Si7Sgpq5k3glDxViT4PsS79Ssi-ZxEZPOIjfe0xI,12
65
+ synapse_sdk/plugins/templates/synapse-{{cookiecutter.plugin_code}}-plugin/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
66
  synapse_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
67
  synapse_sdk/utils/debug.py,sha256=46sMFQLg_JSRUCymnT3wgszG1QsgrocRGiBjVX38r50,53
49
68
  synapse_sdk/utils/file.py,sha256=Iptk_DCPsmJzqAABCD3vC6z1yG74fKb5x81LnUCZzYo,1916
50
69
  synapse_sdk/utils/module_loading.py,sha256=chHpU-BZjtYaTBD_q0T7LcKWtqKvYBS4L0lPlKkoMQ8,1020
51
70
  synapse_sdk/utils/storage.py,sha256=U3TScqQNgHQ89s0kUqQ8hm3npQAznIyRqzWDKR0YA3E,2581
52
71
  synapse_sdk/utils/string.py,sha256=rEwuZ9SAaZLcQ8TYiwNKr1h2u4CfnrQx7SUL8NWmChg,216
53
- synapse_sdk-1.0.0a4.dist-info/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
54
- synapse_sdk-1.0.0a4.dist-info/METADATA,sha256=FLSpO1BrMxmZiNZlHykgljphv6bpNFCNvSSgbjd1CU4,503
55
- synapse_sdk-1.0.0a4.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
56
- synapse_sdk-1.0.0a4.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
57
- synapse_sdk-1.0.0a4.dist-info/RECORD,,
72
+ synapse_sdk-1.0.0a5.dist-info/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
73
+ synapse_sdk-1.0.0a5.dist-info/METADATA,sha256=FrXnCT7BzuNKZDboXK_4sNyy4wsjMLqSL8gKkg8UEU0,568
74
+ synapse_sdk-1.0.0a5.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
75
+ synapse_sdk-1.0.0a5.dist-info/entry_points.txt,sha256=VNptJoGoNJI8yLXfBmhgUefMsmGI0m3-0YoMvrOgbxo,48
76
+ synapse_sdk-1.0.0a5.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
77
+ synapse_sdk-1.0.0a5.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ synapse = synapse_sdk.cli:cli
@@ -1,5 +0,0 @@
1
- class Job:
2
- job_id = None
3
-
4
- def __init__(self, job_id):
5
- self.job_id = job_id