dsw-tdk 4.12.0__py2.py3-none-any.whl → 4.14.0__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/model.py CHANGED
@@ -3,29 +3,30 @@ import json
3
3
  import logging
4
4
  import mimetypes
5
5
  import pathlib
6
- import pathspec # type: ignore
7
6
 
8
7
  from collections import OrderedDict
9
- from typing import List, Dict, Optional, Tuple, Any
8
+ from typing import Any
10
9
 
11
- from .consts import VERSION, DEFAULT_ENCODING, METAMODEL_VERSION, PATHSPEC_FACTORY
10
+ import pathspec
11
+
12
+ from .consts import VERSION, DEFAULT_ENCODING, METAMODEL_VERSION, PathspecFactory
12
13
 
13
14
  mimetypes.init()
14
15
 
15
16
 
16
17
  class TemplateFileType(enum.Enum):
17
- asset = 'asset'
18
- file = 'file'
18
+ ASSET = 'asset'
19
+ FILE = 'file'
19
20
 
20
21
 
21
22
  class PackageFilter:
22
23
 
23
- def __init__(self, *, organization_id=None, km_id=None, min_version=None,
24
- max_version=None):
25
- self.organization_id = organization_id # type: Optional[str]
26
- self.km_id = km_id # type: Optional[str]
27
- self.min_version = min_version # type: Optional[str]
28
- self.max_version = max_version # type: Optional[str]
24
+ def __init__(self, *, organization_id: str | None = None, km_id: str | None = None,
25
+ min_version: str | None = None, max_version: str | None = None):
26
+ self.organization_id = organization_id
27
+ self.km_id = km_id
28
+ self.min_version = min_version
29
+ self.max_version = max_version
29
30
 
30
31
  @classmethod
31
32
  def load(cls, data):
@@ -47,9 +48,10 @@ class PackageFilter:
47
48
 
48
49
  class Step:
49
50
 
50
- def __init__(self, *, name=None, options=None):
51
- self.name = name # type: str
52
- self.options = options or dict() # type: Dict[str, str]
51
+ def __init__(self, *, name: str | None = None,
52
+ options: dict[str, str] | None = None):
53
+ self.name = name
54
+ self.options = options or {}
53
55
 
54
56
  @classmethod
55
57
  def load(cls, data):
@@ -69,11 +71,12 @@ class Format:
69
71
 
70
72
  DEFAULT_ICON = 'fas fa-file'
71
73
 
72
- def __init__(self, *, uuid=None, name=None, icon=None):
73
- self.uuid = uuid # type: str
74
- self.name = name # type: str
75
- self.icon = icon or self.DEFAULT_ICON # type: str
76
- self.steps = [] # type: List[Step]
74
+ def __init__(self, *, uuid: str | None = None, name: str | None = None,
75
+ icon: str | None = None):
76
+ self.uuid = uuid
77
+ self.name = name
78
+ self.icon: str = icon or self.DEFAULT_ICON
79
+ self.steps: list[Step] = []
77
80
 
78
81
  @classmethod
79
82
  def load(cls, data):
@@ -100,11 +103,12 @@ class TDKConfig:
100
103
  DEFAULT_README = 'README.md'
101
104
  DEFAULT_FILES = ['*']
102
105
 
103
- def __init__(self, *, version=None, readme_file=None, files=None):
104
- self.version = version or VERSION # type: str
105
- readme_file_str = readme_file or self.DEFAULT_README # type: str
106
- self.readme_file = pathlib.Path(readme_file_str) # type: pathlib.Path
107
- self.files = files or [] # type: List[str]
106
+ def __init__(self, *, version: str | None = None, readme_file: str | None = None,
107
+ files: list[str] | None = None):
108
+ self.version: str = version or VERSION
109
+ readme_file_str: str = readme_file or self.DEFAULT_README
110
+ self.readme_file: pathlib.Path = pathlib.Path(readme_file_str)
111
+ self.files: list[str] = files or []
108
112
 
109
113
  @classmethod
110
114
  def load(cls, data):
@@ -127,19 +131,19 @@ class TemplateFile:
127
131
  DEFAULT_CONTENT_TYPE = 'application/octet-stream'
128
132
  TEMPLATE_EXTENSIONS = ('.j2', '.jinja', '.jinja2', '.jnj')
