dsw-tdk 4.21.0__py2.py3-none-any.whl → 4.22.1__py2.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.
dsw/tdk/config.py ADDED
@@ -0,0 +1,154 @@
1
+ import configparser
2
+ import dataclasses
3
+ import os
4
+ import pathlib
5
+
6
+ import dotenv
7
+
8
+ from .consts import DEFAULT_ENCODING
9
+
10
+
11
+ def _rectify_api_url(api_url: str | None) -> str:
12
+ if not api_url or not isinstance(api_url, str):
13
+ return ''
14
+ return api_url.rstrip('/')
15
+
16
+
17
+ def _rectify_api_key(api_key: str | None) -> str:
18
+ if not api_key or not isinstance(api_key, str):
19
+ return ''
20
+ return api_key.strip()
21
+
22
+
23
+ @dataclasses.dataclass
24
+ class TDKWizardEnv:
25
+ api_url: str
26
+ api_key: str
27
+
28
+ def rectify(self):
29
+ self.api_url = _rectify_api_url(self.api_url)
30
+ self.api_key = _rectify_api_key(self.api_key)
31
+
32
+
33
+ class TDKConfig:
34
+ LOCAL_CONFIG = '_local'
35
+ HOME_CONFIG = pathlib.Path.home() / '.dsw-tdk' / 'config.cfg'
36
+
37
+ def __init__(self):
38
+ self.shared_envs = {} # type: dict[str, TDKWizardEnv]
39
+ self.local_env = TDKWizardEnv(
40
+ api_url='',
41
+ api_key='',
42
+ )
43
+ self.current_env_name = self.LOCAL_CONFIG
44
+ self.default_env_name = None # type: str | None
45
+
46
+ def load_dotenv(self, path: pathlib.Path):
47
+ try:
48
+ if path.exists():
49
+ dotenv.load_dotenv(path)
50
+ except Exception as e:
51
+ print(f"Error loading .env file: {e}")
52
+ api_url = os.getenv('DSW_API_URL', '')
53
+ api_key = os.getenv('DSW_API_KEY', '')
54
+
55
+ if not api_url or not api_key:
56
+ return
57
+
58
+ self.current_env_name = self.LOCAL_CONFIG
59
+ self.local_env = TDKWizardEnv(
60
+ api_url=api_url,
61
+ api_key=api_key,
62
+ )
63
+ self.local_env.rectify()
64
+
65
+ def load_home_config(self):
66
+ config_path = self.HOME_CONFIG
67
+ if not config_path.exists():
68
+ return
69
+
70
+ config = configparser.ConfigParser()
71
+ config.read(config_path)
72
+ for section in config.sections():
73
+ if section == 'default':
74
+ self.default_env_name = config.get(section, 'env', fallback=None)
75
+ elif section.startswith('env:'):
76
+ env_name = section[4:]
77
+ if env_name not in self.shared_envs:
78
+ self.shared_envs[env_name] = TDKWizardEnv(
79
+ api_url=config.get(section, 'api_url', fallback=''),
80
+ api_key=config.get(section, 'api_key', fallback=''),
81
+ )
82
+ self.shared_envs[env_name].rectify()
83
+ if self.default_env_name is not None:
84
+ self.current_env_name = self.default_env_name
85
+
86
+ @property
87
+ def env(self) -> TDKWizardEnv:
88
+ if self.current_env_name == self.LOCAL_CONFIG:
89
+ return self.local_env
90
+ return self.shared_envs[self.current_env_name]
91
+
92
+ @property
93
+ def has_api_url(self) -> bool:
94
+ return self.env.api_url != ''
95
+
96
+ def set_api_url(self, api_url: str):
97
+ self.env.api_url = _rectify_api_url(api_url)
98
+
99
+ @property
100
+ def has_api_key(self) -> bool:
101
+ return self.env.api_key != ''
102
+
103
+ def set_api_key(self, api_key: str):
104
+ self.env.api_key = _rectify_api_key(api_key)
105
+
106
+ def use_local_env(self):
107
+ self.current_env_name = self.LOCAL_CONFIG
108
+
109
+ def switch_current_env(self, env_name: str | None):
110
+ if env_name not in self.shared_envs:
111
+ raise ValueError(f'Environment "{env_name}" does not exist')
112
+ self.current_env_name = env_name
113
+
114
+ @property
115
+ def is_default_env(self) -> bool:
116
+ return self.current_env_name == self.default_env_name
117
+
118
+ @property
119
+ def env_names(self) -> list[str]:
120
+ return sorted(env_name for env_name in self.shared_envs)
121
+
122
+ def add_shared_env(self, name: str, api_url: str, api_key: str):
123
+ if name == self.LOCAL_CONFIG:
124
+ raise ValueError(f'Environment name "{self.LOCAL_CONFIG}" is reserved')
125
+ if name in self.shared_envs:
126
+ raise ValueError(f'Environment "{name}" already exists')
127
+ self.shared_envs[name] = TDKWizardEnv(
128
+ api_url=api_url,
129
+ api_key=api_key,
130
+ )
131
+
132
+ def persist(self, force: bool):
133
+ output = self.HOME_CONFIG
134
+ if output.exists() and not force:
135
+ raise FileExistsError(f'File {output.as_posix()} already exists (not forced)')
136
+ if not output.parent.exists():
137
+ output.parent.mkdir(parents=True, exist_ok=True)
138
+
139
+ config = configparser.ConfigParser()
140
+ config.add_section('default')
141
+ if self.default_env_name:
142
+ config.set('default', 'env', self.default_env_name)
143
+
144
+ for env_name, env in self.shared_envs.items():
145
+ section_name = f'env:{env_name}'
146
+ config.add_section(section_name)
147
+ config.set(section_name, 'api_url', env.api_url)
148
+ config.set(section_name, 'api_key', env.api_key)
149
+
150
+ with open(output, 'w', encoding=DEFAULT_ENCODING) as configfile:
151
+ config.write(configfile)
152
+
153
+
154
+ CONFIG = TDKConfig()
dsw/tdk/consts.py CHANGED
@@ -4,8 +4,10 @@ import re
4
4
  import pathspec
