tiferet 1.0.0a7__py3-none-any.whl → 1.0.0a9__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.
tiferet/clients/yaml.py CHANGED
@@ -77,16 +77,25 @@ def save(yaml_file: str, data: dict, data_save_path: str = None):
77
77
 
78
78
  # If the new yaml data does not exist, create it from the yaml data.
79
79
  except TypeError:
80
- new_yaml_data = yaml_data[fragment]
81
- continue
82
-
83
- # If the fragment does not exist on
80
+ try:
81
+ new_yaml_data = yaml_data[fragment]
82
+ continue
83
+
84
+ # If the fragment does not exist, create it.
85
+ except KeyError:
86
+ new_yaml_data = yaml_data[fragment] = {}
87
+
88
+ # If the fragment does not exist, create it.
84
89
  except KeyError:
85
90
  new_yaml_data[fragment] = {}
86
91
  new_yaml_data = new_yaml_data[fragment]
87
92
 
88
93
  # Update the yaml data.
89
- new_yaml_data[save_path_list[-1]] = data
94
+ try:
95
+ new_yaml_data[save_path_list[-1]] = data
96
+ # if there is a type error because the new yaml data is None, update the yaml data directly.
97
+ except TypeError:
98
+ yaml_data[save_path_list[-1]] = data
90
99
 
91
100
  # Save the updated yaml data.
92
101
  with open(yaml_file, 'w') as file:
@@ -1,4 +1,3 @@
1
1
  from .app import AppInterfaceContext
2
- from .env import EnvironmentContext
3
2
  from .request import RequestContext
4
3
  from .error import ErrorContext
tiferet/contexts/app.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # *** imports
2
2
 
3
3
  # ** core
4
- from typing import Any
4
+ from typing import Any, Tuple
5
5
 
6
6
  # ** app
7
7
  from .request import RequestContext
@@ -14,13 +14,24 @@ from ..domain import *
14
14
 
15
15
  # ** context: app_interface_context
16
16
  class AppInterfaceContext(Model):
17
+ '''
18
+ The application interface context is a class that is used to create and run the application interface.
19
+ '''
20
+
21
+ # * attribute: interface_id
22
+ interface_id = StringType(
23
+ required=True,
24
+ metadata=dict(
25
+ description='The interface ID.'
26
+ ),
27
+ )
17
28
 
18
29
  # * attribute: name
19
30
  name = StringType(
20
31
  required=True,
21
32
  metadata=dict(
22
33
  description='The application name.'
23
- )
34
+ ),
24
35
  )
25
36
 
26
37
  # * field: features
@@ -29,7 +40,7 @@ class AppInterfaceContext(Model):
29
40
  required=True,
30
41
  metadata=dict(
31
42
  description='The feature context.'
32
- )
43
+ ),
33
44
  )
34
45
 
35
46
  # * field: errors
@@ -38,14 +49,16 @@ class AppInterfaceContext(Model):
38
49
  required=True,
39
50
  metadata=dict(
40
51
  description='The error context.'
41
- )
52
+ ),
42
53
  )
43
54
 
44
55
  # * method: init
45
- def __init__(self, app_name: str, feature_context: FeatureContext, error_context: ErrorContext):
56
+ def __init__(self, interface_id: str, app_name: str, feature_context: FeatureContext, error_context: ErrorContext):
46
57
  '''
47
58
  Initialize the application interface context.
48
59
 
60
+ :param interface_id: The interface ID.
61
+ :type interface_id: str
49
62
  :param app_name: The application name.
50
63
  :type app_name: str
51
64
  :param feature_context: The feature context.
@@ -56,13 +69,14 @@ class AppInterfaceContext(Model):
56
69
 
57
70
  # Initialize the model.
58
71
  super().__init__(dict(
59
- name=app_name,
60
- features=feature_context,
61
- errors=error_context
72
+ interface_id=interface_id,
73
+ name=app_name
62
74
  ))
75
+ self.features = feature_context
76
+ self.errors = error_context
63
77
 
64
78
  # * method: parse_request
65
- def parse_request(self, request: Any, **kwargs) -> RequestContext:
79
+ def parse_request(self, request: Any, **kwargs) -> Tuple[RequestContext, dict]:
66
80
  '''
67
81
  Parse the incoming request.
68
82
 
@@ -75,7 +89,7 @@ class AppInterfaceContext(Model):
75
89
  '''
76
90
 
77
91
  # Parse request.
78
- return request
92
+ return request, kwargs
79
93
 
80
94
  # * method: execute_feature
81
95
  def execute_feature(self, request: RequestContext, **kwargs):
@@ -116,7 +130,7 @@ class AppInterfaceContext(Model):
116
130
  '''