129
133
 
130
- def __init__(self, *, remote_id=None, remote_type=None, filename=None,
131
- content_type=None, content=None):
132
- self.remote_id = remote_id # type: Optional[str]
133
- self.filename = filename # type: pathlib.Path
134
- self.content = content # type: bytes
135
- self.content_type = content_type or self.guess_type() # type: str
136
- self.remote_type = remote_type or self.guess_tfile_type() # type: TemplateFileType
134
+ def __init__(self, *, filename: pathlib.Path,
135
+ remote_id: str | None = None, remote_type: TemplateFileType | None = None,
136
+ content_type: str | None = None, content: bytes = b''):
137
+ self.remote_id = remote_id
138
+ self.filename = filename
139
+ self.content = content
140
+ self.content_type: str = content_type or self.guess_type()
141
+ self.remote_type: TemplateFileType = remote_type or self.guess_tfile_type()
137
142
 
138
143
  def guess_tfile_type(self):
139
- return TemplateFileType.file if self.is_text else TemplateFileType.asset
144
+ return TemplateFileType.FILE if self.is_text else TemplateFileType.ASSET
140
145
 
141
146
  def guess_type(self) -> str:
142
- # TODO: add own map of file extensions
143
147
  filename = self.filename.name
144
148
  for ext in self.TEMPLATE_EXTENSIONS:
145
149
  if filename.endswith(ext):
@@ -151,8 +155,7 @@ class TemplateFile:
151
155
 
152
156
  @property
153
157
  def is_text(self):
154
- # TODO: custom mapping (also some starting with "application" are textual)
155
- if getattr(self, 'remote_type', None) == TemplateFileType.file:
158
+ if getattr(self, 'remote_type', None) == TemplateFileType.FILE:
156
159
  return True
157
160
  return self.content_type.startswith('text')
158
161
 
@@ -163,6 +166,7 @@ class TemplateFile:
163
166
 
164
167
  class Template:
165
168
 
169
+ # pylint: disable-next=too-many-arguments
166
170
  def __init__(self, *, template_id=None, organization_id=None, version=None, name=None,
167
171
  description=None, readme=None, template_license=None,
168
172
  metamodel_version=None, tdk_config=None, loaded_json=None):
@@ -173,13 +177,13 @@ class Template:
173
177
  self.description = description # type: str
174
178
  self.readme = readme # type: str
175
179
  self.license = template_license # type: str
176
- self.metamodel_version = metamodel_version or METAMODEL_VERSION # type: int
177
- self.allowed_packages = [] # type: List[PackageFilter]
178
- self.formats = [] # type: List[Format]
179
- self.files = {} # type: Dict[str, TemplateFile]
180
- self.extras = [] # type: List[TemplateFile]
181
- self.tdk_config = tdk_config or TDKConfig() # type: TDKConfig
182
- self.loaded_json = loaded_json or OrderedDict() # type: OrderedDict
180
+ self.metamodel_version: int = metamodel_version or METAMODEL_VERSION
181
+ self.allowed_packages: list[PackageFilter] = []
182
+ self.formats: list[Format] = []
183
+ self.files: dict[str, TemplateFile] = {}
184
+ self.extras: list[TemplateFile] = []
185
+ self.tdk_config: TDKConfig = tdk_config or TDKConfig()
186
+ self.loaded_json: OrderedDict = loaded_json or OrderedDict()
183
187
 
184
188
  @property
185
189
  def id(self) -> str:
@@ -200,8 +204,8 @@ class Template:
200
204
  org_id = data['organizationId']
201
205
  tmp_id = data['templateId']
202
206
  version = data['version']