5
5
 
6
6
  APP = 'dsw-tdk'
7
- VERSION = '4.21.0'
8
- METAMODEL_VERSION = 16
7
+ VERSION = '4.22.1'
8
+ METAMODEL_VERSION_MAJOR = 17
9
+ METAMODEL_VERSION_MINOR = 0
10
+ METAMODEL_VERSION = f'{METAMODEL_VERSION_MAJOR}.{METAMODEL_VERSION_MINOR}'
9
11
 
10
12
  REGEX_SEMVER = re.compile(r'^[0-9]+\.[0-9]+\.[0-9]+$')
11
13
  REGEX_WIZARD_ID = re.compile(r'^[a-zA-Z0-9-_.]+$')
dsw/tdk/core.py CHANGED
@@ -11,10 +11,10 @@ import zipfile
11
11
 
12
12
  import watchfiles
13
13
 
14
- from .api_client import DSWAPIClient, DSWCommunicationError
14
+ from .api_client import WizardAPIClient, WizardCommunicationError
15
15
  from .consts import DEFAULT_ENCODING, REGEX_SEMVER
16
16
  from .model import TemplateProject, Template, TemplateFile, TemplateFileType
17
- from .utils import UUIDGen, create_dot_env
17
+ from .utils import UUIDGen
18
18
  from .validation import ValidationError, TemplateValidator
19
19
 
20
20
 
@@ -33,54 +33,71 @@ class TDKProcessingError(RuntimeError):
33
33
 
34
34
 
