synapse-sdk 1.0.0a15__py3-none-any.whl → 1.0.0a17__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.

@@ -9,9 +9,7 @@ class MLClientMixin(BaseClient):
9
9
 
10
10
  def get_model(self, pk, params=None, url_conversion=None):
11
11
  path = f'models/{pk}/'
12
- url_conversion = get_default_url_conversion(
13
- url_conversion, files_fields=['files', 'parent.files'], is_list=False
14
- )
12
+ url_conversion = get_default_url_conversion(url_conversion, files_fields=['file'], is_list=False)
15
13
  return self._get(path, params=params, url_conversion=url_conversion)
16
14
 
17
15
  def create_model(self, data):
@@ -62,7 +62,7 @@ class BaseClient:
62
62
  response = self._request('get', path, **kwargs)
63
63
  if url_conversion:
64
64
  if url_conversion['is_list']:
65
- files_url_to_path_from_objs(response['results'], **url_conversion)
65
+ files_url_to_path_from_objs(response['results'], **url_conversion, is_async=True)
66
66
  else:
67
67
  files_url_to_path_from_objs(response, **url_conversion)
68
68
  return response
@@ -80,14 +80,14 @@ class BaseClient:
80
80
  return self._request('delete', path, **kwargs)
81
81
 
82
82
  def _list(self, path, url_conversion=None, list_all=False, **kwargs):
83
- response = self._get(path, url_conversion, **kwargs)
83
+ response = self._get(path, **kwargs)
84
84
  if list_all:
85
85
  return self._list_all(path, url_conversion, **kwargs), response['count']
86
86
  else:
87
87
  return response
88
88
 
89
- def _list_all(self, path, url_conversion=None, **kwargs):
90
- response = self._get(path, url_conversion, **kwargs)
89
+ def _list_all(self, path, url_conversion=None, params=None, **kwargs):
90
+ response = self._get(path, url_conversion, params=params, **kwargs)
91
91
  yield from response['results']
92
92
  if response['next']:
93
93
  yield from self._list_all(response['next'], url_conversion, **kwargs)
@@ -92,13 +92,15 @@ class Action:
92
92
  @property
93
93
  def debug_modules(self):
94
94
  debug_modules = []
95
- for module_path in self.envs.get('SYNAPSE_DEBUG_MODULES', '').split(','):
96
- if module_path.startswith('https://'): # TODO ray에서 지원하는 remote uri 형식 (https, s3, gs) 모두 지원
97
- module_url = module_path
98
- else:
99
- module_url = build_and_upload(module_path, self.plugin_storage_url)
100
- debug_modules.append(module_url)
101
- self.envs['SYNAPSE_DEBUG_MODULES'] = ','.join(debug_modules)
95
+ if self.envs.get('SYNAPSE_DEBUG_MODULES'):
96
+ for module_path in self.envs['SYNAPSE_DEBUG_MODULES'].split(','):
97
+ # TODO ray에서 지원하는 remote uri 형식 (https, s3, gs) 모두 지원
98
+ if module_path.startswith('https://'):
99
+ module_url = module_path
100
+ else:
101
+ module_url = build_and_upload(module_path, self.plugin_storage_url)
102
+ debug_modules.append(module_url)
103
+ self.envs['SYNAPSE_DEBUG_MODULES'] = ','.join(debug_modules)
102
104
  return debug_modules
103
105
 
104
106
  def get_run(self):
@@ -12,7 +12,7 @@ from synapse_sdk.plugins.categories.base import Action
12
12
  from synapse_sdk.plugins.categories.decorators import register_action
13
13
  from synapse_sdk.plugins.enums import PluginCategory, RunMethod
14
14
  from synapse_sdk.plugins.models import Run
15
- from synapse_sdk.utils.file import archive
15
+ from synapse_sdk.utils.file import archive, get_temp_path, unarchive
16
16
  from synapse_sdk.utils.pydantic.validators import non_blank