203
- except KeyError:
204
- raise RuntimeError('Cannot retrieve template ID')
207
+ except KeyError as e:
208
+ raise RuntimeError('Cannot retrieve template ID') from e
205
209
  template = Template(
206
210
  template_id=tmp_id,
207
211
  organization_id=org_id,
@@ -244,7 +248,7 @@ class Template:
244
248
  self.loaded_json['_tdk'] = self.tdk_config.serialize()
245
249
  return self.loaded_json
246
250
 
247
- def serialize_remote(self) -> Dict[str, Any]:
251
+ def serialize_remote(self) -> dict[str, Any]:
248
252
  return {
249
253
  'id': self.id,
250
254
  'templateId': self.template_id,
@@ -260,7 +264,7 @@ class Template:
260
264
  'phase': 'DraftDocumentTemplatePhase',
261
265
  }
262
266
 
263
- def serialize_for_update(self) -> Dict[str, Any]:
267
+ def serialize_for_update(self) -> dict[str, Any]:
264
268
  return {
265
269
  'templateId': self.template_id,
266
270
  'version': self.version,
@@ -274,7 +278,7 @@ class Template:
274
278
  'phase': 'DraftDocumentTemplatePhase',
275
279
  }
276
280
 
277
- def serialize_for_create(self, based_on: Optional[str] = None) -> Dict[str, Any]:
281
+ def serialize_for_create(self, based_on: str | None = None) -> dict[str, Any]:
278
282
  return {
279
283
  'basedOn': based_on,
280
284
  'name': self.name,
@@ -282,7 +286,7 @@ class Template:
282
286
  'version': self.version,
283
287
  }
284
288
 
285
- def serialize_local_new(self) -> Dict[str, Any]:
289
+ def serialize_local_new(self) -> dict[str, Any]:
286
290
  return {
287
291
  'templateId': self.template_id,
288
292
  'organizationId': self.organization_id,
@@ -297,23 +301,24 @@ class Template:
297
301
  }
298
302
 
299
303
 
300
- def _to_ordered_dict(tuples: List[Tuple[str, Any]]) -> OrderedDict:
304
+ def _to_ordered_dict(tuples: list[tuple[str, Any]]) -> OrderedDict:
301
305
  return OrderedDict(tuples)
302
306
 
303
307
 
304
308
  class TemplateProject:
305
309
 
306
310
  TEMPLATE_FILE = 'template.json'
307
- DEFAULT_PATTERNS = ['!**/.git/**/*', '!template.json', '!template.zip']
311
+ DEFAULT_PATTERNS = ['!**/.*', '!**/.*/', '!**/~*', '!**/~*/',
312
+ '!template.json', '!template.zip']
308
313
 
309
314
  json_decoder = json.JSONDecoder(object_pairs_hook=_to_ordered_dict)
310
315
 
311
- def __init__(self, template_dir, logger):
312
- self.template_dir = pathlib.Path(template_dir) # type: pathlib.Path
316
+ def __init__(self, template_dir: pathlib.Path, logger: logging.Logger):
317
+ self.template_dir = pathlib.Path(template_dir)
313
318
  self.descriptor_path = self.template_dir / self.TEMPLATE_FILE
314
- self.template = None # type: Optional[Template]
315
- self.used_readme = None # type: Optional[pathlib.Path]
316
- self._logger = logger # type: logging.Logger
319
+ self.template: Template | None = None
320
+ self.used_readme: pathlib.Path | None = None
321
+ self._logger = logger
317
322
 
318
323
  @property
319
324
  def logger(self) -> logging.Logger:
@@ -331,8 +336,8 @@ class TemplateProject:
331
336
  try:
332
337
  content = self.descriptor_path.read_text(encoding=DEFAULT_ENCODING)
333
338
  self.template = Template.load_local(self.json_decoder.decode(content))
334
- except Exception:
335
- raise RuntimeError(f'Unable to load template using {self.descriptor_path}.')
339
+ except Exception as e:
340
+ raise RuntimeError(f'Unable to load template using {self.descriptor_path}.') from e
336
341
 
337
342
  def load_readme(self):
338
343
  readme = self.safe_template.tdk_config.readme_file
@@ -341,7 +346,7 @@ class TemplateProject:
341
346
  self.used_readme = self.template_dir / readme
342
347
  self.safe_template.readme = self.used_readme.read_text(encoding=DEFAULT_ENCODING)
343
348
  except Exception as e:
344
- raise RuntimeWarning(f'README file "{readme}" cannot be loaded: {e}')
349
+ raise RuntimeWarning(f'README file "{readme}" cannot be loaded: {e}') from e
345
350
 
346
351
  def load_file(self, filepath: pathlib.Path) -> TemplateFile:
347
352
  try:
@@ -353,7 +358,7 @@ class TemplateProject:
353
358
  self.safe_template.files[filepath.as_posix()] = tfile
354
359
  return tfile
355
360
  except Exception as e:
356
- raise RuntimeWarning(f'Failed to load template file {filepath}: {e}')
361
+ raise RuntimeWarning(f'Failed to load template file {filepath}: {e}') from e
357
362
 
358
363
  def load_files(self):
359
364
  self.safe_template.files.clear()
@@ -362,22 +367,24 @@ class TemplateProject:
362
367
 
363
368
  @property
364
369
  def files_pathspec(self) -> pathspec.PathSpec:
365
- # TODO: make this more efficient (reload only when tdk_config changes, otherwise cache)
366
370
  patterns = self.safe_template.tdk_config.files + self.DEFAULT_PATTERNS
367
- return pathspec.PathSpec.from_lines(PATHSPEC_FACTORY, patterns)
371
+ return pathspec.PathSpec.from_lines(PathspecFactory, patterns)
368
372
 
369
- def list_files(self) -> List[pathlib.Path]:
370
- files = (pathlib.Path(p) for p in self.files_pathspec.match_tree_files(str(self.template_dir)))
373
+ def list_files(self) -> list[pathlib.Path]:
374
+ files = (pathlib.Path(p)
375
+ for p in self.files_pathspec.match_tree_files(str(self.template_dir)))
371
376
  if self.used_readme is not None:
372
377
  return list(p for p in files if p != self.used_readme.relative_to(self.template_dir))
373
378
  return list(files)
374
379
 
375
- def _relative_paths_eq(self, filepath1: Optional[pathlib.Path], filepath2: Optional[pathlib.Path]) -> bool:
380
+ def _relative_paths_eq(self, filepath1: pathlib.Path | None,
381
+ filepath2: pathlib.Path | None) -> bool:
376
382
  if filepath1 is None or filepath2 is None:
377
383
  return False
378
384
  return filepath1.relative_to(self.template_dir) == filepath2.relative_to(self.template_dir)
379
385
 
380
- def is_template_file(self, filepath: pathlib.Path, include_descriptor: bool = False, include_readme: bool = False):
386
+ def is_template_file(self, filepath: pathlib.Path, include_descriptor: bool = False,
387
+ include_readme: bool = False):
381
388
  if include_readme and self._relative_paths_eq(filepath, self.used_readme):
382
389
  return True
383
390
  if include_descriptor and self._relative_paths_eq(filepath, self.descriptor_path):
@@ -400,7 +407,7 @@ class TemplateProject:
400
407
  filename = tfile.filename.as_posix()
401
408
  self.safe_template.files[filename] = tfile
402
409
 
403
- def get_template_file(self, filepath: pathlib.Path) -> Optional[TemplateFile]:
410
+ def get_template_file(self, filepath: pathlib.Path) -> TemplateFile | None:
404
411
  if filepath.is_absolute():
405
412
  filepath = filepath.relative_to(self.template_dir)
406
413
  return self.safe_template.files.get(filepath.as_posix(), None)
@@ -419,7 +426,10 @@ class TemplateProject:
419
426
  def store_descriptor(self, force: bool):
420
427
  self._write_file(
421
428
  filepath=self.descriptor_path,
422
- contents=json.dumps(self.safe_template.serialize_local(), indent=4).encode(encoding=DEFAULT_ENCODING),
429
+ contents=json.dumps(
430
+ obj=self.safe_template.serialize_local(),
431
+ indent=4
432
+ ).encode(encoding=DEFAULT_ENCODING),
423
433
  force=force,
424
434
  )
425
435
 
@@ -1,7 +1,6 @@
1
1
  {%- raw -%}
2
2
  {# This is the template starter file generated by DSW TDK #}
3
- {%- set km = ctx.knowledgeModel -%}
4
- {%- set repliesMap = ctx.questionnaireReplies -%}
3
+ {%- set dc = ctx|to_context_obj -%}
5
4
 
6
5
  {#
7
6
  ##
dsw/tdk/utils.py CHANGED
@@ -1,8 +1,7 @@
1
- import jinja2 # type: ignore
2
1
  import pathlib
3
2
  import uuid
4
3
 
5
- from typing import List, Set, Optional
4
+ import jinja2
6
5
 
7
6
  from .consts import DEFAULT_ENCODING, DEFAULT_README
8
7
  from .model import Template, TemplateFile, Format, Step, PackageFilter
@@ -20,10 +19,10 @@ j2_env = jinja2.Environment(
20
19
 
21
20
  class UUIDGen:
22
21
 
23
- _uuids = set() # type: Set[uuid.UUID]
22
+ _uuids: set[uuid.UUID] = set()
24
23
 
25
24
  @classmethod
26
- def used(cls) -> Set[uuid.UUID]:
25
+ def used(cls) -> set[uuid.UUID]:
27
26
  return cls._uuids
28
27
 
29
28
  @classmethod
@@ -91,10 +90,10 @@ class TemplateBuilder:
91
90
 
92
91
  def __init__(self):
93
92
  self.template = Template()
94
- self._formats = [] # type: List[FormatSpec]
93
+ self._formats: list[FormatSpec] = []
95
94
 
96
95
  @property
97
- def formats(self) -> List[FormatSpec]:
96
+ def formats(self) -> list[FormatSpec]:
98
97
  return self._formats
99
98
 
100
99
  def _validate_field(self, field_name: str):
@@ -177,13 +176,13 @@ class TemplateBuilder:
177
176
  license_file = j2_env.get_template('LICENSE.j2').render(template=self.template)
178
177
  self.template.tdk_config.files.append('LICENSE')
179
178
  self.template.files['LICENSE'] = TemplateFile(
180
- filename='LICENSE',
179
+ filename=pathlib.Path('LICENSE'),
181
180
  content_type='text/plain',
182
181
  content=license_file.encode(encoding=DEFAULT_ENCODING),
183
182
  )
184
183
 
185
184
  self.template.files['.env'] = TemplateFile(
186
- filename='.env',
185
+ filename=pathlib.Path('.env'),
187
186
  content_type='text/plain',
188
187
  content=create_dot_env().encode(encoding=DEFAULT_ENCODING),
189
188
  )
@@ -191,7 +190,7 @@ class TemplateBuilder:
191
190
  return self.template
192
191
 
193
192
 
194
- def create_dot_env(api_url: Optional[str] = None, api_key: Optional[str] = None) -> str:
193
+ def create_dot_env(api_url: str | None = None, api_key: str | None = None) -> str:
195
194
  return j2_env.get_template('env.j2').render(api_url=api_url, api_key=api_key)
196
195
 
197
196
 
dsw/tdk/validation.py CHANGED
@@ -15,55 +15,82 @@ class ValidationError(BaseException):
15
15
 
16
16
  def _validate_required(field_name: str, value) -> List[ValidationError]:
17
17
  if value is None:
18
- return [ValidationError(field_name, 'Missing but it is required')]
18
+ return [ValidationError(
19
+ field_name=field_name,
20
+ message='Missing but it is required',
21
+ )]
19
22
  return []
20
23
 
21
24
 
22
25
  def _validate_non_empty(field_name: str, value) -> List[ValidationError]:
23
26
  if value is not None and len(value.strip()) == 0:
24
- return [ValidationError(field_name, 'Cannot be empty or only-whitespace')]
27
+ return [ValidationError(
28
+ field_name=field_name,
29
+ message='Cannot be empty or only-whitespace',
30
+ )]
25
31
  return []
26
32
 
27
33
 
28
34
  def _validate_content_type(field_name: str, value) -> List[ValidationError]:
29
35
  if value is not None and re.match(REGEX_MIME_TYPE, value) is None:
30
- return [ValidationError(field_name, 'Content type should be valid IANA media type')]
36
+ return [ValidationError(
37
+ field_name=field_name,
38
+ message='Content type should be valid IANA media type',
39
+ )]
31
40
  return []
32
41
 
33
42
 
34
43
  def _validate_extension(field_name: str, value) -> List[ValidationError]:
35
44
  if value is not None and re.match(REGEX_ORGANIZATION_ID, value) is None:
36
- return [ValidationError(field_name, 'File extension should contain only letters, numbers and dots (inside-only)')]
45
+ return [ValidationError(
46
+ field_name=field_name,
47
+ message='File extension should contain only letters, numbers and dots (inside-only)',
48
+ )]
37
49
  return []
38
50
 
39
51
 
40
52
  def _validate_organization_id(field_name: str, value) -> List[ValidationError]:
41
53
  if value is not None and re.match(REGEX_ORGANIZATION_ID, value) is None:
42
- return [ValidationError(field_name, 'Organization ID may contain only letters, numbers, and period (inside-only)')]
54
+ return [ValidationError(
55
+ field_name=field_name,
56
+ message='Organization ID may contain only letters, numbers, and period (inside-only)',
57
+ )]
43
58
  return []
44
59
 
45
60
 
46
61
  def _validate_template_id(field_name: str, value) -> List[ValidationError]:
47
62
  if value is not None and re.match(REGEX_TEMPLATE_ID, value) is None:
48
- return [ValidationError(field_name, 'Template ID may contain only letters, numbers, and dash (inside-only)')]
63
+ return [ValidationError(
64
+ field_name=field_name,
65
+ message='Template ID may contain only letters, numbers, and dash (inside-only)',
66
+ )]
49
67
  return []
50
68
 
51
69
 
52
70
  def _validate_km_id(field_name: str, value) -> List[ValidationError]:
53
71
  if value is not None and re.match(REGEX_KM_ID, value) is None:
54
- return [ValidationError(field_name, 'KM ID may contain only letters, numbers, and dash (inside-only)')]
72
+ return [ValidationError(
73
+ field_name=field_name,
74
+ message='KM ID may contain only letters, numbers, and dash (inside-only)',
75
+ )]
55
76
  return []
56
77
 
57
78
 
58
79
  def _validate_version(field_name: str, value) -> List[ValidationError]:
59
80
  if value is not None and re.match(REGEX_SEMVER, value) is None:
60
- return [ValidationError(field_name, 'Version must be in semver format <NUM>.<NUM>.<NUM>')]
81
+ return [ValidationError(
82
+ field_name=field_name,
83
+ message='Version must be in semver format <NUM>.<NUM>.<NUM>',
84
+ )]
61
85
  return []
62
86
 
63
87
 
64
88
  def _validate_natural(field_name: str, value) -> List[ValidationError]:
65
89
  if value is not None and (not isinstance(value, int) or value < 1):
66
- return [ValidationError(field_name, 'It must be positive integer')]
90
+ return [ValidationError(
91
+ field_name=field_name,
92
+ message='It must be positive integer',
93
+ )]
67
94
  return []
68
95
 
69
96
 
@@ -72,16 +99,31 @@ def _validate_package_id(field_name: str, value: str) -> List[ValidationError]:
72
99
  if value is None:
73
100
  return res
74
101
  if not isinstance(value, str):
75
- return [ValidationError(field_name, 'Package ID is not a string')]
102
+ return [ValidationError(
103
+ field_name=field_name,
104
+ message='Package ID is not a string',
105
+ )]
76
106
  parts = value.split(':')
77
107
  if len(parts) != 3:
78
- res.append(ValidationError(field_name, 'Package ID is not valid (only {len(parts)} parts)'))
108
+ res.append(ValidationError(
109
+ field_name=field_name,
110
+ message='Package ID is not valid (only {len(parts)} parts)',
111
+ ))
79
112
  if re.match(REGEX_ORGANIZATION_ID, parts[0]) is None:
80
- res.append(ValidationError(field_name, 'Package ID contains invalid organization id'))
113
+ res.append(ValidationError(
114
+ field_name=field_name,
115
+ message='Package ID contains invalid organization id',
116
+ ))
81
117
  if re.match(REGEX_KM_ID, parts[1]) is None:
82
- res.append(ValidationError(field_name, 'Package ID contains invalid KM id'))
118
+ res.append(ValidationError(
119
+ field_name=field_name,
120
+ message='Package ID contains invalid KM id',
121
+ ))
83
122
  if re.match(REGEX_SEMVER, parts[2]) is None:
84
- res.append(ValidationError(field_name, 'Package ID contains invalid version'))
123
+ res.append(ValidationError(
124
+ field_name=field_name,
125
+ message='Package ID contains invalid version',
126
+ ))
85
127
  return res
86
128
 
87
129
 
@@ -91,11 +133,20 @@ def _validate_jinja_options(field_name: str, value: Dict[str, str]) -> List[Vali
91
133
  return res
92
134
  for k in ('template', 'content-type', 'extension'):
93
135
  if k not in value.keys():
94
- res.append(ValidationError(field_name, 'Jinja option cannot be left out'))
136
+ res.append(ValidationError(
137
+ field_name=field_name,
138
+ message='Jinja option cannot be left out',
139
+ ))
95
140
  elif value[k] is None or not isinstance(value[k], str) or len(value[k]) == 0:
96
- res.append(ValidationError(field_name, 'Jinja option cannot be empty'))
141
+ res.append(ValidationError(
142
+ field_name=field_name,
143
+ message='Jinja option cannot be empty',
144
+ ))
97
145
  if 'content-type' in value.keys():
98
- res.extend(_validate_content_type(f'{field_name}.content-type', value['content-type']))
146
+ res.extend(_validate_content_type(
147
+ field_name=f'{field_name}.content-type',
148
+ value=value['content-type'],
149
+ ))
99
150
  return res
100
151
 
101
152
 
@@ -129,7 +180,10 @@ class GenericValidator:
129
180
  if field_name.startswith('__'):
130
181
  continue
131
182
  for validator in validators:
132
- result.extend(validator(field_name_prefix + field_name, getattr(entity, field_name)))
183
+ result.extend(validator(
184
+ field_name=f'{field_name_prefix}{field_name}',
185
+ value=getattr(entity, field_name),
186
+ ))
133
187
  if '__all' in self.rules.keys():
134
188
  result.extend(self.rules['__all'](field_name_prefix, entity))
135
189
  return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsw-tdk
3
- Version: 4.12.0
3
+ Version: 4.14.0
4
4
  Summary: Data Stewardship Wizard Template Development Toolkit
5
5
  Author-email: Marek Suchánek <marek.suchanek@ds-wizard.org>
6
6
  License: Apache License 2.0
@@ -12,12 +12,12 @@ Classifier: Framework :: AsyncIO
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: License :: OSI Approved :: Apache Software License
14
14
  Classifier: Programming Language :: Python
15
- Classifier: Programming Language :: Python :: 3.9
16
15
  Classifier: Programming Language :: Python :: 3.10
17
16
  Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
18
  Classifier: Topic :: Internet :: WWW/HTTP
19
19
  Classifier: Topic :: Utilities
20
- Requires-Python: <4,>=3.9
20
+ Requires-Python: <4,>=3.10
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
23
  Requires-Dist: aiohttp
@@ -0,0 +1,20 @@
1
+ dsw/tdk/__init__.py,sha256=zJeTybb0SqiNdGLkANjRa36hku4axi17mZL2dM3tHto,288
2
+ dsw/tdk/__main__.py,sha256=cCzxo6f7raF50kQE-nM_segNjCNe723ZrxOBB6f3qwc,84
3
+ dsw/tdk/api_client.py,sha256=1WpUSgi8BfNrq3rUHWSfcZnmNGydID1mzkWBp5TnNmc,14727
4
+ dsw/tdk/build_info.py,sha256=xBZ1XqKVizhNtN7VHteBe1AGMyK4GwZrZQtrNx-EZz8,381
5
+ dsw/tdk/cli.py,sha256=7OYoGvceSd2TuyeRXFv7ikylJNKFk3Ua8t9l_Vas12E,22012
6
+ dsw/tdk/consts.py,sha256=WwGlNfUF50WmQZQwyRDRPufOAXwwABjJuF2lkTU9VMM,619
7
+ dsw/tdk/core.py,sha256=LvpB8J_AmAe-ljEIYjO3oP45EDAgjzKGEnZkkDqNiho,26448
8
+ dsw/tdk/model.py,sha256=5_qSOEdEeikskvoThClPQU2szS3pDw8-R2kDQVdBf7U,17151
9
+ dsw/tdk/utils.py,sha256=ICZpgxkDRWg9lq1gnHyQCEISFMtmGtu8Hl5yEclwn14,5685
10
+ dsw/tdk/validation.py,sha256=6GTyBpSvrvj73A2RkFJ-NL7SCjXFI4JnPneAEumR-ww,8847
11
+ dsw/tdk/templates/LICENSE.j2,sha256=6WzK06169rxZ4V_boYgejcZkw-1Up_WoU18iI3Gbkfs,60
12
+ dsw/tdk/templates/README.md.j2,sha256=FzUABeMM8To0oT48Kytoox64uAZ8F7FSAAXgpyKzqdU,247
13
+ dsw/tdk/templates/env.j2,sha256=7IJ6HAIY1bXKLake4c72DSEUcQtAquO5wlSgH8vg_8s,97
14
+ dsw/tdk/templates/starter.j2,sha256=JKJIkiXsmBO4P6pKXM4IvSz3JgJhqCnaZI1NVfPPnXg,246
15
+ dsw_tdk-4.14.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
+ dsw_tdk-4.14.0.dist-info/METADATA,sha256=1CXbl6itGPeaQ2wm-GTEzEg52J6J602oJG0pi_rnBIk,6022
17
+ dsw_tdk-4.14.0.dist-info/WHEEL,sha256=M1ikteR9eetPNvm1LyQ3rpXxNYuGd90oakQO1a-ohSk,109
18
+ dsw_tdk-4.14.0.dist-info/entry_points.txt,sha256=lwD5ZzRCbTFSjP1-SkhYsaJe8sEXOWWgMAMUhw0v2Hk,41
19
+ dsw_tdk-4.14.0.dist-info/top_level.txt,sha256=7SfbsHFoJ_vlAgG6C-xzETETwYO71dBrGnod8uMFnjw,4
20
+ dsw_tdk-4.14.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: setuptools (75.7.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -1,20 +0,0 @@
1
- dsw/tdk/__init__.py,sha256=zJeTybb0SqiNdGLkANjRa36hku4axi17mZL2dM3tHto,288
2
- dsw/tdk/__main__.py,sha256=IkqeOatxravhcQCdk4l0BkbaMILkgVopB9phYCIR1uo,38
3
- dsw/tdk/api_client.py,sha256=N3-PoO__kPtqFmR2QY-OG-9OkjYZwuXg8JxcBgpI8vQ,14222
4
- dsw/tdk/build_info.py,sha256=tppWzn16SBK4k6X9Kb1tcx2_lK7t2IXi0_N9QmbdW1s,381
5
- dsw/tdk/cli.py,sha256=_DZRSAo04wajiWVTod6lPdh477Rdxf7zBomySPxiL1c,21676
6
- dsw/tdk/consts.py,sha256=40HjoDQ4bX5X4G9JYhZ7jPbWI6Xj6NBCeXMTWJPENmQ,635
7
- dsw/tdk/core.py,sha256=Tyv2KXgBlm9mbJqFMaeyn6-07JE1nPHbKWTIKAvu2XY,25970
8
- dsw/tdk/model.py,sha256=B9_cCmg_Z2IHabMMychKFV4dh4SFPVEentuPcb5fzlY,17235
9
- dsw/tdk/utils.py,sha256=gW_-1qj7osHgKhTjjMGeVL2pxoBDQuq7VjRE6OmEMCw,5734
10
- dsw/tdk/validation.py,sha256=hr04MRVqwBIBeKoX6v53Ix1S-vjvIQYM5dwI0SnMRsc,7827
11
- dsw/tdk/templates/LICENSE.j2,sha256=6WzK06169rxZ4V_boYgejcZkw-1Up_WoU18iI3Gbkfs,60
12
- dsw/tdk/templates/README.md.j2,sha256=FzUABeMM8To0oT48Kytoox64uAZ8F7FSAAXgpyKzqdU,247
13
- dsw/tdk/templates/env.j2,sha256=7IJ6HAIY1bXKLake4c72DSEUcQtAquO5wlSgH8vg_8s,97
14
- dsw/tdk/templates/starter.j2,sha256=XjZy3T9i8aWFlq4clXL6Q4JNh455crGelR9AoHisTbw,296
15
- dsw_tdk-4.12.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
- dsw_tdk-4.12.0.dist-info/METADATA,sha256=ldEae9hLRn_sVciIFiUTULYaCeqpoSaqsp6ElbqvoCQ,6020
17
- dsw_tdk-4.12.0.dist-info/WHEEL,sha256=OpXWERl2xLPRHTvd2ZXo_iluPEQd8uSbYkJ53NAER_Y,109
18
- dsw_tdk-4.12.0.dist-info/entry_points.txt,sha256=lwD5ZzRCbTFSjP1-SkhYsaJe8sEXOWWgMAMUhw0v2Hk,41
19
- dsw_tdk-4.12.0.dist-info/top_level.txt,sha256=7SfbsHFoJ_vlAgG6C-xzETETwYO71dBrGnod8uMFnjw,4
20
- dsw_tdk-4.12.0.dist-info/RECORD,,