35
35
  METAMODEL_VERSION_SUPPORT = {
36
- 1: (2, 5, 0),
37
- 2: (2, 6, 0),
38
- 3: (2, 12, 0),
39
- 4: (3, 2, 0),
40
- 5: (3, 5, 0),
41
- 6: (3, 6, 0),
42
- 7: (3, 7, 0),
43
- 8: (3, 8, 0),
44
- 9: (3, 10, 0),
45
- 10: (3, 12, 0),
46
- 11: (3, 20, 0),
47
- 12: (4, 1, 0),
48
- 13: (4, 3, 0),
49
- 14: (4, 10, 0),
50
- 15: (4, 12, 0),
51
- 16: (4, 13, 0),
36
+ '1.0': (2, 5, 0),
37
+ '2.0': (2, 6, 0),
38
+ '3.0': (2, 12, 0),
39
+ '4.0': (3, 2, 0),
40
+ '5.0': (3, 5, 0),
41
+ '6.0': (3, 6, 0),
42
+ '7.0': (3, 7, 0),
43
+ '8.0': (3, 8, 0),
44
+ '9.0': (3, 10, 0),
45
+ '10.0': (3, 12, 0),
46
+ '11.0': (3, 20, 0),
47
+ '12.0': (4, 1, 0),
48
+ '13.0': (4, 3, 0),
49
+ '14.0': (4, 10, 0),
50
+ '15.0': (4, 12, 0),
51
+ '16.0': (4, 13, 0),
52
+ '17.0': (4, 22, 0),
52
53
  }
53
54
 
54
55
 
55
- # pylint: disable=too-many-public-methods
56
+ # pylint: disable-next=too-many-public-methods
56
57
  class TDKCore:
57
58
 
59
+ # pylint: disable-next=too-many-locals
58
60
  def _check_metamodel_version(self):
59
- mm_ver = self.safe_template.metamodel_version
61
+ hint = 'Fix your metamodelVersion in template.json and/or visit docs'
62
+ mm_ver = str(self.safe_template.metamodel_version)
63
+ try:
64
+ if '.' not in mm_ver:
65
+ mm_ver = f'{mm_ver}.0'
66
+ mm_major, mm_minor = map(int, mm_ver.split('.'))
67
+ except ValueError as e:
68
+ raise TDKProcessingError(f'Invalid metamodel version format: {mm_ver}', hint) from e
60
69
  api_version = self.remote_version.split('~', maxsplit=1)[0]
61
70
  if '-' in api_version:
62
71
  api_version = api_version.split('-', maxsplit=1)[0]
63
72
  if 'v' == api_version[0]:
64
73
  api_version = api_version[1:]
65
74
  if not re.match(REGEX_SEMVER, api_version):
66
- self.logger.warning('Using non-stable release of API: %s', self.remote_version)
75
+ self.logger.warning('Using non-stable release of API: %s',
76
+ self.remote_version)
67
77
  return
68
78
  parts = api_version.split('.')
69
79
  ver = (int(parts[0]), int(parts[1]), int(parts[2]))
70
80
  vtag = f'v{ver[0]}.{ver[1]}.{ver[2]}'
71
- hint = 'Fix your metamodelVersion in template.json and/or visit docs'
72
81
  if mm_ver not in METAMODEL_VERSION_SUPPORT:
73
82
  raise TDKProcessingError(f'Unknown metamodel version: {mm_ver}', hint)
74
- min_version = METAMODEL_VERSION_SUPPORT[mm_ver]
75
- if min_version > ver:
76
- raise TDKProcessingError(f'Unsupported metamodel version for API {vtag}', hint)
77
- if mm_ver + 1 in METAMODEL_VERSION_SUPPORT:
78
- max_version = METAMODEL_VERSION_SUPPORT[mm_ver + 1]
79
- if ver >= max_version:
80
- raise TDKProcessingError(f'Unsupported metamodel version for API {vtag}', hint)
83
+ map_reverse = {v: k for k, v in METAMODEL_VERSION_SUPPORT.items()}
84
+ nearest_leq = unknown_version = (0, 0, 0)
85
+ for known_version in map_reverse.keys():
86
+ if known_version <= ver:
87
+ nearest_leq = known_version
88
+ else:
89
+ break
90
+ if nearest_leq == unknown_version:
91
+ raise TDKProcessingError(f'Unsupported API version: {vtag}', hint)
92
+ api_mm_major, api_mm_minor = map(int, map_reverse[nearest_leq].split('.'))
93
+ if mm_major != api_mm_major or mm_minor < api_mm_minor:
94
+ raise TDKProcessingError(
95
+ f'Unsupported metamodel version {mm_ver} for API version {api_version}',
96
+ hint,
97
+ )
81
98
 
