tiferet 1.0.0a0__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.
app/__init__.py ADDED
File without changes
File without changes
app/clients/yaml.py ADDED
@@ -0,0 +1,93 @@
1
+ # *** imports
2
+
3
+ # ** infra
4
+ import yaml
5
+
6
+
7
+ # *** functions
8
+
9
+ # ** function: load
10
+ def load(path: str, create_data = lambda data: data, start_node = lambda data: data, **kwargs):
11
+ '''
12
+ Load the data from the yaml file.
13
+
14
+ :param path: The path to the yaml file.
15
+ :type path: str
16
+ :param create_data: The function to create the data.
17
+ :type create_data: function
18
+ :param start_node: The function to start the node.
19
+ :type start_node: function
20
+ :param kwargs: Additional keyword arguments.
21
+ :type kwargs: dict
22
+ :return: The data.
23
+ :rtype: dict
24
+ '''
25
+
26
+ # Load the data from the yaml file.
27
+ with open(path, 'r') as file:
28
+ data = yaml.safe_load(file)
29
+
30
+ # Find the start node.
31
+ try:
32
+ data = start_node(data)
33
+ except AttributeError:
34
+ return None
35
+
36
+ # Return the data if it is None.
37
+ if data == None:
38
+ return None
39
+
40
+ # Create and return the data.
41
+ return create_data(data, **kwargs)
42
+
43
+
44
+ # ** function: save
45
+ def save(yaml_file: str, data: dict, data_save_path: str = None):
46
+ '''
47
+ Save the data to the yaml file.
48
+
49
+ :param yaml_file: The path to the yaml file.
50
+ :type yaml_file: str
51
+ :param data: The data to save.
52
+ :type data: dict
53
+ :param data_save_path: The path to save the data to.
54
+ :type data_save_path: str
55
+ '''
56
+
57
+ # Save the data to the yaml file and exit if no save path is provided.
58
+ if not data_save_path:
59
+ with open(yaml_file, 'w') as file:
60
+ yaml.safe_dump(data, file)
61
+ return
62
+
63
+ # Load the yaml data.
64
+ with open(yaml_file, 'r') as file:
65
+ yaml_data = yaml.safe_load(file)
66
+
67
+ # Get the data save path list.
68
+ save_path_list = data_save_path.split('/')
69
+
70
+ # Update the yaml data.
71
+ new_yaml_data = None
72
+ for fragment in save_path_list[:-1]:
73
+
74
+ # If the new yaml data exists, update it.
75
+ try:
76
+ new_yaml_data = new_yaml_data[fragment]
77
+
78
+ # If the new yaml data does not exist, create it from the yaml data.
79
+ except TypeError:
80
+ new_yaml_data = yaml_data[fragment]
81
+ continue
82
+
83
+ # If the fragment does not exist on
84
+ except KeyError:
85
+ new_yaml_data[fragment] = {}
86
+ new_yaml_data = new_yaml_data[fragment]
87
+
88
+ # Update the yaml data.
89
+ new_yaml_data[save_path_list[-1]] = data
90
+
91
+ # Save the updated yaml data.
92
+ with open(yaml_file, 'w') as file:
93
+ yaml.safe_dump(yaml_data, file)
File without changes
@@ -0,0 +1,54 @@
1
+ from ..repos.container import ContainerRepository
2
+ from ..domain.container import ContainerAttribute, ContainerDependency
3
+ from ..services import container as container_service
4
+
5
+
6
+ class SetContainerAttribute(object):
7
+ '''
8
+ Command to set a new container attribute
9
+ '''
10
+
11
+ container_repo: ContainerRepository
12
+
13
+ def __init__(self, container_repo: ContainerRepository):
14
+ '''
15
+ Initialize the command to set a new container attribute.
16
+
17
+ :param container_repo: The container repository.
18
+ :type container_repo: ContainerRepository
19
+ '''
20
+
21
+ self.container_repo = container_repo
22
+
23
+ def execute(self, attribute_id: str, type: str, **kwargs):
24
+ '''
25
+ Execute the command to set a new container attribute.
26
+
27
+ :param attribute_id: The attribute id.
28
+ :type attribute_id: str
29
+ :param type: The attribute type.
30
+ :type type: str
31
+ :param kwargs: Additional keyword arguments.
32
+ :type kwargs: dict
33
+ '''
34
+
35
+ # Look up the container attribute.
36
+ attribute: ContainerAttribute = self.container_repo.get_attribute(attribute_id, type)
37
+
38
+ # If not attribute is found, create a new one.
39
+ if not attribute:
40
+ attribute = ContainerAttribute.new(
41
+ id=attribute_id,
42
+ type=type,
43
+ dependencies=[ContainerDependency.new(**kwargs)])
44
+
45
+ # Otherwise, create the container depenedency and add it to the attribute.
46
+ else:
47
+ dependency = ContainerDependency.new(**kwargs)
48
+ attribute.set_dependency(dependency)
49
+
50
+ # Save the container attribute.
51
+ self.container_repo.save_attribute(attribute=attribute)
52
+
53
+ # Return the new container attribute.
54
+ return attribute
app/commands/error.py ADDED
@@ -0,0 +1,21 @@
1
+ from ..domain.error import Error
2
+ from ..repos.error import ErrorRepository
3
+
4
+ class AddNewError(object):
5
+
6
+ def __init__(self, error_repo: ErrorRepository):
7
+ self.error_repo = error_repo
8
+
9
+ def execute(self, **kwargs) -> Error:
10
+
11
+ # Create a new error.
12
+ error: Error = Error.new(**kwargs)
13
+
14
+ # Assert that the error does not already exist.
15
+ assert not self.error_repo.exists(error.id), f'ERROR_ALREADY_EXISTS: {error.id}'
16
+
17
+ # Save the error.
18
+ self.error_repo.save(error)
19
+
20
+ # Return the new error.
21
+ return error
@@ -0,0 +1,90 @@
1
+ from ..domain.feature import Feature
2
+ from ..domain.feature import FeatureHandler
3
+ from ..repos.feature import FeatureRepository
4
+
5
+
6
+ class AddNewFeature(object):
7
+ '''
8
+ Add a new feature.
9
+ '''
10
+
11
+ def __init__(self, feature_repo: FeatureRepository):
12
+ '''
13
+ Initialize the command.
14
+
15
+ :param feature_repo: The feature repository.
16
+ :type feature_repo: FeatureRepository
17
+ '''
18
+
19
+ # Set the feature repository.
20
+ self.feature_repo = feature_repo
21
+
22
+ def execute(self, **kwargs) -> Feature:
23
+ '''
24
+ Execute the command to add a new feature.
25
+
26
+ :param kwargs: The keyword arguments.
27
+ :type kwargs: dict
28
+ :return: The new feature.
29
+ '''
30
+
31
+ # Create a new feature.
32
+ feature = Feature.new(**kwargs)
33
+
34
+ # Assert that the feature does not already exist.
35
+ assert not self.feature_repo.exists(
36
+ feature.id), f'FEATURE_ALREADY_EXISTS: {feature.id}'
37
+
38
+ # Save and return the feature.
39
+ self.feature_repo.save(feature)
40
+ return feature
41
+
42
+
43
+ class AddFeatureHandler(object):
44
+ '''
45
+ Adds a feature handler to a feature.
46
+ '''
47
+
48
+ def __init__(self, feature_repo: FeatureRepository):
49
+ '''
50
+ Initialize the command.
51
+
52
+ :param feature_repo: The feature repository.
53
+ :type feature_repo: FeatureRepository
54
+ '''
55
+
56
+ # Set the feature repository.
57
+ self.feature_repo = feature_repo
58
+
59
+ def execute(self, feature_id: str, position: int = None, **kwargs):
60
+ '''
61
+ Execute the command to add a feature handler to a feature.
62
+
63
+ :param feature_id: The feature ID.
64
+ :type feature_id: str
65
+ :param position: The position of the handler.
66
+ :type position: int
67
+ :param kwargs: Additional keyword arguments.
68
+ :type kwargs: dict
69
+ :return: The updated feature.
70
+ :rtype: Feature
71
+ '''
72
+
73
+ # Create a new feature handler instance.
74
+ handler = FeatureHandler.new(**kwargs)
75
+
76
+ # Get the feature using the feature ID.
77
+ feature = self.feature_repo.get(feature_id)
78
+
79
+ # Assert that the feature was successfully found.
80
+ assert feature is not None, f'FEATURE_NOT_FOUND: {feature_id}'
81
+
82
+ # Add the feature handler to the feature.
83
+ feature.add_handler(
84
+ handler,
85
+ position=position
86
+ )
87
+
88
+ # Save and return the feature.
89
+ self.feature_repo.save(feature)
90
+ return feature
@@ -0,0 +1,69 @@
1
+ # *** imports
2
+
3
+ # ** infra
4
+ from schematics import types as t
5
+
6
+
7
+ # *** config
8
+
9
+ # ** config (class): string_type
10
+ class StringType(t.StringType):
11
+ '''
12
+ A string type.
13
+ '''
14
+
15
+ pass
16
+
17
+
18
+ # ** config (class): integer_type
19
+ class IntegerType(t.IntType):
20
+ '''
21
+ An integer type.
22
+ '''
23
+
24
+ pass
25
+
26
+
27
+ # ** config (class): float_type
28
+ class FloatType(t.FloatType):
29
+ '''
30
+ A float type.
31
+ '''
32
+
33
+ pass
34
+
35
+
36
+ # ** config (class): boolean_type
37
+ class BooleanType(t.BooleanType):
38
+ '''
39
+ A boolean type.
40
+ '''
41
+
42
+ pass
43
+
44
+
45
+ # ** config (class): list_type
46
+ class ListType(t.ListType):
47
+ '''
48
+ A list type.
49
+ '''
50
+
51
+ pass
52
+
53
+
54
+ # ** config (class): dict_type
55
+ class DictType(t.DictType):
56
+ '''
57
+ A dictionary type.
58
+ '''
59
+
60
+ pass
61
+
62
+
63
+ # ** config (class): model_type
64
+ class ModelType(t.ModelType):
65
+ '''
66
+ A model type.
67
+ '''
68
+
69
+ pass
app/configs/app.py ADDED
@@ -0,0 +1,16 @@
1
+ # *** imports
2
+
3
+ # ** app
4
+ from ..domain.app import AppRepositoryConfiguration
5
+
6
+
7
+ # *** constants
8
+
9
+ # ** constant: APP_REPO
10
+ APP_REPO = AppRepositoryConfiguration.new(
11
+ module_path='app.repositories.app',
12
+ class_name='YamlProxy',
13
+ params=dict(
14
+ app_config_file='app/configs/app.yaml'
15
+ ),
16
+ )
@@ -0,0 +1,91 @@
1
+ # *** imports
2
+
3
+ # ** app
4
+ from ..domain.container import ContainerAttribute, ContainerDependency
5
+
6
+
7
+ # *** configs (container_attribute)
8
+
9
+ # ** config: feature_repo
10
+ feature_repo = ContainerAttribute.new(
11
+ id='feature_repo',
12
+ type='data',
13
+ flags=[
14
+ ContainerDependency.new(
15
+ flag='yaml',
16
+ module_path='app.repositories.feature',
17
+ class_name='YamlProxy',
18
+ parameters={
19
+ 'feature_config_file': 'app/configs/features.yml'
20
+ }
21
+ )
22
+ ]
23
+ )
24
+
25
+ # ** config: error_repo
26
+ error_repo = ContainerAttribute.new(
27
+ id='error_repo',
28
+ type='data',
29
+ flags=[
30
+ ContainerDependency.new(
31
+ flag='yaml',
32
+ module_path='app.repositories.error',
33
+ class_name='YamlProxy',
34
+ parameters={
35
+ 'error_config_file': 'app/configs/errors.yml'
36
+ }
37
+ )
38
+ ]
39
+ )
40
+
41
+ # ** config: set_container_attribute
42
+ set_container_attribute = ContainerAttribute.new(
43
+ id='set_container_attribute',
44
+ type='feature',
45
+ flags=[
46
+ ContainerDependency.new(
47
+ flag='core',
48
+ module_path='app.commands.container',
49
+ class_name='SetContainerAttribute'
50
+ )
51
+ ]
52
+ )
53
+
54
+ # ** config: add_new_feature
55
+ add_new_feature = ContainerAttribute.new(
56
+ id='add_new_feature',
57
+ type='feature',
58
+ flags=[
59
+ ContainerDependency.new(
60
+ flag='core',
61
+ module_path='app.commands.feature',
62
+ class_name='AddNewFeature'
63
+ )
64
+ ]
65
+ )
66
+
67
+ # ** config: add_feature_command
68
+ add_feature_command = ContainerAttribute.new(
69
+ id='add_feature_command',
70
+ type='feature',
71
+ flags=[
72
+ ContainerDependency.new(
73
+ flag='core',
74
+ module_path='app.commands.feature',
75
+ class_name='AddFeatureCommand'
76
+ )
77
+ ]
78
+ )
79
+
80
+ # ** config: add_new_error
81
+ add_new_error = ContainerAttribute.new(
82
+ id='add_new_error',
83
+ type='feature',
84
+ flags=[
85
+ ContainerDependency.new(
86
+ flag='core',
87
+ module_path='app.commands.error',
88
+ class_name='AddNewError'
89
+ )
90
+ ]
91
+ )
@@ -0,0 +1,2 @@
1
+ from .app import AppContext
2
+ from .env import EnvironmentContext
app/contexts/app.py ADDED
@@ -0,0 +1,130 @@
1
+ # *** imports
2
+
3
+ # ** core
4
+ from typing import Any
5
+
6
+ # ** app
7
+ from .request import RequestContext
8
+ from .feature import FeatureContext
9
+ from .error import ErrorContext
10
+ from ..domain import *
11
+
12
+
13
+ # *** contexts
14
+
15
+ # ** context: app_interface_context
16
+ class AppInterfaceContext(Model):
17
+
18
+ # * attribute: name
19
+ name = StringType(
20
+ required=True,
21
+ metadata=dict(
22
+ description='The application name.'
23
+ )
24
+ )
25
+
26
+ # * field: features
27
+ features = ModelType(
28
+ FeatureContext,
29
+ required=True,
30
+ metadata=dict(
31
+ description='The feature context.'
32
+ )
33
+ )
34
+
35
+ # * field: errors
36
+ errors = ModelType(
37
+ ErrorContext,
38
+ required=True,
39
+ metadata=dict(
40
+ description='The error context.'
41
+ )
42
+ )
43
+
44
+ # * method: init
45
+ def __init__(self, app_name: str, feature_context: FeatureContext, error_context: ErrorContext):
46
+ '''
47
+ Initialize the application interface context.
48
+
49
+ :param app_name: The application name.
50
+ :type app_name: str
51
+ :param feature_context: The feature context.
52
+ :type feature_context: FeatureContext
53
+ :param error_context: The error context.
54
+ :type error_context: ErrorContext
55
+ '''
56
+
57
+ # Initialize the model.
58
+ super().__init__(dict(
59
+ name=app_name,
60
+ features=feature_context,
61
+ errors=error_context
62
+ ))
63
+
64
+ # * method: parse_request
65
+ def parse_request(self, request: Any, **kwargs) -> RequestContext:
66
+ '''
67
+ Parse the incoming request.
68
+
69
+ :param request: The incoming request.
70
+ :type request: Any
71
+ :param kwargs: Additional keyword arguments.
72
+ :type kwargs: dict
73
+ :return: The request context.
74
+ :rtype: RequestContext
75
+ '''
76
+
77
+ # Parse request.
78
+ return request
79
+
80
+ # * method: execute_feature
81
+ def execute_feature(self, request: RequestContext, **kwargs):
82
+ '''
83
+ Execute the feature context.
84
+
85
+ :param request: The request context.
86
+ :type request: RequestContext
87
+ '''
88
+
89
+ # Execute feature context and return session.
90
+ self.features.execute(request, **kwargs)
91
+
92
+ # * method: handle_response
93
+ def handle_response(self, request: RequestContext) -> Any:
94
+ '''
95
+ Handle the response.
96
+
97
+ :param request: The request context.
98
+ :type request: RequestContext
99
+ :return: The response.
100
+ :rtype: Any
101
+ '''
102
+
103
+ # Import the JSON module.
104
+ import json
105
+
106
+ # Return the response.
107
+ return json.loads(request.result)
108
+
109
+ # * method: run
110
+ def run(self, **kwargs):
111
+ '''
112
+ Run the application interface.
113
+
114
+ :param kwargs: Additional keyword arguments.
115
+ :type kwargs: dict
116
+ '''
117
+
118
+ # Parse request.
119
+ request = self.parse_request(**kwargs)
120
+
121
+ # Execute feature context and return session.
122
+ # Handle error and return response if triggered.
123
+ has_error, message = self.errors.handle_error(lambda: self.execute_feature(request, **kwargs))
124
+
125
+ # Handle error if present.
126
+ if has_error:
127
+ return message
128
+
129
+ # Handle response.
130
+ return self.handle_response(request)