17
17
 
18
18
 
@@ -83,10 +83,15 @@ class TrainAction(Action):
83
83
  self.run.log_message('Preparing dataset for training.')
84
84
  input_dataset = self.get_dataset()
85
85
 
86
+ # retrieve checkpoint
87
+ checkpoint = None
88
+ if self.params['checkpoint']:
89
+ self.run.log_message('Retrieving checkpoint.')
90
+ checkpoint = self.get_model(self.params['checkpoint'])
91
+
86
92
  # train dataset
87
93
  self.run.log_message('Starting model training.')
88
-
89
- result = self.entrypoint(self.run, input_dataset, hyperparameter)
94
+ result = self.entrypoint(self.run, input_dataset, hyperparameter, checkpoint=checkpoint)
90
95
 
91
96
  # upload model_data
92
97
  self.run.log_message('Registering model data.')
@@ -106,6 +111,7 @@ class TrainAction(Action):
106
111
  ground_truths, count_dataset = client.list_ground_truth_events(
107
112
  params={
108
113
  'fields': ['category', 'files', 'data'],
114
+ 'expand': ['data'],
109
115
  'ground_truth_dataset_versions': self.params['dataset'],
110
116
  },
111
117
  list_all=True,
@@ -120,11 +126,16 @@ class TrainAction(Action):
120
126
 
121
127
  return input_dataset
122
128
 
123
- def create_model(self, path):
124
- if not self.client:
125
- print(path)
126
- return None
129
+ def get_model(self, model_id):
130
+ model = self.client.get_model(model_id)
131
+ model_file = Path(model['file'])
132
+ output_path = get_temp_path(f'models/{model_file.stem}')
133
+ if not output_path.exists():
134
+ unarchive(model_file, output_path)
135
+ model['path'] = output_path
136
+ return model
127
137
 
138
+ def create_model(self, path):
128
139
  params = copy.deepcopy(self.params)
129
140
  configuration_fields = ['hyperparameter']
130
141
  configuration = {field: params.pop(field) for field in configuration_fields}
@@ -26,8 +26,8 @@ def publish(ctx, host, user_token, tenant, debug_modules):
26
26
 
27
27
  data = {'plugin': plugin_release.plugin, 'file': str(archive_path), 'debug': debug}
28
28
  if debug:
29
- if debug_modules:
30
- data['debug_meta'] = json.dumps({'modules': debug_modules.split(',')})
29
+ modules = debug_modules.split(',') if debug_modules else []
30
+ data['debug_meta'] = json.dumps({'modules': modules})
31
31
 
32
32
  client = BackendClient(host, user_token, tenant=tenant)
33
33
  client.create_plugin_release(data)
synapse_sdk/utils/file.py CHANGED
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import hashlib
2
3
  import json
3
4
  import operator
@@ -6,6 +7,7 @@ from functools import reduce
6
7
  from pathlib import Path
7
8
  from urllib.parse import urlparse
8
9
 
10
+ import aiohttp
9
11
  import requests
10
12
  import yaml
11
13
 
@@ -28,28 +30,85 @@ def download_file(url, path_download, name=None, coerce=None):
28
30
  return path
29
31
 
30
32
 
31
- def files_url_to_path(files, coerce=None):
33
+ def files_url_to_path(files, coerce=None, file_field=None):
32
34
  path_download = Path('/tmp/datamaker') / 'media'
33
35
  path_download.mkdir(parents=True, exist_ok=True)
36
+ if file_field:
37
+ files[file_field] = download_file(files[file_field], path_download, coerce=coerce)
38
+ else:
39
+ for file_name in files:
40
+ if isinstance(files[file_name], str):
41
+ files[file_name] = download_file(files[file_name], path_download, coerce=coerce)
42
+ else:
43
+ files[file_name]['path'] = download_file(files[file_name].pop('url'), path_download, coerce=coerce)
44
+
45
+
46
+ def files_url_to_path_from_objs(objs, files_fields, coerce=None, is_list=False, is_async=False):
47
+ if is_async:
48
+ asyncio.run(afiles_url_to_path_from_objs(objs, files_fields, coerce=coerce, is_list=is_list))
49
+ else:
50
+ if not is_list:
51
+ objs = [objs]
52
+
53
+ for obj in objs:
54
+ for files_field in files_fields:
55
+ try:
56
+ files = reduce(operator.getitem, files_field.split('.'), obj)
57
+ if isinstance(files, str):
58
+ files_url_to_path(obj, coerce=coerce, file_field=files_field)
59
+ else:
60
+ files_url_to_path(files, coerce=coerce)
61
+ except KeyError:
62
+ pass
63
+
64
+
65
+ async def adownload_file(url, path_download, name=None, coerce=None):
66
+ if name:
67
+ name += Path(url).suffix
68
+ else:
69
+ name = Path(url).name
70
+
71
+ name = urlparse(name).path
72
+ path = Path(path_download) / name
73
+ if not path.is_file():
74
+ async with aiohttp.ClientSession() as session:
75
+ async with session.get(url) as response:
76
+ with open(str(path), 'wb') as file:
77
+ while chunk := await response.content.read(1024 * 64):
78
+ file.write(chunk)
79
+
80
+ if coerce:
81
+ path = coerce(path)
82
+
83
+ return path
84
+
85
+
86
+ async def afiles_url_to_path(files, coerce=None):
87
+ path_download = get_temp_path('media')
88
+ path_download.mkdir(parents=True, exist_ok=True)
34
89
  for file_name in files:
35
90
  if isinstance(files[file_name], str):
36
- files[file_name] = download_file(files[file_name], path_download, coerce=coerce)
91
+ files[file_name] = await adownload_file(files[file_name], path_download, coerce=coerce)
37
92
  else:
38
- files[file_name]['path'] = download_file(files[file_name].pop('url'), path_download, coerce=coerce)
93
+ files[file_name]['path'] = await adownload_file(files[file_name].pop('url'), path_download, coerce=coerce)
39
94
 
40
95
 
41
- def files_url_to_path_from_objs(objs, files_fields, coerce=None, is_list=False):
96
+ async def afiles_url_to_path_from_objs(objs, files_fields, coerce=None, is_list=False):
42
97
  if not is_list:
43
98
  objs = [objs]
44
99
 
100
+ tasks = []
101
+
45
102
  for obj in objs:
46
103
  for files_field in files_fields:
47
104
  try:
48
105
  files = reduce(operator.getitem, files_field.split('.'), obj)
49
- files_url_to_path(files, coerce=coerce)
106
+ tasks.append(afiles_url_to_path(files, coerce=coerce))
50
107
  except KeyError:
51
108
  pass
52
109
 
110
+ await asyncio.gather(*tasks)
111
+
53
112
 
54
113
  def get_dict_from_file(file_path):
55
114
  if isinstance(file_path, str):
@@ -85,3 +144,25 @@ def archive(input_path, output_path):
85
144
  if file_path.is_file(): # Only add files, skip directories
86
145
  arcname = file_path.relative_to(input_path.parent)
87
146
  zipf.write(file_path, arcname)
147
+
148
+
149
+ def unarchive(file_path, output_path):
150
+ """
151
+ Unarchives a ZIP file to a given directory.
152
+
153
+ Parameters:
154
+ file_path (str | Path): The path to the ZIP file.
155
+ output_path (str): The directory where the files will be extracted.
156
+ """
157
+ output_path = Path(output_path)
158
+ output_path.mkdir(parents=True, exist_ok=True)
159
+
160
+ with zipfile.ZipFile(str(file_path), 'r') as zip_ref:
161
+ zip_ref.extractall(output_path)
162
+
163
+
164
+ def get_temp_path(sub_path=None):
165
+ path = Path('/tmp/datamaker')
166
+ if sub_path:
167
+ path = path / sub_path
168
+ return path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: synapse-sdk
3
- Version: 1.0.0a15
3
+ Version: 1.0.0a17
4
4
  Summary: synapse sdk
5
5
  Author-email: datamaker <developer@datamaker.io>
6
6
  License: MIT
@@ -8,7 +8,7 @@ synapse_sdk/loggers.py,sha256=RsDDOiOeUCih1XOkWQJseYdYCX_wt50AZJRe6aPf96Q,4004
8
8
  synapse_sdk/cli/__init__.py,sha256=WmYGW1qZEXXIGJe3SGr8QjOStY4svuZKK1Lp_aPvtPs,140
9
9
  synapse_sdk/cli/create_plugin.py,sha256=egbW_92WwxfHz50Gy4znX5Bf5fxDdQj3GFyd0l3Y3SY,228
10
10
  synapse_sdk/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- synapse_sdk/clients/base.py,sha256=b34uGFZyV13NVWPfycDK3FNz3W9gT5r4-oLQ_mVrDPQ,3327
11
+ synapse_sdk/clients/base.py,sha256=un2vseaQ7YY6rVQqd5fIyzclg7VYLAEx2TwUkZof3ik,3354
12
12
  synapse_sdk/clients/exceptions.py,sha256=ylv7x10eOp4aA3a48jwonnvqvkiYwzJYXjkVkRTAjwk,220
13
13
  synapse_sdk/clients/utils.py,sha256=8pPJTdzHiRPSbZMoQYHAgR2BAMO6u_R_jMV6a2p34iQ,392
14
14
  synapse_sdk/clients/agent/__init__.py,sha256=Pz8_iTbIbnb7ywGJ3feqoZVmO2I3mEbwpWsISIxh0BU,1968
@@ -19,7 +19,7 @@ synapse_sdk/clients/backend/__init__.py,sha256=50MW1CMWGaKnALSv2fOjhJZG55Xb3yrql
19
19
  synapse_sdk/clients/backend/annotation.py,sha256=eZc5EidgR_RfMGwvv1r1_mLkPdRd8e52c4zuuMjMX34,979
20
20
  synapse_sdk/clients/backend/dataset.py,sha256=a_svyCKgzF7N99l8V4u4wXD8JxiGuLW9z2EBinnz7b8,1738
21
21
  synapse_sdk/clients/backend/integration.py,sha256=Jg_8fEmbrgYXfZZcG8cDtLxR6ugPmnbNhPDyRu_Uib0,2160
22
- synapse_sdk/clients/backend/ml.py,sha256=lg978cCMcPiLN4ByjhrSlJHlw1_kgZQgaNZNKr9zPsI,1054
22
+ synapse_sdk/clients/backend/ml.py,sha256=vNo1FOG9welXGizcnylLSW_-l9iJSQrTI3DhyCCyFKw,1015
23
23
  synapse_sdk/clients/ray/__init__.py,sha256=9ZSPXVVxlJ8Wp8ku7l021ENtPjVrGgQDgqifkkVAXgM,187
24
24
  synapse_sdk/clients/ray/core.py,sha256=a4wyCocAma2HAm-BHlbZnoVbpfdR-Aad2FM0z6vPFvw,731
25
25
  synapse_sdk/clients/ray/serve.py,sha256=rbCpXZYWf0oP8XJ9faa9QFNPYU7h8dltIG8xn9ZconY,907
@@ -30,7 +30,7 @@ synapse_sdk/plugins/models.py,sha256=T3ZuTw7BZwMKpz2QGaErnEPetKRD9d4z3qceJkV363o
30
30
  synapse_sdk/plugins/upload.py,sha256=VJOotYMayylOH0lNoAGeGHRkLdhP7jnC_A0rFQMvQpQ,3228
31
31
  synapse_sdk/plugins/utils.py,sha256=UYkwxkmrs0-mRgQB63SkTGD1HpIQEIiHndzTcpdNaF4,2936
32
32
  synapse_sdk/plugins/categories/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- synapse_sdk/plugins/categories/base.py,sha256=Q14bnUTdPLeNeFodcOBMr9Z0d8LM1VRIq-pl8vTKgTc,8093
33
+ synapse_sdk/plugins/categories/base.py,sha256=5BrOWXbLiwZw4I1sfElQ5CF12kLDXY97b8MSvpdNIb0,8179
34
34
  synapse_sdk/plugins/categories/decorators.py,sha256=Gw6T-UHwpCKrSt596X-g2sZbY_Z1zbbogowClj7Pr5Q,518
35
35
  synapse_sdk/plugins/categories/registry.py,sha256=KdQR8SUlLT-3kgYzDNWawS1uJnAhrcw2j4zFaTpilRs,636
36
36
  synapse_sdk/plugins/categories/templates.py,sha256=FF5FerhkZMeW1YcKLY5cylC0SkWSYdJODA_Qcm4OGYQ,887
@@ -51,7 +51,7 @@ synapse_sdk/plugins/categories/neural_net/actions/__init__.py,sha256=47DEQpj8HBS
51
51
  synapse_sdk/plugins/categories/neural_net/actions/deployment.py,sha256=HeNGfRBIjiw_rRwzoApAuPm6nuT0qEj-BlJBpI8nGKc,1505
52
52
  synapse_sdk/plugins/categories/neural_net/actions/inference.py,sha256=i18bDDjkuF9V8nxxW-T_umNIOD-Jnq_MMjIjZc6W8n8,645
53
53
  synapse_sdk/plugins/categories/neural_net/actions/test.py,sha256=JY25eg-Fo6WbgtMkGoo_qNqoaZkp3AQNEypJmeGzEog,320
54
- synapse_sdk/plugins/categories/neural_net/actions/train.py,sha256=7SNhETRw-L-dNEXXANejHMPYCYeqmYjpuUaRFS5vIYA,4554
54
+ synapse_sdk/plugins/categories/neural_net/actions/train.py,sha256=ZjBE4uHOdVZ318BuepBt2l0KvSflLr1Fqt3dt4KYXJs,5113
55
55
  synapse_sdk/plugins/categories/neural_net/templates/config.yaml,sha256=dXKB1hO53hDZB73xnxLVCNQl8Sm7svMmVmuMrOCQmEU,343
56
56
  synapse_sdk/plugins/categories/neural_net/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  synapse_sdk/plugins/categories/neural_net/templates/plugin/inference.py,sha256=InfqKWJYi6sqiUnfPKHC5KYGhxckDaWZNQ202u-uVP4,366
@@ -76,7 +76,7 @@ synapse_sdk/plugins/categories/smart_tool/templates/config.yaml,sha256=3jxW8daip
76
76
  synapse_sdk/plugins/categories/smart_tool/templates/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  synapse_sdk/plugins/categories/smart_tool/templates/plugin/auto_label.py,sha256=eevNg0nOcYFR4z_L_R-sCvVOYoLWSAH1jwDkAf3YCjY,320
78
78
  synapse_sdk/plugins/cli/__init__.py,sha256=LPtUO0jqkhKq6xR1grpse7da2R6OoT_BeDyCNyUY0T4,380
79
- synapse_sdk/plugins/cli/publish.py,sha256=rhUtJsKhYyeDTQlul8mQthfMeNuQCou64faHyaP9y1c,1230
79
+ synapse_sdk/plugins/cli/publish.py,sha256=Kg_MaOeTNCra9BIzWBASsIZxLfhnNkzbRPqdlf6aTyk,1251
80
80
  synapse_sdk/plugins/cli/run.py,sha256=lw1KbsL-xTGllF4NtD2cq-Rh6HMbhi-sO862_Ds-sUo,2330
81
81
  synapse_sdk/plugins/templates/cookiecutter.json,sha256=NxOWk9A_v1pO0Ny4IYT9Cj5iiJ16--cIQrGC67QdR0I,396
82
82
  synapse_sdk/plugins/templates/hooks/post_gen_project.py,sha256=jqlYkY1O2TxIR-Vh3gnwILYy8k-D39Xx66d2KNQVMCs,147
@@ -95,7 +95,7 @@ synapse_sdk/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
95
95
  synapse_sdk/shared/enums.py,sha256=WMZPag9deVF7VCXaQkLk7ly_uX1KwbNzRx9TdvgaeFE,138
96
96
  synapse_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
97
  synapse_sdk/utils/debug.py,sha256=F7JlUwYjTFZAMRbBqKm6hxOIz-_IXYA8lBInOS4jbS4,100
98
- synapse_sdk/utils/file.py,sha256=OYch8D5Ub8oaGIIcpO6_R6-McpR3QJk7xlkaffhgd_c,2547
98
+ synapse_sdk/utils/file.py,sha256=r7KBH2uKkpj7qWTWT75zHGgm5Vfw3XKzwgkrCBLqTUU,5163
99
99
  synapse_sdk/utils/module_loading.py,sha256=chHpU-BZjtYaTBD_q0T7LcKWtqKvYBS4L0lPlKkoMQ8,1020
100
100
  synapse_sdk/utils/storage.py,sha256=a8OVbd38ATr0El4G4kuV07lr_tJZrpIJBSy4GHb0qZ8,2581
101
101
  synapse_sdk/utils/string.py,sha256=rEwuZ9SAaZLcQ8TYiwNKr1h2u4CfnrQx7SUL8NWmChg,216
@@ -103,9 +103,9 @@ synapse_sdk/utils/pydantic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
103
103
  synapse_sdk/utils/pydantic/config.py,sha256=1vYOcUI35GslfD1rrqhFkNXXJOXt4IDqOPSx9VWGfNE,123
104
104
  synapse_sdk/utils/pydantic/errors.py,sha256=0v0T12eQBr1KrFiEOBu6KMaPK4aPEGEC6etPJGoR5b4,1061
105
105
  synapse_sdk/utils/pydantic/validators.py,sha256=G47P8ObPhsePmd_QZDK8EdPnik2CbaYzr_N4Z6En8dc,193
106
- synapse_sdk-1.0.0a15.dist-info/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
107
- synapse_sdk-1.0.0a15.dist-info/METADATA,sha256=Wh0N4QJ0Hy4XMeV9YUvIHoQUGRNYklUvVnPMv9E7Bbs,1049
108
- synapse_sdk-1.0.0a15.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
109
- synapse_sdk-1.0.0a15.dist-info/entry_points.txt,sha256=VNptJoGoNJI8yLXfBmhgUefMsmGI0m3-0YoMvrOgbxo,48
110
- synapse_sdk-1.0.0a15.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
111
- synapse_sdk-1.0.0a15.dist-info/RECORD,,
106
+ synapse_sdk-1.0.0a17.dist-info/LICENSE,sha256=bKzmC5YAg4V1Fhl8OO_tqY8j62hgdncAkN7VrdjmrGk,1101
107
+ synapse_sdk-1.0.0a17.dist-info/METADATA,sha256=k2z5Xe9bbv1rYVgzhZ79iVumdgXyUfFNSz2x9euqQWQ,1049
108
+ synapse_sdk-1.0.0a17.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
109
+ synapse_sdk-1.0.0a17.dist-info/entry_points.txt,sha256=VNptJoGoNJI8yLXfBmhgUefMsmGI0m3-0YoMvrOgbxo,48
110
+ synapse_sdk-1.0.0a17.dist-info/top_level.txt,sha256=ytgJMRK1slVOKUpgcw3LEyHHP7S34J6n_gJzdkcSsw8,12
111
+ synapse_sdk-1.0.0a17.dist-info/RECORD,,