82
99
  def __init__(self, template: Template | None = None, project: TemplateProject | None = None,
83
- client: DSWAPIClient | None = None, logger: logging.Logger | None = None):
100
+ client: WizardAPIClient | None = None, logger: logging.Logger | None = None):
84
101
  self.template = template
85
102
  self.project = project
86
103
  self.client = client
@@ -106,14 +123,14 @@ class TDKCore:
106
123
  return self.project
107
124
 
108
125
  @property
109
- def safe_client(self) -> DSWAPIClient:
126
+ def safe_client(self) -> WizardAPIClient:
110
127
  if self.client is None:
111
128
  raise RuntimeError('No DSW API client specified')
112
129
  return self.client
113
130
 
114
131
  async def init_client(self, api_url: str, api_key: str):
115
132
  self.logger.info('Connecting to %s', api_url)
116
- self.client = DSWAPIClient(api_url=api_url, api_key=api_key)
133
+ self.client = WizardAPIClient(api_url=api_url, api_key=api_key)
117
134
  self.remote_version = await self.client.get_api_version()
118
135
  user = await self.client.get_current_user()
119
136
  self.logger.info('Successfully authenticated as %s %s (%s)',
@@ -135,13 +152,13 @@ class TDKCore:
135
152
  self.logger.debug('Retrieving template draft files')
136
153
  files = await self.safe_client.get_template_draft_files(remote_id=template_id)
137
154
  self.logger.info('Retrieved %s file(s)', len(files))
138
- for tfile in files:
139
- self.safe_template.files[tfile.filename.as_posix()] = tfile
155
+ for file in files:
156
+ self.safe_template.files[file.filename.as_posix()] = file
140
157
  self.logger.debug('Retrieving template draft assets')
141
158
  assets = await self.safe_client.get_template_draft_assets(remote_id=template_id)
142
159
  self.logger.info('Retrieved %s asset(s)', len(assets))
143
- for tfile in assets:
144
- self.safe_template.files[tfile.filename.as_posix()] = tfile
160
+ for asset in assets:
161
+ self.safe_template.files[asset.filename.as_posix()] = asset
145
162
 
146
163
  async def download_bundle(self, template_id: str) -> bytes:
147
164
  self.logger.info('Retrieving template %s bundle', template_id)
@@ -215,103 +232,105 @@ class TDKCore:
215
232
  )
216
233
  await self.store_remote_files()
217
234
 
218
- async def _update_template_file(self, remote_tfile: TemplateFile, local_tfile: TemplateFile,
235
+ async def _update_template_file(self, remote_file: TemplateFile, local_file: TemplateFile,
219
236
  project_update: bool = False):
220
237
  try:
221
238
  self.logger.debug('Updating existing remote %s %s (%s) started',
222
- remote_tfile.remote_type.value, remote_tfile.filename.as_posix(),
223
- remote_tfile.remote_id)
224
- local_tfile.remote_id = remote_tfile.remote_id
225
- if remote_tfile.remote_type == TemplateFileType.ASSET:
239
+ remote_file.remote_type.value, remote_file.filename.as_posix(),
240
+ remote_file.remote_id)
241
+ local_file.remote_id = remote_file.remote_id
242
+ if remote_file.remote_type == TemplateFileType.ASSET:
226
243
  result = await self.safe_client.put_template_draft_asset_content(
227
244
  remote_id=self.remote_id,
228
- tfile=local_tfile,
245
+ file=local_file,
229
246
  )
230
247
  else:
231
248
  result = await self.safe_client.put_template_draft_file_content(
232
249
  remote_id=self.remote_id,
233
- tfile=local_tfile,
250
+ file=local_file,
234
251
  )
235
252
  self.logger.debug('Updating existing remote %s %s (%s) finished: %s',
236
- remote_tfile.remote_type.value, remote_tfile.filename.as_posix(),
237
- remote_tfile.remote_id, 'ok' if result else 'failed')
253
+ remote_file.remote_type.value, remote_file.filename.as_posix(),
254
+ remote_file.remote_id, 'ok' if result else 'failed')
238
255
  if project_update and result:
239
256
  self.safe_project.update_template_file(result)
240
257
  except Exception as e1:
241
258
  try:
242
259
  self.logger.debug('Trying to delete/create due to: %s', str(e1))
243
- await self._delete_template_file(tfile=remote_tfile)
244
- await self._create_template_file(tfile=local_tfile, project_update=True)
260
+ await self._delete_template_file(file=remote_file)
261
+ await self._create_template_file(file=local_file, project_update=True)
245
262
  except Exception as e2:
246
263
  self.logger.error('Failed to update existing remote %s %s: %s',
247
- remote_tfile.remote_type.value,
248
- remote_tfile.filename.as_posix(), e2)
264
+ remote_file.remote_type.value,
265
+ remote_file.filename.as_posix(), e2)
249
266
 
250
- async def _delete_template_file(self, tfile: TemplateFile, project_update: bool = False):
267
+ async def _delete_template_file(self, file: TemplateFile, project_update: bool = False):
251
268
  try:
252
269
  self.logger.debug('Deleting existing remote %s %s (%s) started',
253
- tfile.remote_type.value, tfile.filename.as_posix(),
254
- tfile.remote_id)
255
- if tfile.remote_type == TemplateFileType.ASSET:
270
+ file.remote_type.value, file.filename.as_posix(),
271
+ file.remote_id)
272
+ if file.remote_type == TemplateFileType.ASSET:
256
273
  result = await self.safe_client.delete_template_draft_asset(
257
274
  remote_id=self.remote_id,
258
- asset_id=tfile.remote_id,
275
+ asset_id=file.remote_id,
259
276
  )
260
277
  else:
261
278
  result = await self.safe_client.delete_template_draft_file(
262
279
  remote_id=self.remote_id,
263
- file_id=tfile.remote_id,
280
+ file_id=file.remote_id,
264
281
  )
265
282
  self.logger.debug('Deleting existing remote %s %s (%s) finished: %s',
266
- tfile.remote_type.value, tfile.filename.as_posix(),
267
- tfile.remote_id, 'ok' if result else 'failed')
283
+ file.remote_type.value,
284
+ file.filename.as_posix(),
285
+ file.remote_id, 'ok' if result else 'failed')
268
286
  if project_update and result:
269
- self.safe_project.remove_template_file(tfile.filename)
287
+ self.safe_project.remove_template_file(file.filename)
270
288
  except Exception as e:
271
289
  self.logger.error('Failed to delete existing remote %s %s: %s',
272
- tfile.remote_type.value, tfile.filename.as_posix(), e)
290
+ file.remote_type.value, file.filename.as_posix(), e)
273
291
 
274
292
  async def cleanup_remote_files(self, remote_assets: list[TemplateFile],
275
293
  remote_files: list[TemplateFile]):
276
- for tfile in self.safe_project.safe_template.files.values():
277
- self.logger.debug('Cleaning up remote %s', tfile.filename.as_posix())
278
- for remote_asset in remote_assets:
279
- if remote_asset.filename == tfile.filename:
280
- await self._delete_template_file(tfile=remote_asset, project_update=False)
281
- for remote_file in remote_files:
282
- if remote_file.filename == tfile.filename:
283
- await self._delete_template_file(tfile=remote_file, project_update=False)
284
-
285
- async def _create_template_file(self, tfile: TemplateFile, project_update: bool = False):
294
+ for file in self.safe_project.safe_template.files.values():
295
+ self.logger.debug('Cleaning up remote %s', file.filename.as_posix())
296
+ for asset in remote_assets:
297
+ if asset.filename == file.filename:
298
+ await self._delete_template_file(file=asset, project_update=False)
299
+ for file in remote_files:
300
+ if file.filename == file.filename:
301
+ await self._delete_template_file(file=file, project_update=False)
302
+
303
+ async def _create_template_file(self, file: TemplateFile, project_update: bool = False):
286
304
  try:
287
305
  self.logger.debug('Storing remote %s %s started',
288
- tfile.remote_type.value, tfile.filename.as_posix())
289
- if tfile.remote_type == TemplateFileType.ASSET:
306
+ file.remote_type.value, file.filename.as_posix())
307
+ if file.remote_type == TemplateFileType.ASSET:
290
308
  result = await self.safe_client.post_template_draft_asset(
291
309
  remote_id=self.remote_id,
292
- tfile=tfile,
310
+ file=file,
293
311
  )
294
312
  else:
295
313
  result = await self.safe_client.post_template_draft_file(
296
314
  remote_id=self.remote_id,
297
- tfile=tfile,
315
+ file=file,
298
316
  )
299
317
  self.logger.debug('Storing remote %s %s finished: %s',
300
- tfile.remote_type.value, tfile.filename.as_posix(), result.remote_id)
318
+ file.remote_type.value, file.filename.as_posix(),
319
+ result.remote_id)
301
320
  if project_update and result is not None:
302
321
  self.safe_project.update_template_file(result)
303
322
  except Exception as e:
304
323
  self.logger.error('Failed to store remote %s %s: %s',
305
- tfile.remote_type.value, tfile.filename.as_posix(), e)
324
+ file.remote_type.value, file.filename.as_posix(), e)
306
325
 
307
326
  async def store_remote_files(self):
308
327
  if len(self.safe_project.safe_template.files) == 0:
309
328
  self.logger.warning('No files to store, maybe you forgot to '
310
329
  'update _tdk.files patterns in template.json?')
311
- for tfile in self.safe_project.safe_template.files.values():
312
- tfile.remote_id = None
313
- tfile.remote_type = TemplateFileType.FILE if tfile.is_text else TemplateFileType.ASSET
314
- await self._create_template_file(tfile=tfile, project_update=True)
330
+ for file in self.safe_project.safe_template.files.values():
331
+ file.remote_id = None
332
+ file.remote_type = TemplateFileType.FILE if file.is_text else TemplateFileType.ASSET
333
+ await self._create_template_file(file=file, project_update=True)
315
334
 
316
335
  def create_package(self, output: pathlib.Path, force: bool):
317
336
  if output.exists() and not force:
@@ -321,23 +340,26 @@ class TDKCore:
321
340
  descriptor = self.safe_project.safe_template.serialize_remote()
322
341
  files = []
323
342
  assets = []
324
- for tfile in self.safe_project.safe_template.files.values():
325
- if tfile.is_text:
326
- self.logger.info('Adding template file %s', tfile.filename.as_posix())
343
+ for file in self.safe_project.safe_template.files.values():
344
+ if file.is_text:
345
+ self.logger.info('Adding template file %s', file.filename.as_posix())
327
346
  files.append({
328
347
  'uuid': str(UUIDGen.generate()),
329
- 'content': tfile.content.decode(encoding=DEFAULT_ENCODING),
330
- 'fileName': str(tfile.filename.as_posix()),
348
+ 'content': file.content.decode(encoding=DEFAULT_ENCODING),
349
+ 'fileName': str(file.filename.as_posix()),
331
350
  })
332
351
  else:
333
- self.logger.info('Adding template asset %s', tfile.filename.as_posix())
352
+ self.logger.info('Adding template asset %s',
353
+ file.filename.as_posix())
334
354
  assets.append({
335
355
  'uuid': str(UUIDGen.generate()),
336
- 'contentType': tfile.content_type,
337
- 'fileName': str(tfile.filename.as_posix()),
356
+ 'contentType': file.content_type,
357
+ 'fileName': str(file.filename.as_posix()),
338
358
  })
339
- self.logger.debug('Packaging template asset %s', tfile.filename.as_posix())
340
- pkg.writestr(f'template/assets/{tfile.filename.as_posix()}', tfile.content)
359
+ self.logger.debug('Packaging template asset %s',
360
+ file.filename.as_posix())
361
+ pkg.writestr(f'template/assets/{file.filename.as_posix()}',
362
+ file.content)
341
363
  descriptor['files'] = files
342
364
  descriptor['assets'] = assets
