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 +0 -0
- app/clients/__init__.py +0 -0
- app/clients/yaml.py +93 -0
- app/commands/__init__.py +0 -0
- app/commands/container.py +54 -0
- app/commands/error.py +21 -0
- app/commands/feature.py +90 -0
- app/configs/__init__.py +69 -0
- app/configs/app.py +16 -0
- app/configs/container.py +91 -0
- app/contexts/__init__.py +2 -0
- app/contexts/app.py +130 -0
- app/contexts/container.py +167 -0
- app/contexts/env.py +109 -0
- app/contexts/error.py +95 -0
- app/contexts/feature.py +79 -0
- app/contexts/request.py +108 -0
- app/data/__init__.py +4 -0
- app/data/app.py +227 -0
- app/data/container.py +179 -0
- app/data/error.py +99 -0
- app/data/feature.py +132 -0
- app/domain/__init__.py +5 -0
- app/domain/app.py +330 -0
- app/domain/container.py +141 -0
- app/domain/core.py +199 -0
- app/domain/error.py +136 -0
- app/domain/feature.py +176 -0
- app/repos/__init__.py +0 -0
- app/repos/app.py +102 -0
- app/repos/container.py +164 -0
- app/repos/error.py +173 -0
- app/repos/feature.py +169 -0
- app/services/__init__.py +4 -0
- app/services/cli.py +186 -0
- app/services/container.py +44 -0
- tiferet-1.0.0a0.dist-info/LICENSE +28 -0
- tiferet-1.0.0a0.dist-info/METADATA +13 -0
- tiferet-1.0.0a0.dist-info/RECORD +41 -0
- tiferet-1.0.0a0.dist-info/WHEEL +5 -0
- tiferet-1.0.0a0.dist-info/top_level.txt +1 -0
app/repos/error.py
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
# *** imports
|
2
|
+
|
3
|
+
# ** core
|
4
|
+
from typing import List, Dict
|
5
|
+
|
6
|
+
# ** app
|
7
|
+
from ..domain.error import Error
|
8
|
+
from ..clients import yaml as yaml_client
|
9
|
+
from ..data.error import ErrorData
|
10
|
+
|
11
|
+
|
12
|
+
# *** repository
|
13
|
+
|
14
|
+
# ** interface: error_repository
|
15
|
+
class ErrorRepository(object):
|
16
|
+
|
17
|
+
# * method: exists
|
18
|
+
def exists(self, id: str, **kwargs) -> bool:
|
19
|
+
'''
|
20
|
+
Check if the error exists.
|
21
|
+
|
22
|
+
:param id: The error id.
|
23
|
+
:type id: str
|
24
|
+
:param kwargs: Additional keyword arguments.
|
25
|
+
:type kwargs: dict
|
26
|
+
:return: Whether the error exists.
|
27
|
+
:rtype: bool
|
28
|
+
'''
|
29
|
+
|
30
|
+
# Not implemented.
|
31
|
+
raise NotImplementedError()
|
32
|
+
|
33
|
+
# * method: get
|
34
|
+
def get(self, id: str) -> Error:
|
35
|
+
'''
|
36
|
+
Get the error.
|
37
|
+
|
38
|
+
:param id: The error id.
|
39
|
+
:type id: str
|
40
|
+
:return: The error.
|
41
|
+
:rtype: Error
|
42
|
+
'''
|
43
|
+
|
44
|
+
# Not implemented.
|
45
|
+
raise NotImplementedError()
|
46
|
+
|
47
|
+
# * method: list
|
48
|
+
def list(self) -> List[Error]:
|
49
|
+
'''
|
50
|
+
List all errors.
|
51
|
+
|
52
|
+
:return: The list of errors.
|
53
|
+
:rtype: List[Error]
|
54
|
+
'''
|
55
|
+
|
56
|
+
# Not implemented.
|
57
|
+
raise NotImplementedError()
|
58
|
+
|
59
|
+
# * method: save
|
60
|
+
def save(self, error: Error):
|
61
|
+
'''
|
62
|
+
Save the error.
|
63
|
+
|
64
|
+
:param error: The error.
|
65
|
+
:type error: Error
|
66
|
+
'''
|
67
|
+
|
68
|
+
# Not implemented.
|
69
|
+
raise NotImplementedError
|
70
|
+
|
71
|
+
|
72
|
+
# ** proxy: yaml_proxy
|
73
|
+
class YamlProxy(ErrorRepository):
|
74
|
+
'''
|
75
|
+
The YAML proxy for the error repository
|
76
|
+
'''
|
77
|
+
|
78
|
+
# * field: config_file
|
79
|
+
config_file: str
|
80
|
+
|
81
|
+
# * method: init
|
82
|
+
def __init__(self, error_config_file: str):
|
83
|
+
'''
|
84
|
+
Initialize the yaml proxy.
|
85
|
+
|
86
|
+
:param error_config_file: The error configuration file.
|
87
|
+
:type error_config_file: str
|
88
|
+
'''
|
89
|
+
|
90
|
+
# Set the base path.
|
91
|
+
self.config_file = error_config_file
|
92
|
+
|
93
|
+
# * method: exists
|
94
|
+
def exists(self, id: str, **kwargs) -> bool:
|
95
|
+
'''
|
96
|
+
Check if the error exists.
|
97
|
+
|
98
|
+
:param id: The error id.
|
99
|
+
:type id: str
|
100
|
+
:param kwargs: Additional keyword arguments.
|
101
|
+
:type kwargs: dict
|
102
|
+
:return: Whether the error exists.
|
103
|
+
:rtype: bool
|
104
|
+
'''
|
105
|
+
|
106
|
+
# Load the error data from the yaml configuration file.
|
107
|
+
data: List[ErrorData] = yaml_client.load(
|
108
|
+
self.config_file,
|
109
|
+
create_data=lambda data: ErrorData.from_yaml_data(
|
110
|
+
id=id, **data),
|
111
|
+
start_node=lambda data: data.get('errors').get(id))
|
112
|
+
|
113
|
+
# Return whether the error exists.
|
114
|
+
return data is not None
|
115
|
+
|
116
|
+
# * method: get
|
117
|
+
def get(self, id: str) -> Error:
|
118
|
+
'''
|
119
|
+
Get the error.
|
120
|
+
|
121
|
+
:param id: The error id.
|
122
|
+
:type id: str
|
123
|
+
:return: The error.
|
124
|
+
:rtype: Error
|
125
|
+
'''
|
126
|
+
|
127
|
+
# Load the error data from the yaml configuration file.
|
128
|
+
_data: ErrorData = yaml_client.load(
|
129
|
+
self.config_file,
|
130
|
+
create_data=lambda data: ErrorData.from_yaml_data(
|
131
|
+
id=id, **data),
|
132
|
+
start_node=lambda data: data.get('errors').get(id))
|
133
|
+
|
134
|
+
# Return the error object.
|
135
|
+
return _data.map('to_object.yaml')
|
136
|
+
|
137
|
+
# * method: list
|
138
|
+
def list(self) -> List[Error]:
|
139
|
+
'''
|
140
|
+
List all errors.
|
141
|
+
|
142
|
+
:return: The list of errors.
|
143
|
+
:rtype: List[Error]
|
144
|
+
'''
|
145
|
+
|
146
|
+
# Load the error data from the yaml configuration file.
|
147
|
+
_data: Dict[str, ErrorData] = yaml_client.load(
|
148
|
+
self.config_file,
|
149
|
+
create_data=lambda data: ErrorData.from_yaml_data(
|
150
|
+
id=id, **data),
|
151
|
+
start_node=lambda data: data.get('errors'))
|
152
|
+
|
153
|
+
# Return the error object.
|
154
|
+
return [data.map('to_object.yaml') for data in _data.values()]
|
155
|
+
|
156
|
+
# * method: save
|
157
|
+
def save(self, error: Error):
|
158
|
+
'''
|
159
|
+
Save the error.
|
160
|
+
|
161
|
+
:param error: The error.
|
162
|
+
:type error: Error
|
163
|
+
'''
|
164
|
+
|
165
|
+
# Create updated error data.
|
166
|
+
error_data = ErrorData.new(**error.to_primitive())
|
167
|
+
|
168
|
+
# Update the error data.
|
169
|
+
yaml_client.save(
|
170
|
+
path=self.config_file,
|
171
|
+
data=error_data,
|
172
|
+
data_save_path=f'errors/{error.name}',
|
173
|
+
)
|
app/repos/feature.py
ADDED
@@ -0,0 +1,169 @@
|
|
1
|
+
from typing import Dict, Any, List
|
2
|
+
|
3
|
+
from ..data.feature import FeatureData
|
4
|
+
from ..domain.feature import Feature
|
5
|
+
|
6
|
+
from ..clients import yaml as yaml_client
|
7
|
+
|
8
|
+
|
9
|
+
class FeatureRepository(object):
|
10
|
+
'''
|
11
|
+
Feature repository interface.
|
12
|
+
'''
|
13
|
+
|
14
|
+
def exists(self, id: str) -> bool:
|
15
|
+
'''
|
16
|
+
Verifies if the feature exists.
|
17
|
+
|
18
|
+
:param id: The feature id.
|
19
|
+
:type id: str
|
20
|
+
:return: Whether the feature exists.
|
21
|
+
:rtype: bool
|
22
|
+
'''
|
23
|
+
|
24
|
+
raise NotImplementedError()
|
25
|
+
|
26
|
+
def get(self, id: str) -> Feature:
|
27
|
+
'''
|
28
|
+
Get the feature by id.
|
29
|
+
|
30
|
+
:param id: The feature id.
|
31
|
+
:type id: str
|
32
|
+
:return: The feature object.
|
33
|
+
:rtype: f.Feature
|
34
|
+
'''
|
35
|
+
|
36
|
+
raise NotImplementedError()
|
37
|
+
|
38
|
+
def list(self, group_id: str = None) -> List[Feature]:
|
39
|
+
'''
|
40
|
+
List the features.
|
41
|
+
|
42
|
+
:param group_id: The group id.
|
43
|
+
:type group_id: str
|
44
|
+
:return: The list of features.
|
45
|
+
:rtype: list
|
46
|
+
'''
|
47
|
+
|
48
|
+
raise NotImplementedError
|
49
|
+
|
50
|
+
def save(self, feature: Feature):
|
51
|
+
'''
|
52
|
+
Save the feature.
|
53
|
+
|
54
|
+
:param feature: The feature object.
|
55
|
+
:type feature: f.Feature
|
56
|
+
'''
|
57
|
+
|
58
|
+
raise NotImplementedError()
|
59
|
+
|
60
|
+
|
61
|
+
class YamlProxy(FeatureRepository):
|
62
|
+
'''
|
63
|
+
Yaml repository for features.
|
64
|
+
'''
|
65
|
+
|
66
|
+
def __init__(self, feature_yaml_base_path: str):
|
67
|
+
'''
|
68
|
+
Initialize the yaml repository.
|
69
|
+
|
70
|
+
:param feature_yaml_base_path: The base path to the yaml file.
|
71
|
+
:type feature_yaml_base_path: str
|
72
|
+
'''
|
73
|
+
|
74
|
+
# Set the base path.
|
75
|
+
self.base_path = feature_yaml_base_path
|
76
|
+
|
77
|
+
def exists(self, id: str) -> bool:
|
78
|
+
'''
|
79
|
+
Verifies if the feature exists.
|
80
|
+
|
81
|
+
:param id: The feature id.
|
82
|
+
:type id: str
|
83
|
+
:return: Whether the feature exists.
|
84
|
+
:rtype: bool
|
85
|
+
'''
|
86
|
+
|
87
|
+
# Retrieve the feature by id.
|
88
|
+
feature = self.get(id)
|
89
|
+
|
90
|
+
# Return whether the feature exists.
|
91
|
+
return feature is not None
|
92
|
+
|
93
|
+
def get(self, id: str) -> Feature:
|
94
|
+
'''
|
95
|
+
Get the feature by id.
|
96
|
+
|
97
|
+
:param id: The feature id.
|
98
|
+
:type id: str
|
99
|
+
:return: The feature object.
|
100
|
+
'''
|
101
|
+
|
102
|
+
# Get context group and feature key from the id.
|
103
|
+
group_id, feature_key = id.split('.')
|
104
|
+
|
105
|
+
# Load feature data from yaml.
|
106
|
+
_data: FeatureData = yaml_client.load(
|
107
|
+
self.base_path,
|
108
|
+
create_data=lambda data: FeatureData.from_yaml_data(
|
109
|
+
id=id,
|
110
|
+
group_id=group_id,
|
111
|
+
**data
|
112
|
+
),
|
113
|
+
start_node=lambda data: data.get('features').get('groups').get(group_id).get('features').get(feature_key)
|
114
|
+
)
|
115
|
+
|
116
|
+
# Return None if feature data is not found.
|
117
|
+
if not _data:
|
118
|
+
return None
|
119
|
+
|
120
|
+
# Return feature.
|
121
|
+
return _data.map('to_object.yaml')
|
122
|
+
|
123
|
+
def list(self, group_id: str = None) -> List[Feature]:
|
124
|
+
'''
|
125
|
+
List the features.
|
126
|
+
|
127
|
+
:param group_id: The group id.
|
128
|
+
:type group_id: str
|
129
|
+
:return: The list of features.
|
130
|
+
:rtype: list
|
131
|
+
'''
|
132
|
+
|
133
|
+
# Load all feature data from yaml.
|
134
|
+
features = yaml_client.load(
|
135
|
+
self.base_path,
|
136
|
+
create_data=lambda data: [FeatureData.from_yaml_data(
|
137
|
+
id=id,
|
138
|
+
**feature_data
|
139
|
+
) for id, feature_data in data.items()],
|
140
|
+
start_node=lambda data: data.get('features')
|
141
|
+
)
|
142
|
+
|
143
|
+
# Filter features by group id.
|
144
|
+
if group_id:
|
145
|
+
features = [feature for feature in features if feature.group_id == group_id]
|
146
|
+
|
147
|
+
# Return the list of features.
|
148
|
+
return [feature.map('to_object.yaml') for feature in features]
|
149
|
+
|
150
|
+
def save(self, feature: Feature):
|
151
|
+
'''
|
152
|
+
Save the feature.
|
153
|
+
|
154
|
+
:param feature: The feature object.
|
155
|
+
:type feature: f.Feature
|
156
|
+
'''
|
157
|
+
|
158
|
+
# Create updated feature data.
|
159
|
+
feature_data = FeatureData.new(**feature.to_primitive())
|
160
|
+
|
161
|
+
# Update the feature data.
|
162
|
+
yaml_client.save(
|
163
|
+
self.base_path,
|
164
|
+
data=feature_data,
|
165
|
+
data_save_path=f'features/{feature.group_id}.{feature_data.feature_key}'
|
166
|
+
)
|
167
|
+
|
168
|
+
# Return the updated feature object.
|
169
|
+
return feature_data.map('to_object.yaml')
|
app/services/__init__.py
ADDED
app/services/cli.py
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
from typing import List, Dict, Any
|
2
|
+
import argparse
|
3
|
+
|
4
|
+
from ..contexts.request import RequestContext
|
5
|
+
from ..domain.cli import CliInterface
|
6
|
+
from ..domain.cli import CliArgument
|
7
|
+
|
8
|
+
|
9
|
+
def create_argument_data(cli_argument: CliArgument):
|
10
|
+
|
11
|
+
# List fields to be excluded.
|
12
|
+
exclude_fields = ['name_or_flags', 'arg_type', 'to_data']
|
13
|
+
|
14
|
+
# Exclude unneeded fields if the argument contains an action.
|
15
|
+
if cli_argument.action:
|
16
|
+
exclude_fields.append('nargs')
|
17
|
+
exclude_fields.append('type')
|
18
|
+
exclude_fields.append('choices')
|
19
|
+
|
20
|
+
# Set the data type for the argument.
|
21
|
+
if cli_argument.type == 'str':
|
22
|
+
data_type = str
|
23
|
+
elif cli_argument.type == 'int':
|
24
|
+
data_type = int
|
25
|
+
elif cli_argument.type == 'float':
|
26
|
+
data_type = float
|
27
|
+
|
28
|
+
# For each name or flag in the argument,
|
29
|
+
for name in cli_argument.name_or_flags:
|
30
|
+
|
31
|
+
# If the name or flag is a positional argument,
|
32
|
+
if not name.startswith('--'):
|
33
|
+
|
34
|
+
# Remove the required field.
|
35
|
+
exclude_fields.append('required')
|
36
|
+
|
37
|
+
# Assemble the argument data.
|
38
|
+
argument_data = cli_argument.to_primitive()
|
39
|
+
|
40
|
+
# Set the data type.
|
41
|
+
argument_data['type'] = data_type
|
42
|
+
|
43
|
+
# For each field in the excluded fields,
|
44
|
+
for field in exclude_fields:
|
45
|
+
|
46
|
+
# Remove the field from the argument data if it is present.
|
47
|
+
try:
|
48
|
+
del argument_data[field]
|
49
|
+
except KeyError:
|
50
|
+
pass
|
51
|
+
|
52
|
+
# Return the argument data.
|
53
|
+
return argument_data
|
54
|
+
|
55
|
+
|
56
|
+
def create_headers(data: dict):
|
57
|
+
headers = dict(
|
58
|
+
group_id=data.pop('group'),
|
59
|
+
command_id=data.pop('command'),
|
60
|
+
)
|
61
|
+
headers['id'] = f"{headers['group_id']}.{headers['command_id']}".replace(
|
62
|
+
'-', '_')
|
63
|
+
return headers
|
64
|
+
|
65
|
+
|
66
|
+
def create_cli_parser(cli_interface: CliInterface):
|
67
|
+
|
68
|
+
# Format commands into a dictionary lookup by group id.
|
69
|
+
commands = {}
|
70
|
+
for command in cli_interface.commands:
|
71
|
+
group_id = command.group_id
|
72
|
+
if group_id not in commands:
|
73
|
+
commands[group_id] = []
|
74
|
+
commands[group_id].append(command)
|
75
|
+
|
76
|
+
# Create parser.
|
77
|
+
parser = argparse.ArgumentParser()
|
78
|
+
|
79
|
+
# Add command subparsers
|
80
|
+
command_subparsers = parser.add_subparsers(dest='group')
|
81
|
+
for group_id, commands in commands.items():
|
82
|
+
group_name = group_id.replace('_', '-')
|
83
|
+
command_subparser = command_subparsers.add_parser(
|
84
|
+
group_name)
|
85
|
+
subcommand_subparsers = command_subparser.add_subparsers(
|
86
|
+
dest='command')
|
87
|
+
for command in commands:
|
88
|
+
command_name = command.id.split('.')[-1].replace('_', '-')
|
89
|
+
subcommand_subparser = subcommand_subparsers.add_parser(
|
90
|
+
command_name)
|
91
|
+
for argument in command.arguments:
|
92
|
+
subcommand_subparser.add_argument(
|
93
|
+
*argument.name_or_flags, **create_argument_data(argument))
|
94
|
+
for argument in cli_interface.parent_arguments:
|
95
|
+
subcommand_subparser.add_argument(
|
96
|
+
*argument.name_or_flags, **create_argument_data(argument))
|
97
|
+
|
98
|
+
return parser
|
99
|
+
|
100
|
+
|
101
|
+
def create_request(request: argparse.Namespace, cli_interface: CliInterface, **kwargs) -> RequestContext:
|
102
|
+
|
103
|
+
# Convert argparse.Namespace to dictionary.
|
104
|
+
data = vars(request)
|
105
|
+
|
106
|
+
# Create header values.
|
107
|
+
headers = create_headers(data)
|
108
|
+
|
109
|
+
# Get the command from the CLI interface.
|
110
|
+
command = cli_interface.get_command(**headers)
|
111
|
+
|
112
|
+
# Create map of arguments to their data attribute names.
|
113
|
+
argument_map = {arg.get_name(): arg for arg in command.arguments}
|
114
|
+
|
115
|
+
# Map the data to the request context.
|
116
|
+
for key, value in data.items():
|
117
|
+
if value is None:
|
118
|
+
continue
|
119
|
+
argument = argument_map.get(key)
|
120
|
+
data[key] = map_object_input(value, argument)
|
121
|
+
|
122
|
+
# Create request context.
|
123
|
+
return RequestContext(
|
124
|
+
feature_id=command.feature_id,
|
125
|
+
data=data,
|
126
|
+
headers=headers,
|
127
|
+
**headers,
|
128
|
+
**kwargs
|
129
|
+
)
|
130
|
+
|
131
|
+
|
132
|
+
def map_object_input(data: Any, argument: CliArgument):
|
133
|
+
|
134
|
+
# If the argument is not input to data,
|
135
|
+
if not argument.to_data:
|
136
|
+
|
137
|
+
# Return the data.
|
138
|
+
return data
|
139
|
+
|
140
|
+
# If the argument is a dictionary,
|
141
|
+
if argument.nargs:
|
142
|
+
|
143
|
+
# If the argument is a list, split the data by the delimiter.
|
144
|
+
result = {}
|
145
|
+
|
146
|
+
# For each item in the data, split the item into key and value.
|
147
|
+
for item in data:
|
148
|
+
|
149
|
+
# Split the item into key and value.
|
150
|
+
key, value = item.split('=')
|
151
|
+
|
152
|
+
# Add the key and value to the result.
|
153
|
+
result[key] = value
|
154
|
+
|
155
|
+
# Return result.
|
156
|
+
return result
|
157
|
+
|
158
|
+
# If the argument is an object list,
|
159
|
+
if argument.action == 'append':
|
160
|
+
|
161
|
+
# Create a list to store the result.
|
162
|
+
result = []
|
163
|
+
|
164
|
+
# For each row object in the data,
|
165
|
+
for row in data:
|
166
|
+
|
167
|
+
# Create an object to store the key value pairs.
|
168
|
+
obj = {}
|
169
|
+
|
170
|
+
# Split the row by the delimiter.
|
171
|
+
items = row.split(';')
|
172
|
+
|
173
|
+
# For each item in the row,
|
174
|
+
for item in items:
|
175
|
+
|
176
|
+
# Split the item into key and value.
|
177
|
+
key, value = item.split('=')
|
178
|
+
|
179
|
+
# Add the key and value to the object.
|
180
|
+
obj[key] = value
|
181
|
+
|
182
|
+
# Add the object to the result.
|
183
|
+
result.append(obj)
|
184
|
+
|
185
|
+
# Return result.
|
186
|
+
return result
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# *** imports
|
2
|
+
|
3
|
+
# ** core
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
# ** infra
|
7
|
+
from dependencies import Injector
|
8
|
+
|
9
|
+
|
10
|
+
# *** functions
|
11
|
+
|
12
|
+
# ** function: import_dependency
|
13
|
+
def import_dependency(module_path: str, class_name: str) -> Any:
|
14
|
+
'''
|
15
|
+
Import an object dependency from its configured Python module.
|
16
|
+
|
17
|
+
:param module_path: The module path.
|
18
|
+
:type module_path: str
|
19
|
+
:param class_name: The class name.
|
20
|
+
:type class_name: str
|
21
|
+
:return: The dependency.
|
22
|
+
:rtype: Any
|
23
|
+
'''
|
24
|
+
|
25
|
+
# Import module.
|
26
|
+
from importlib import import_module
|
27
|
+
return getattr(import_module(module_path), class_name)
|
28
|
+
|
29
|
+
|
30
|
+
# ** function: create_injector
|
31
|
+
def create_injector(name: str, **dependencies) -> Any:
|
32
|
+
'''
|
33
|
+
Create an injector object with the given dependencies.
|
34
|
+
|
35
|
+
:param name: The name of the injector.
|
36
|
+
:type name: str
|
37
|
+
:param dependencies: The dependencies.
|
38
|
+
:type dependencies: dict
|
39
|
+
:return: The injector object.
|
40
|
+
:rtype: Any
|
41
|
+
'''
|
42
|
+
|
43
|
+
# Create container.
|
44
|
+
return type(f'{name.capitalize()}Container', (Injector,), {**dependencies})
|
@@ -0,0 +1,28 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2024, Great Strength Systems LLC
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
13
|
+
and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
16
|
+
contributors may be used to endorse or promote products derived from
|
17
|
+
this software without specific prior written permission.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: tiferet
|
3
|
+
Version: 1.0.0a0
|
4
|
+
Summary: A multi-purpose application framework embodying beauty in form.
|
5
|
+
Home-page: https://github.com/greatstrength/app
|
6
|
+
Download-URL: https://github.com/greatstrength/app
|
7
|
+
Author: Andrew Shatz
|
8
|
+
Author-email: andrew@greatstrength.me
|
9
|
+
License: BSD 3
|
10
|
+
License-File: LICENSE
|
11
|
+
Requires-Dist: schematics >=2.1.1
|
12
|
+
Requires-Dist: pyyaml >=6.0.1
|
13
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
app/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
|
+
app/clients/yaml.py,sha256=-Eo8PX2oPpVxv1c-cpkNOrGhxx9T7XPYoAyGi1DxMi4,2454
|
4
|
+
app/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
app/commands/container.py,sha256=L2IKJqEbRglw_LC144oYAkARr2Rixj8IFuC6Ro1jAqA,1789
|
6
|
+
app/commands/error.py,sha256=ixMYH0yrEWlMAVGDSRke3IGoWaOShfmiXntrUC2b3wY,573
|
7
|
+
app/commands/feature.py,sha256=tXa-MDf14ByIJqwQFeSUu2QLUjHPdsyvFNhj1XeaQVk,2507
|
8
|
+
app/configs/__init__.py,sha256=NfT6XFNcJznOLXjMuNmj3XeaOPVWwbc-N4kVWaVjuD0,845
|
9
|
+
app/configs/app.py,sha256=YWKVPTCaCVwpmTbdUdeZya-IfJvxxenGQpcUD7YbU54,302
|
10
|
+
app/configs/container.py,sha256=x9JwWi7XRRnoVahf858REYNY3ZxCaznjGJUqoAK1FZs,2106
|
11
|
+
app/contexts/__init__.py,sha256=0HzyDBIyyF8fZ0gOXekzfzHWVkbLFUx9eLLzuooEzFs,63
|
12
|
+
app/contexts/app.py,sha256=MPRFu3ut7DOmc3i3PqLR96ymvWMShW6BUbY9eG8i6Eg,3296
|
13
|
+
app/contexts/container.py,sha256=RI33tK9XF18PaUfOp64ddMZGOCMIy3XNgQMUtJ_jYNE,4924
|
14
|
+
app/contexts/env.py,sha256=bbvZzDy075SuKL2ZIfDEE5yD1Hbk-4XLGe4eC_tT8e8,3080
|
15
|
+
app/contexts/error.py,sha256=VO3Wgkmf5bdK6LoT0xhQn1WeSAVulQwUhvBAsoUPd1c,2503
|
16
|
+
app/contexts/feature.py,sha256=u7wEhdfTLeWKIv5i2nzBcu4cAcVkm6iqNNznczPmHjc,2293
|
17
|
+
app/contexts/request.py,sha256=TOECa0V1wKuNGCYFIRKxwsZVpLtP0FS_Nm96DaEVsWU,2726
|
18
|
+
app/data/__init__.py,sha256=ts3bkFftArKTgUJj7q65Sob4fC6jOqfYNxm6cqjFr_w,74
|
19
|
+
app/data/app.py,sha256=8kv7tDJUjl70bqdpiMXXs6e89zDQIvtlDSOq42iyyX0,6312
|
20
|
+
app/data/container.py,sha256=jTQlT4D-lLC_QLNAmMara6O78g667GXk1LU_EyuX_HU,5180
|
21
|
+
app/data/error.py,sha256=lfGO3SjtsxSv6d7iKDeVw3vXfocCk29g4-uwC3jnaig,2377
|
22
|
+
app/data/feature.py,sha256=s_aqVYhH7VKzXpWM3d-uvSv3_r8A0LgObv3Agg-CKoc,3697
|
23
|
+
app/domain/__init__.py,sha256=uC1lHXzRnpoHqfgPcUraea5F_T1Nsx0wBau0paslsQg,146
|
24
|
+
app/domain/app.py,sha256=t_TcemJfpSa_CQfjcSfRRo2iFS1ilanfpHTiHx1vM8w,8528
|
25
|
+
app/domain/container.py,sha256=Kw_xNn5_tWghcx3Dl_vPEdwZ2b8u23ZpbgMQ_bkUKaw,3666
|
26
|
+
app/domain/core.py,sha256=a1nJvH7bCqP_JvGrkMDClH8nef2L3WHpmTV6ksmdZ4c,4600
|
27
|
+
app/domain/error.py,sha256=myUpdB4rgmbVBwIP8Pa88uastTSjPFGqrSwqR9C-VYg,3371
|
28
|
+
app/domain/feature.py,sha256=RhedOKb8nG1D0J9b_aPVtJc_rQjLXwOpwpIsmzrH21o,4552
|
29
|
+
app/repos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
30
|
+
app/repos/app.py,sha256=VptevFxeST5slbk_em7dazXgz5U8f_XLDsGdM0Gq3qE,2696
|
31
|
+
app/repos/container.py,sha256=2Medggn4BZrelnZ-cDZfFFwHaDB80R7iFJ5OF-6E62g,4811
|
32
|
+
app/repos/error.py,sha256=c3Bs2QTktMuJWGSRF8rKeTN5vFEsaOycUdYD7QSIDEc,4224
|
33
|
+
app/repos/feature.py,sha256=uR4s-n28J4WCO4Npi6AzOxk5R9I6HuUMHDzoK1Xo_80,4361
|
34
|
+
app/services/__init__.py,sha256=CIyUCm2oFrhZvCLPCPz3UG-eghdkIBgqayxoOr-QrdE,151
|
35
|
+
app/services/cli.py,sha256=aqrn7kxqe2xTJWBSs5hDiyD0ND50mPVDIJf_C87YgRk,5364
|
36
|
+
app/services/container.py,sha256=yZU09pziCMz74UIRqiM_gHNqNE4Hml555WEuNoJlEDA,1048
|
37
|
+
tiferet-1.0.0a0.dist-info/LICENSE,sha256=e8_GutFM0sxbRlgUaeVsGvJ5uE-KvruLApOzIoHy_zU,1513
|
38
|
+
tiferet-1.0.0a0.dist-info/METADATA,sha256=kxGZQgEojSufeAWAvLtuL0RV4-Z58KIBcI9hUkbQ5kE,386
|
39
|
+
tiferet-1.0.0a0.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
40
|
+
tiferet-1.0.0a0.dist-info/top_level.txt,sha256=io9g7LCbfmTG1SFKgEOGXmCFB9uMP2H5lerm0HiHWQE,4
|
41
|
+
tiferet-1.0.0a0.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
app
|