117
131
 
118
132
  # Parse request.
119
- request = self.parse_request(**kwargs)
133
+ request, kwargs = self.parse_request(**kwargs)
120
134
 
121
135
  # Execute feature context and return session.
122
136
  # Handle error and return response if triggered.
@@ -86,17 +86,21 @@ class ContainerContext(Model):
86
86
 
87
87
  # Add the attributes to the context.
88
88
  for attr in attrs:
89
- attribute: ContainerAttribute = attributes[attr.id]
90
-
89
+
91
90
  # If the attribute already exists, set the dependencies.
92
91
  if attr.id in attributes:
93
92
  for dep in attr.dependencies:
94
- attribute.set_dependency(dep)
93
+ attr.set_dependency(dep)
95
94
  continue
96
95
 
97
96
  # Otherwise, add the attribute.
98
97
  attributes[attr.id] = attr
99
98
 
99
+ # Add any parameters as constants.
100
+ for dep in attr.dependencies:
101
+ for key in dep.parameters:
102
+ consts[key] = dep.parameters[key]
103
+
100
104
  # Add the constants and attributes to the context.
101
105
  super().__init__(dict(
102
106
  interface_id=interface_id,
@@ -145,7 +149,7 @@ class ContainerContext(Model):
145
149
  dependencies[attribute_id] = self.import_dependency(attribute, flag_map[attribute.type])
146
150
 
147
151
  # Create container.
148
- return container_service.create_injector(self,
152
+ return container_service.create_injector(
149
153
  self.interface_id,
150
154
  **self.constants,
151
155
  **dependencies,
@@ -45,10 +45,12 @@ class FeatureContext(Model):
45
45
  features = {feature.id: feature for feature in feature_repo.list()}
46
46
 
47
47
  # Set the features and container.
48
+ ## NOTE: There is a bug in the schematics library that does not allow us to initialize
49
+ ## the feature context with the container context directly.
48
50
  super().__init__(dict(
49
51
  features=features,
50
- container=container_context,
51
52
  ))
53
+ self.container = container_context
52
54
 
53
55
  # * method: execute
54
56
  def execute(self, request: RequestContext, debug: bool = False, **kwargs):
@@ -75,16 +77,21 @@ class FeatureContext(Model):
75
77
  result = handler.execute(
76
78
  **request.data,
77
79
  **command.params,
80
+ debug=debug,
78
81
  **kwargs)
82
+
83
+ # Return the result to the session context if return to data is set.
84
+ if command.return_to_data:
85
+ request.data[command.data_key] = result
86
+ continue
87
+
88
+ # Set the result in the request context.
89
+ if result:
90
+ request.set_result(result)
91
+
92
+ # Handle assertion errors if pass on error is not set.
79
93
  except AssertionError as e:
80
94
  if not command.pass_on_error:
81
95
  raise e
82
96
 
83
- # Return the result to the session context if return to data is set.
84
- if command.return_to_data:
85
- request.data[command.data_key] = result
86
- continue
87
-
88
- # Set the result in the request context.
89
- if result:
90
- request.set_result(result)
97
+
@@ -62,9 +62,11 @@ class RequestContext(Model):
62
62
  '''
63
63
 
64
64
  # Set the context attributes.
65
- self.feature_id = feature_id
66
- self.headers = headers
67
- self.data = data
65
+ super().__init__(dict(
66
+ feature_id=feature_id,
67
+ headers=headers,
68
+ data=data
69
+ ))
68
70
 
69
71
  # Validate the context.
70
72
  self.validate()
@@ -92,7 +94,7 @@ class RequestContext(Model):
92
94
  return
93
95
 
94
96
  # If the result is not a list, it must be a dict, so serialize it and set it.
95
- if type(self.result) != list:
97
+ if type(result) != list:
96
98
  self.result = json.dumps(result)
97
99
  return
98
100
 
tiferet/data/__init__.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from typing import List, Dict
2
2
 
3
3
  from .error import *
4
- from .feature import *
4
+ from .feature import *
5
+ from .app import *
tiferet/data/app.py CHANGED
@@ -9,6 +9,50 @@ from ..domain import DataObject
9
9
  from ..domain.app import AppDependency, AppInterface, AppRepositoryConfiguration
10
10
 
11
11
 
12
+ # *** constants
13
+
14
+ # ** constant: app_dependency_default
15
+ FEATURE_CONTEXT_DEFAULT = dict(
16
+ module_path='tiferet.contexts.feature',
17
+ class_name='FeatureContext',
18
+ )
19
+
20
+ # * constant: app_dependency_default
21
+ CONTAINER_CONTEXT_DEFAULT = dict(
22
+ module_path='tiferet.contexts.container',
23
+ class_name='ContainerContext',
24
+ )
25
+
26
+ ERROR_CONTEXT_DEFAULT = dict(
27
+ module_path='tiferet.contexts.error',
28
+ class_name='ErrorContext',
29
+ )
30
+
31
+ FEATURE_REPO_DEFAULT = dict(
32
+ module_path='tiferet.repos.feature',
33
+ class_name='YamlProxy',
34
+ )
35
+
36
+ CONTAINER_REPO_DEFAULT = dict(
37
+ module_path='tiferet.repos.container',
38
+ class_name='YamlProxy',
39
+ )
40
+
41
+ ERROR_REPO_DEFAULT = dict(
42
+ module_path='tiferet.repos.error',
43
+ class_name='YamlProxy',
44
+ )
45
+
46
+ # ** constant: context_list_default
47
+ CONTEXT_LIST_DEFAULT = {
48
+ 'feature_context': FEATURE_CONTEXT_DEFAULT,
49
+ 'container_context': CONTAINER_CONTEXT_DEFAULT,
50
+ 'error_context': ERROR_CONTEXT_DEFAULT,
51
+ 'feature_repo': FEATURE_REPO_DEFAULT,
52
+ 'container_repo': CONTAINER_REPO_DEFAULT,
53
+ 'error_repo': ERROR_REPO_DEFAULT,
54
+ }
55
+
12
56
  # *** data
13
57
 
14
58
  # ** data: app_dependency_yaml_data
@@ -34,9 +78,27 @@ class AppDependencyYamlData(AppDependency, DataObject):
34
78
  'to_data.yaml': DataObject.deny('attribute_id')
35
79
  }
36
80
 
81
+ # * method: from_data
82
+ @staticmethod
83
+ def from_data(**kwargs) -> 'AppDependencyYamlData':
84
+ '''
85
+ Initializes a new YAML representation of an AppDependency object.
86
+
87
+ :param kwargs: Additional keyword arguments.
88
+ :type kwargs: dict
89
+ :return: A new AppDependencyData object.
90
+ :rtype: AppDependencyData
91
+ '''
92
+
93
+ # Create a new AppDependencyData object.
94
+ return super(AppDependencyYamlData, AppDependencyYamlData).from_data(
95
+ AppDependencyYamlData,
96
+ **kwargs
97
+ )
98
+
37
99
  # * method: new
38
100
  @staticmethod
39
- def new(**kwargs) -> 'AppDependencyYamlData':
101
+ def from_data(**kwargs) -> 'AppDependencyYamlData':
40
102
  '''
41
103
  Initializes a new YAML representation of an AppDependency object.
42
104
 
@@ -47,11 +109,11 @@ class AppDependencyYamlData(AppDependency, DataObject):
47
109
  '''
48
110
 
49
111
  # Create a new AppDependencyData object.
50
- return AppDependencyYamlData(
51
- dict(**kwargs),
52
- strict=False,
112
+ return super(AppDependencyYamlData, AppDependencyYamlData).from_data(
113
+ AppDependencyYamlData,
114
+ **kwargs
53
115
  )
54
-
116
+
55
117
  # * method: map
56
118
  def map(self, **kwargs) -> AppDependency:
57
119
  '''
@@ -67,7 +129,7 @@ class AppDependencyYamlData(AppDependency, DataObject):
67
129
 
68
130
  # Map the app dependency data.
69
131
  return super().map(AppDependency, **kwargs)
70
-
132
+
71
133
 
72
134
  # ** data: app_interface_yaml_data
73
135
  class AppInterfaceYamlData(AppInterface, DataObject):
@@ -82,7 +144,7 @@ class AppInterfaceYamlData(AppInterface, DataObject):
82
144
  serialize_when_none = False
83
145
  roles = {
84
146
  'to_model': DataObject.deny('app_context', 'container_context', 'feature_context', 'error_context', 'feature_repo', 'container_repo', 'error_repo'),
85
- 'to_data.yaml': DataObject.deny('id')
147
+ 'to_data': DataObject.deny('id')
86
148
  }
87
149
 
88
150
  # attribute: app_context
@@ -98,11 +160,6 @@ class AppInterfaceYamlData(AppInterface, DataObject):
98
160
  feature_context = ModelType(
99
161
  AppDependencyYamlData,
100
162
  required=True,
101
- default=AppDependencyYamlData.new(
102
- attribute_id='feature_context',
103
- module_path='tiferet.contexts.feature',
104
- class_name='FeatureContext',
105
- ),
106
163
  metadata=dict(
107
164
  description='The feature context dependency.'
108
165
  ),
@@ -112,11 +169,6 @@ class AppInterfaceYamlData(AppInterface, DataObject):
112
169
  container_context = ModelType(
113
170
  AppDependencyYamlData,
114
171
  required=True,
115
- default=AppDependencyYamlData.new(
116
- attribute_id='container_context',
117
- module_path='tiferet.contexts.container',
118
- class_name='ContainerContext',
119
- ),
120
172
  metadata=dict(
121
173
  description='The container context dependency.'
122
174
  ),
@@ -126,11 +178,6 @@ class AppInterfaceYamlData(AppInterface, DataObject):
126
178
  error_context = ModelType(
127
179
  AppDependencyYamlData,
128
180
  required=True,
129
- default=AppDependencyYamlData.new(
130
- attribute_id='error_context',
131
- module_path='tiferet.contexts.error',
132
- class_name='ErrorContext',
133
- ),
134
181
  metadata=dict(
135
182
  description='The error context dependency.'
136
183
  ),
@@ -140,11 +187,6 @@ class AppInterfaceYamlData(AppInterface, DataObject):
140
187
  feature_repo = ModelType(
141
188
  AppDependencyYamlData,
142
189
  required=True,
143
- default=AppDependencyYamlData.new(
144
- attribute_id='feature_repo',
145
- module_path='tiferet.repos.feature',
146
- class_name='YamlProxy',
147
- ),
148
190
  metadata=dict(
149
191
  description='The feature repository dependency.'
150
192
  ),
@@ -154,11 +196,6 @@ class AppInterfaceYamlData(AppInterface, DataObject):
154
196
  container_repo = ModelType(
155
197
  AppDependencyYamlData,
156
198
  required=True,
157
- default=AppDependencyYamlData.new(
158
- attribute_id='container_repo',
159
- module_path='tiferet.repos.container',
160
- class_name='YamlProxy',
161
- ),
162
199
  metadata=dict(
163
200
  description='The container repository dependency.'
164
201
  ),
@@ -168,11 +205,6 @@ class AppInterfaceYamlData(AppInterface, DataObject):
168
205
  error_repo = ModelType(
169
206
  AppDependencyYamlData,
170
207
  required=True,
171
- default=AppDependencyYamlData.new(
172
- attribute_id='error_repo',
173
- module_path='tiferet.repos.error',
174
- class_name='YamlProxy',
175
- ),
176
208
  metadata=dict(
177
209
  description='The error repository dependency.'
178
210
  ),
@@ -180,14 +212,8 @@ class AppInterfaceYamlData(AppInterface, DataObject):
180
212
 
181
213
  # * method: new
182
214
  @staticmethod
183
- def new(app_context: Dict[str, str],
184
- container_context: Dict[str, str] = None,
185
- feature_context: Dict[str, str] = None,
186
- error_context: Dict[str, str] = None,
187
- feature_repo: Dict[str, str] = None,
188
- container_repo: Dict[str, str] = None,
189
- error_repo: Dict[str, str] = None,
190
- **kwargs) -> 'AppInterfaceYamlData':
215
+ def from_data(app_context: Dict[str, str],
216
+ **kwargs) -> 'AppInterfaceYamlData':
191
217
  '''
192
218
  Initializes a new YAML representation of an AppInterface object.
193
219
 
@@ -197,34 +223,36 @@ class AppInterfaceYamlData(AppInterface, DataObject):
197
223
  :rtype: AppInterfaceData
198
224
  '''
199
225
 
200
- # Format the dependencies.
201
- dependencies = {}
202
- if app_context:
203
- dependencies['app_context'] = AppDependencyYamlData.new(attribute_id='app_context', **app_context)
204
- if container_context:
205
- dependencies['container_context'] = AppDependencyYamlData.new(attribute_id='container_context', **container_context)
206
- if feature_context:
207
- dependencies['feature_context'] = AppDependencyYamlData.new(attribute_id='feature_context', **feature_context)
208
- if error_context:
209
- dependencies['error_context'] = AppDependencyYamlData.new(attribute_id='error_context', **error_context)
210
- if feature_repo:
211
- dependencies['feature_repo'] = AppDependencyYamlData.new(attribute_id='feature_repo', **feature_repo)
212
- if container_repo:
213
- dependencies['container_repo'] = AppDependencyYamlData.new(attribute_id='container_repo', **container_repo)
214
- if error_repo:
215
- dependencies['error_repo'] = AppDependencyYamlData.new(attribute_id='error_repo', **error_repo)
226
+ # Add the app context to the dependencies.
227
+ dependencies = dict(
228
+ app_context=AppDependencyYamlData.from_data(
229
+ attribute_id='app_context',
230
+ **app_context
231
+ )
232
+ )
233
+
234
+ # Going through the default dependencies...
235
+ for key, value in CONTEXT_LIST_DEFAULT.items():
236
+
237
+ # If the key is in the kwargs, add it and continue.
238
+ if key in kwargs:
239
+ dependencies[key] = AppDependencyYamlData.from_data(
240
+ attribute_id=key,
241
+ **kwargs.pop(key)) # Pop the key to avoid duplication.
242
+ continue
243
+
244
+ # Otherwise, add the default value.
245
+ dependencies[key] = AppDependencyYamlData.from_data(
246
+ attribute_id=key,
247
+ **value)
216
248
 
217
249
  # Create a new AppInterfaceData object.
218
- data = AppInterfaceYamlData(dict(
250
+ return super(AppInterfaceYamlData, AppInterfaceYamlData).from_data(
251
+ AppInterfaceYamlData,
219
252
  **dependencies,
220
- **kwargs),
221
- strict=False,
253
+ **kwargs
222
254
  )
223
255
 
224
- # Validate and return the new AppInterfaceData object.
225
- data.validate()
226
- return data
227
-
228
256
  # * method: map
229
257
  def map(self, **kwargs) -> AppInterface:
230
258
  '''
@@ -250,15 +278,15 @@ class AppInterfaceYamlData(AppInterface, DataObject):
250
278
  ]
251
279
 
252
280
  # Map the app interface data.
253
- return super().map(AppInterface,
254
- dependencies=dependencies,
255
- **self.to_primitive('to_model'),
281
+ return super().map(AppInterface,
282
+ dependencies=dependencies,
283
+ **self.to_primitive('to_model'),
256
284
  **kwargs
257
285
  )
258
286
 
259
287
 
260
288
  # ** data: app_repository_configuration_yaml_data
261
- class AppRepositoryConfigurationYamlData(DataObject):
289
+ class AppRepositoryConfigurationYamlData(DataObject, AppRepositoryConfiguration):
262
290
  '''
263
291
  A YAML data representation of an app repository configuration object.
264
292
  '''
@@ -270,12 +298,12 @@ class AppRepositoryConfigurationYamlData(DataObject):
270
298
  serialize_when_none = False
271
299
  roles = {
272
300
  'to_model': DataObject.allow(),
273
- 'to_data.yaml': DataObject.allow()
301
+ 'to_data': DataObject.allow()
274
302
  }
275
303
 
276
304
  # * method: new
277
305
  @staticmethod
278
- def new(**kwargs) -> 'AppRepositoryConfigurationYamlData':
306
+ def from_data(**kwargs) -> 'AppRepositoryConfigurationYamlData':
279
307
  '''
280
308
  Initializes a new YAML representation of an AppRepositoryConfiguration object.
281
309
 
@@ -286,12 +314,11 @@ class AppRepositoryConfigurationYamlData(DataObject):
286
314
  '''
287
315
 
288
316
  # Create a new AppRepositoryConfigurationData object.
289
- return AppRepositoryConfigurationYamlData(
290
- super(AppRepositoryConfigurationYamlData, AppRepositoryConfigurationYamlData).new(
291
- **kwargs
292
- )
317
+ return super(AppRepositoryConfigurationYamlData, AppRepositoryConfigurationYamlData).from_data(
318
+ AppRepositoryConfigurationYamlData,
319
+ **kwargs
293
320
  )
294
-
321
+
295
322
  # * method: map
296
323
  def map(self, **kwargs) -> AppRepositoryConfiguration:
297
324
  '''
@@ -306,4 +333,4 @@ class AppRepositoryConfigurationYamlData(DataObject):
306
333
  '''
307
334
 
308
335
  # Map the app repository configuration data.
309
- return super().map(AppRepositoryConfiguration, **kwargs)
336
+ return super().map(AppRepositoryConfiguration, **kwargs)