343
365
  if len(files) == 0 and len(assets) == 0:
@@ -347,7 +369,8 @@ class TDKCore:
347
369
  descriptor['createdAt'] = timestamp
348
370
  descriptor['updatedAt'] = timestamp
349
371
  self.logger.debug('Packaging template.json file')
350
- pkg.writestr('template/template.json', data=json.dumps(descriptor, indent=4))
372
+ pkg.writestr('template/template.json',
373
+ data=json.dumps(descriptor, indent=4))
351
374
  self.logger.debug('ZIP packaging done')
352
375
 
353
376
  # pylint: disable=too-many-locals
@@ -358,12 +381,12 @@ class TDKCore:
358
381
  pkg.extractall(tmp_dir)
359
382
  del io_zip
360
383
  tmp_root = pathlib.Path(tmp_dir) / 'template'
361
- template_file = tmp_root / 'template.json'
384
+ file = tmp_root / 'template.json'
362
385
  assets_dir = tmp_root / 'assets'
363
386
  self.logger.debug('Extracting template data')
364
- if not template_file.exists():
387
+ if not file.exists():
365
388
  raise RuntimeError('Malformed package: missing template.json file')
366
- data = json.loads(template_file.read_text(encoding=DEFAULT_ENCODING))
389
+ data = json.loads(file.read_text(encoding=DEFAULT_ENCODING))
367
390
  template = Template.load_local(data)
368
391
  template.tdk_config.use_default_files()
369
392
  self.logger.warning('Using default _tdk.files in template.json, you may want '
@@ -406,17 +429,6 @@ class TDKCore:
406
429
  target_file.write_text(data=content, encoding=DEFAULT_ENCODING)
407
430
  self.logger.debug('Extracting package done')
408
431
 
409
- def create_dot_env(self, output: pathlib.Path, force: bool, api_url: str, api_key: str):
410
- if output.exists():
411
- if force:
412
- self.logger.warning('Overwriting %s (forced)', output.as_posix())
413
- else:
414
- raise RuntimeError(f'File {output} already exists (not forced)')
415
- output.write_text(
416
- data=create_dot_env(api_url=api_url, api_key=api_key),
417
- encoding=DEFAULT_ENCODING,
418
- )
419
-
420
432
  async def watch_project(self, callback, stop_event: asyncio.Event):
421
433
  async for changes in watchfiles.awatch(
422
434
  self.safe_project.template_dir,
@@ -442,10 +454,11 @@ class TDKCore:
442
454
  remote_id=self.remote_id,
443
455
  )
444
456
  else:
445
- self.logger.info('Document template draft %s does not exist on remote - full sync',
457
+ self.logger.info('Document template draft %s does '
458
+ 'not exist on remote - full sync',
446
459
  self.safe_project.safe_template.id)
447
460
  await self.store_remote(force=False)
448
- except DSWCommunicationError as e:
461
+ except WizardCommunicationError as e:
449
462
  self.logger.error('Failed to update document template draft %s: %s',
450
463
  self.safe_project.safe_template.id, e.message)
451
464
  except Exception as e:
@@ -458,12 +471,12 @@ class TDKCore:
458
471
  filepath.as_posix())
459
472
  return
460
473
  try:
461
- tfile = self.safe_project.get_template_file(filepath=filepath)
462
- if tfile is None:
474
+ file = self.safe_project.get_template_file(filepath=filepath)
475
+ if file is None:
463
476
  self.logger.info('File %s not tracked currently - skipping',
464
477
  filepath.as_posix())
465
478
  return
466
- await self._delete_template_file(tfile=tfile, project_update=True)
479
+ await self._delete_template_file(file=file, project_update=True)
467
480
  except Exception as e:
468
481
  self.logger.error('Failed to delete file %s: %s',
469
482
  filepath.as_posix(), e)
@@ -474,12 +487,12 @@ class TDKCore:
474
487
  filepath.as_posix())
475
488
  return
476
489
  try:
477
- remote_tfile = self.safe_project.get_template_file(filepath=filepath)
478
- local_tfile = self.safe_project.load_file(filepath=filepath)
479
- if remote_tfile is not None:
480
- await self._update_template_file(remote_tfile, local_tfile, project_update=True)
490
+ remote_file = self.safe_project.get_template_file(filepath=filepath)
491
+ local_file = self.safe_project.load_file(filepath=filepath)
492
+ if remote_file is not None:
493
+ await self._update_template_file(remote_file, local_file, project_update=True)
481
494
  else:
482
- await self._create_template_file(tfile=local_tfile, project_update=True)
495
+ await self._create_template_file(file=local_file, project_update=True)
483
496
  except Exception as e:
484
497
  self.logger.error('Failed to update file %s: %s', filepath.as_posix(), e)
485
498
 
dsw/tdk/model.py CHANGED
@@ -141,9 +141,9 @@ class TemplateFile:
141
141
  self.filename = filename
142
142
  self.content = content
143
143
  self.content_type: str = content_type or self.guess_type()
144
- self.remote_type: TemplateFileType = remote_type or self.guess_tfile_type()
144
+ self.remote_type: TemplateFileType = remote_type or self.guess_template_file_type()
145
145
 
146
- def guess_tfile_type(self):
146
+ def guess_template_file_type(self):
147
147
  return TemplateFileType.FILE if self.is_text else TemplateFileType.ASSET
148
148
 
149
149
  def guess_type(self) -> str:
@@ -180,7 +180,7 @@ class Template:
180
180
  self.description = description # type: str
181
181
  self.readme = readme # type: str
182
182
  self.license = template_license # type: str
183
- self.metamodel_version: int = metamodel_version or METAMODEL_VERSION
183
+ self.metamodel_version: str = metamodel_version or METAMODEL_VERSION
184
184
  self.allowed_packages: list[PackageFilter] = []
185
185
  self.formats: list[Format] = []
186
186
  self.files: dict[str, TemplateFile] = {}
@@ -355,11 +355,11 @@ class TemplateProject:
355
355
  try:
356
356
  if filepath.is_absolute():
357
357
  filepath = filepath.relative_to(self.template_dir)
358
- tfile = TemplateFile(filename=filepath)
358
+ template_file = TemplateFile(filename=filepath)
359
359
  with open(self.template_dir / filepath, mode='rb') as f:
360
- tfile.content = f.read()
361
- self.safe_template.files[filepath.as_posix()] = tfile
362
- return tfile
360
+ template_file.content = f.read()
361
+ self.safe_template.files[filepath.as_posix()] = template_file
362
+ return template_file
363
363
  except Exception as e:
364
364
  raise RuntimeWarning(f'Failed to load template file {filepath}: {e}') from e
365
365
 
@@ -406,9 +406,9 @@ class TemplateProject:
406
406
  if filename in self.safe_template.files:
407
407
  del self.safe_template.files[filename]
408
408
 
409
- def update_template_file(self, tfile: TemplateFile):
410
- filename = tfile.filename.as_posix()
411
- self.safe_template.files[filename] = tfile
409
+ def update_template_file(self, template_file: TemplateFile):
410
+ filename = template_file.filename.as_posix()
411
+ self.safe_template.files[filename] = template_file
412
412
 
413
413
  def get_template_file(self, filepath: pathlib.Path) -> TemplateFile | None:
414
414
  if filepath.is_absolute():
@@ -447,10 +447,10 @@ class TemplateProject:
447
447
  )
448
448
 
449
449
  def store_files(self, force: bool):
450
- for tfile in self.safe_template.files.values():
450
+ for template_file in self.safe_template.files.values():
451
451
  self._write_file(
452
- filepath=self.template_dir / tfile.filename,
453
- contents=tfile.content,
452
+ filepath=self.template_dir / template_file.filename,
453
+ contents=template_file.content,
454
454
  force=force,
455
455
  )
456
456
 
dsw/tdk/templates/env.j2 CHANGED
@@ -1,2 +1,3 @@
1
1
  DSW_API_URL={{ api_url|default("http://localhost:3000") }}
2
2
  DSW_API_KEY={{ api_key|default("") }}
3
+