tiferet 1.0.0a19__py3-none-any.whl → 1.0.0b0__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/__init__.py +3 -2
- tiferet/commands/__init__.py +6 -0
- tiferet/commands/app.py +102 -0
- tiferet/commands/core.py +124 -0
- tiferet/commands/dependencies.py +76 -0
- tiferet/commands/settings.py +101 -0
- tiferet/configs/__init__.py +3 -67
- tiferet/configs/error.py +48 -0
- tiferet/configs/settings.py +37 -0
- tiferet/contexts/__init__.py +0 -8
- tiferet/contexts/app.py +215 -182
- tiferet/contexts/cache.py +76 -0
- tiferet/contexts/container.py +92 -190
- tiferet/contexts/error.py +78 -80
- tiferet/contexts/feature.py +120 -83
- tiferet/contracts/__init__.py +4 -0
- tiferet/contracts/app.py +92 -0
- tiferet/contracts/cache.py +70 -0
- tiferet/contracts/container.py +147 -0
- tiferet/contracts/error.py +177 -0
- tiferet/contracts/feature.py +159 -0
- tiferet/contracts/settings.py +34 -0
- tiferet/data/__init__.py +3 -4
- tiferet/data/app.py +71 -208
- tiferet/data/container.py +52 -38
- tiferet/data/error.py +15 -24
- tiferet/data/feature.py +27 -8
- tiferet/{domain/core.py → data/settings.py} +36 -96
- tiferet/handlers/__init__.py +0 -0
- tiferet/handlers/container.py +116 -0
- tiferet/handlers/error.py +49 -0
- tiferet/handlers/feature.py +94 -0
- tiferet/models/__init__.py +4 -0
- tiferet/models/app.py +150 -0
- tiferet/models/container.py +135 -0
- tiferet/{domain → models}/error.py +86 -36
- tiferet/{domain → models}/feature.py +107 -47
- tiferet/models/settings.py +148 -0
- tiferet/proxies/__init__.py +0 -0
- tiferet/proxies/yaml/__init__.py +0 -0
- tiferet/{repos → proxies/yaml}/app.py +13 -41
- tiferet/{repos → proxies/yaml}/container.py +26 -56
- tiferet/{repos → proxies/yaml}/error.py +11 -70
- tiferet/proxies/yaml/feature.py +92 -0
- {tiferet-1.0.0a19.dist-info → tiferet-1.0.0b0.dist-info}/METADATA +12 -3
- tiferet-1.0.0b0.dist-info/RECORD +51 -0
- {tiferet-1.0.0a19.dist-info → tiferet-1.0.0b0.dist-info}/WHEEL +1 -1
- tiferet/commands/container.py +0 -54
- tiferet/commands/error.py +0 -21
- tiferet/commands/feature.py +0 -90
- tiferet/contexts/request.py +0 -110
- tiferet/domain/__init__.py +0 -5
- tiferet/domain/app.py +0 -131
- tiferet/domain/container.py +0 -141
- tiferet/repos/__init__.py +0 -7
- tiferet/repos/feature.py +0 -151
- tiferet-1.0.0a19.dist-info/RECORD +0 -35
- {tiferet-1.0.0a19.dist-info → tiferet-1.0.0b0.dist-info/licenses}/LICENSE +0 -0
- {tiferet-1.0.0a19.dist-info → tiferet-1.0.0b0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
# *** imports
|
2
|
+
|
3
|
+
# ** app
|
4
|
+
from .settings import *
|
5
|
+
|
6
|
+
|
7
|
+
# *** models
|
8
|
+
|
9
|
+
# ** model: flagged_dependency
|
10
|
+
class FlaggedDependency(ValueObject):
|
11
|
+
'''
|
12
|
+
A flagged container dependency object.
|
13
|
+
'''
|
14
|
+
|
15
|
+
# * attribute: module_path
|
16
|
+
module_path = StringType(
|
17
|
+
required=True,
|
18
|
+
metadata=dict(
|
19
|
+
description='The module path.'
|
20
|
+
)
|
21
|
+
)
|
22
|
+
|
23
|
+
# * attribute: class_name
|
24
|
+
class_name = StringType(
|
25
|
+
required=True,
|
26
|
+
metadata=dict(
|
27
|
+
description='The class name.'
|
28
|
+
)
|
29
|
+
)
|
30
|
+
|
31
|
+
# * attribute: flag
|
32
|
+
flag = StringType(
|
33
|
+
required=True,
|
34
|
+
metadata=dict(
|
35
|
+
description='The flag for the container dependency.'
|
36
|
+
)
|
37
|
+
)
|
38
|
+
|
39
|
+
# * attribute: parameters
|
40
|
+
parameters = DictType(
|
41
|
+
StringType,
|
42
|
+
default={},
|
43
|
+
metadata=dict(
|
44
|
+
description='The container dependency parameters.'
|
45
|
+
)
|
46
|
+
)
|
47
|
+
|
48
|
+
|
49
|
+
# ** model: container_attribute
|
50
|
+
class ContainerAttribute(Entity):
|
51
|
+
'''
|
52
|
+
An attribute that defines container injectior behavior.
|
53
|
+
'''
|
54
|
+
|
55
|
+
# * attribute: id
|
56
|
+
id = StringType(
|
57
|
+
required=True,
|
58
|
+
metadata=dict(
|
59
|
+
description='The unique identifier for the container attribute.'
|
60
|
+
)
|
61
|
+
)
|
62
|
+
|
63
|
+
# * attribute: module_path
|
64
|
+
module_path = StringType(
|
65
|
+
metadata=dict(
|
66
|
+
description='The non-flagged module path for the container attribute.'
|
67
|
+
)
|
68
|
+
)
|
69
|
+
|
70
|
+
# * attribute: class_name
|
71
|
+
class_name = StringType(
|
72
|
+
metadata=dict(
|
73
|
+
description='The non-flagged class name for the container attribute.'
|
74
|
+
)
|
75
|
+
)
|
76
|
+
|
77
|
+
# * attribute: parameters
|
78
|
+
parameters = DictType(
|
79
|
+
StringType,
|
80
|
+
default={},
|
81
|
+
metadata=dict(
|
82
|
+
description='The container attribute parameters.'
|
83
|
+
)
|
84
|
+
)
|
85
|
+
|
86
|
+
# * attribute: dependencies
|
87
|
+
dependencies = ListType(
|
88
|
+
ModelType(FlaggedDependency),
|
89
|
+
default=[],
|
90
|
+
metadata=dict(
|
91
|
+
description='The container attribute dependencies.'
|
92
|
+
)
|
93
|
+
)
|
94
|
+
|
95
|
+
# * method: get_dependency
|
96
|
+
def get_dependency(self, *flags) -> FlaggedDependency:
|
97
|
+
'''
|
98
|
+
Gets a flagged container dependency by flag.
|
99
|
+
|
100
|
+
:param flags: The flags for the flagged container dependency.
|
101
|
+
:type flags: Tuple[str, ...]
|
102
|
+
:return: The flagged container dependency that matches the first provided flag.
|
103
|
+
:rtype: FlaggedDependency
|
104
|
+
'''
|
105
|
+
|
106
|
+
# Return the first dependency that matches any of the provided flags.
|
107
|
+
# Input flags are assumed ordinal in priority, so the first match is returned.
|
108
|
+
for flag in flags:
|
109
|
+
match = next(
|
110
|
+
(dependency for dependency in self.dependencies if dependency.flag == flag),
|
111
|
+
None
|
112
|
+
)
|
113
|
+
if match:
|
114
|
+
return match
|
115
|
+
|
116
|
+
# Return None if no dependency matches the flags.
|
117
|
+
return None
|
118
|
+
|
119
|
+
# * method: set_dependency
|
120
|
+
def set_dependency(self, dependency: FlaggedDependency):
|
121
|
+
'''
|
122
|
+
Sets a flagged container dependency.
|
123
|
+
|
124
|
+
:param dependency: The flagged container dependency to set.
|
125
|
+
:type dependency: ContainerDependency
|
126
|
+
'''
|
127
|
+
|
128
|
+
# Replace the value of the dependency if a dependency with the same flag exists.
|
129
|
+
for index, dep in enumerate(self.dependencies):
|
130
|
+
if dep.flag == dependency.flag:
|
131
|
+
self.dependencies[index] = dependency
|
132
|
+
return
|
133
|
+
|
134
|
+
# Append the dependency otherwise.
|
135
|
+
self.dependencies.append(dependency)
|
@@ -1,19 +1,22 @@
|
|
1
1
|
# *** imports
|
2
2
|
|
3
3
|
# ** core
|
4
|
-
from
|
4
|
+
from typing import List, Any
|
5
|
+
|
6
|
+
# ** app
|
7
|
+
from .settings import *
|
5
8
|
|
6
9
|
|
7
10
|
# *** models
|
8
11
|
|
9
|
-
# ** model:
|
12
|
+
# ** model: error_message
|
10
13
|
class ErrorMessage(ValueObject):
|
11
14
|
'''
|
12
15
|
An error message object.
|
13
16
|
'''
|
14
17
|
|
15
18
|
# * attribute: lang
|
16
|
-
lang =
|
19
|
+
lang = StringType(
|
17
20
|
required=True,
|
18
21
|
metadata=dict(
|
19
22
|
description='The language of the error message text.'
|
@@ -21,30 +24,13 @@ class ErrorMessage(ValueObject):
|
|
21
24
|
)
|
22
25
|
|
23
26
|
# * attribute: text
|
24
|
-
text =
|
27
|
+
text = StringType(
|
25
28
|
required=True,
|
26
29
|
metadata=dict(
|
27
30
|
description='The error message text.'
|
28
31
|
)
|
29
32
|
)
|
30
33
|
|
31
|
-
# * method: new
|
32
|
-
@staticmethod
|
33
|
-
def new(**kwargs) -> 'ErrorMessage':
|
34
|
-
'''Initializes a new ErrorMessage object.
|
35
|
-
|
36
|
-
:param kwargs: Additional keyword arguments.
|
37
|
-
:type kwargs: dict
|
38
|
-
:return: A new ErrorMessage object.
|
39
|
-
:rtype: ErrorMessage
|
40
|
-
'''
|
41
|
-
|
42
|
-
# Create and return a new ErrorMessage object.
|
43
|
-
return super(ErrorMessage, ErrorMessage).new(
|
44
|
-
ErrorMessage,
|
45
|
-
**kwargs
|
46
|
-
)
|
47
|
-
|
48
34
|
# * method: format
|
49
35
|
def format(self, *args) -> str:
|
50
36
|
'''
|
@@ -71,7 +57,7 @@ class Error(Entity):
|
|
71
57
|
'''
|
72
58
|
|
73
59
|
# * attribute: name
|
74
|
-
name =
|
60
|
+
name = StringType(
|
75
61
|
required=True,
|
76
62
|
metadata=dict(
|
77
63
|
description='The name of the error.'
|
@@ -79,15 +65,15 @@ class Error(Entity):
|
|
79
65
|
)
|
80
66
|
|
81
67
|
# * attribute: error_code
|
82
|
-
error_code =
|
68
|
+
error_code = StringType(
|
83
69
|
metadata=dict(
|
84
70
|
description='The unique code of the error.'
|
85
71
|
)
|
86
72
|
)
|
87
73
|
|
88
74
|
# * attribute: message
|
89
|
-
message =
|
90
|
-
|
75
|
+
message = ListType(
|
76
|
+
ModelType(ErrorMessage),
|
91
77
|
required=True,
|
92
78
|
metadata=dict(
|
93
79
|
description='The error message translations for the error.'
|
@@ -96,7 +82,7 @@ class Error(Entity):
|
|
96
82
|
|
97
83
|
# * method: new
|
98
84
|
@staticmethod
|
99
|
-
def new(name: str, id: str = None, error_code: str = None, **kwargs) -> 'Error':
|
85
|
+
def new(name: str, id: str = None, error_code: str = None, message: List[ErrorMessage | Any] = [], **kwargs) -> 'Error':
|
100
86
|
'''Initializes a new Error object.
|
101
87
|
|
102
88
|
:param name: The name of the error.
|
@@ -105,33 +91,42 @@ class Error(Entity):
|
|
105
91
|
:type id: str
|
106
92
|
:param error_code: The error code for the error.
|
107
93
|
:type error_code: str
|
94
|
+
:param message: The error message translations for the error.
|
95
|
+
:type message: list
|
108
96
|
:param kwargs: Additional keyword arguments.
|
109
97
|
:type kwargs: dict
|
110
98
|
:return: A new Error object.
|
111
99
|
'''
|
112
|
-
|
113
|
-
# Format name as upper case snake case.
|
114
|
-
name = name.upper().replace(' ', '_')
|
115
100
|
|
116
|
-
# Set Id as the name if not provided.
|
101
|
+
# Set Id as the name lower cased if not provided.
|
117
102
|
if not id:
|
118
|
-
id = name
|
103
|
+
id = name.lower().replace(' ', '_')
|
119
104
|
|
120
|
-
# Set the error code as the
|
105
|
+
# Set the error code as the id upper cased if not provided.
|
121
106
|
if not error_code:
|
122
|
-
error_code =
|
107
|
+
error_code = id.upper().replace(' ', '_')
|
108
|
+
|
109
|
+
# Convert any error message dicts to ErrorMessage objects.
|
110
|
+
message_objs = []
|
111
|
+
for msg in message:
|
112
|
+
if isinstance(msg, ErrorMessage):
|
113
|
+
message_objs.append(msg)
|
114
|
+
elif not isinstance(msg, ErrorMessage) and isinstance(msg, dict):
|
115
|
+
message_objs.append(ValueObject.new(ErrorMessage, **msg))
|
116
|
+
|
123
117
|
|
124
118
|
# Create and return a new Error object.
|
125
|
-
return
|
119
|
+
return Entity.new(
|
126
120
|
Error,
|
127
121
|
id=id,
|
128
122
|
name=name,
|
129
123
|
error_code=error_code,
|
124
|
+
message=message_objs,
|
130
125
|
**kwargs
|
131
126
|
)
|
132
127
|
|
133
|
-
# * method:
|
134
|
-
def
|
128
|
+
# * method: format_message
|
129
|
+
def format_message(self, lang: str = 'en_US', *args) -> str:
|
135
130
|
'''
|
136
131
|
Formats the error message text for the specified language.
|
137
132
|
|
@@ -152,3 +147,58 @@ class Error(Entity):
|
|
152
147
|
|
153
148
|
# Format the error message text.
|
154
149
|
return msg.format(*args)
|
150
|
+
|
151
|
+
# * method: format_response
|
152
|
+
def format_response(self, lang: str = 'en_US', *args, **kwargs) -> Any:
|
153
|
+
'''
|
154
|
+
Formats the error response for the specified language.
|
155
|
+
|
156
|
+
:param lang: The language of the error message text.
|
157
|
+
:type lang: str
|
158
|
+
:param args: The format arguments for the error message text.
|
159
|
+
:type args: tuple
|
160
|
+
:param kwargs: Additional keyword arguments.
|
161
|
+
:type kwargs: dict
|
162
|
+
:return: The formatted error response.
|
163
|
+
:rtype: dict
|
164
|
+
'''
|
165
|
+
|
166
|
+
# Format the error message text.
|
167
|
+
error_message = self.format_message(lang, *args)
|
168
|
+
|
169
|
+
# If the error message is not found, return no response.
|
170
|
+
if not error_message:
|
171
|
+
return None
|
172
|
+
|
173
|
+
# Return the formatted error response.
|
174
|
+
return dict(
|
175
|
+
error_code=self.error_code,
|
176
|
+
message=error_message,
|
177
|
+
**kwargs
|
178
|
+
)
|
179
|
+
|
180
|
+
# * method: set_message
|
181
|
+
def set_message(self, lang: str, text: str):
|
182
|
+
'''
|
183
|
+
Sets the error message text for the specified language.
|
184
|
+
|
185
|
+
:param lang: The language of the error message text.
|
186
|
+
:type lang: str
|
187
|
+
:param text: The error message text.
|
188
|
+
:type text: str
|
189
|
+
'''
|
190
|
+
|
191
|
+
# Check if the message already exists for the language.
|
192
|
+
for msg in self.message:
|
193
|
+
if msg.lang == lang:
|
194
|
+
msg.text = text
|
195
|
+
return
|
196
|
+
|
197
|
+
# If not, create a new ErrorMessage object and add it to the message list.
|
198
|
+
self.message.append(
|
199
|
+
ValueObject.new(
|
200
|
+
ErrorMessage,
|
201
|
+
lang=lang,
|
202
|
+
text=text
|
203
|
+
)
|
204
|
+
)
|
@@ -1,11 +1,88 @@
|
|
1
1
|
# *** imports
|
2
2
|
|
3
|
+
# ** core
|
4
|
+
from typing import Any
|
5
|
+
import json
|
6
|
+
|
3
7
|
# ** app
|
4
|
-
from
|
8
|
+
from .settings import *
|
5
9
|
|
6
10
|
|
7
11
|
# *** models
|
8
12
|
|
13
|
+
# ** model: request
|
14
|
+
class Request(ValueObject):
|
15
|
+
'''
|
16
|
+
A request object.
|
17
|
+
'''
|
18
|
+
|
19
|
+
# * attribute: headers
|
20
|
+
headers = DictType(
|
21
|
+
StringType(),
|
22
|
+
metadata=dict(
|
23
|
+
description='The request headers.'
|
24
|
+
)
|
25
|
+
)
|
26
|
+
|
27
|
+
# * attribute: data
|
28
|
+
data = DictType(
|
29
|
+
StringType(),
|
30
|
+
metadata=dict(
|
31
|
+
description='The request data.'
|
32
|
+
)
|
33
|
+
)
|
34
|
+
|
35
|
+
# * attribute: result
|
36
|
+
result = StringType(
|
37
|
+
metadata=dict(
|
38
|
+
description='The request result.'
|
39
|
+
)
|
40
|
+
)
|
41
|
+
|
42
|
+
# * method: set_result
|
43
|
+
def set_result(self, result: Any):
|
44
|
+
# Set the result as a serialized empty dictionary if it is None.
|
45
|
+
if not result:
|
46
|
+
self.result = json.dumps({})
|
47
|
+
return
|
48
|
+
|
49
|
+
# If the result is a Model, convert it to a primitive dictionary and serialize it.
|
50
|
+
if isinstance(result, ModelObject):
|
51
|
+
self.result = json.dumps(result.to_primitive())
|
52
|
+
return
|
53
|
+
|
54
|
+
# If the result is not a list, it must be a dict, so serialize it and set it.
|
55
|
+
if type(result) != list:
|
56
|
+
self.result = json.dumps(result)
|
57
|
+
return
|
58
|
+
|
59
|
+
# If the result is a list, convert each item to a primitive dictionary.
|
60
|
+
result_list = []
|
61
|
+
for item in result:
|
62
|
+
if isinstance(item, ModelObject):
|
63
|
+
result_list.append(item.to_primitive())
|
64
|
+
else:
|
65
|
+
result_list.append(item)
|
66
|
+
|
67
|
+
# Serialize the result and set it.
|
68
|
+
self.result = json.dumps(result_list)
|
69
|
+
|
70
|
+
# * method: handle_response
|
71
|
+
def handle_response(self, **kwargs) -> Any:
|
72
|
+
'''
|
73
|
+
Handle the response.
|
74
|
+
|
75
|
+
:param kwargs: Additional keyword arguments.
|
76
|
+
:type kwargs: dict
|
77
|
+
:return: The response object.
|
78
|
+
:rtype: Any
|
79
|
+
'''
|
80
|
+
|
81
|
+
# Deserialize the result.
|
82
|
+
# Return None if the result is None.
|
83
|
+
return json.loads(self.result) if self.result else None
|
84
|
+
|
85
|
+
|
9
86
|
# ** model: feature_command
|
10
87
|
class FeatureCommand(ValueObject):
|
11
88
|
'''
|
@@ -13,7 +90,7 @@ class FeatureCommand(ValueObject):
|
|
13
90
|
'''
|
14
91
|
|
15
92
|
# * attribute: name
|
16
|
-
name =
|
93
|
+
name = StringType(
|
17
94
|
required=True,
|
18
95
|
metadata=dict(
|
19
96
|
description='The name of the feature handler.'
|
@@ -21,62 +98,44 @@ class FeatureCommand(ValueObject):
|
|
21
98
|
)
|
22
99
|
|
23
100
|
# * attribute: attribute_id
|
24
|
-
attribute_id =
|
101
|
+
attribute_id = StringType(
|
25
102
|
required=True,
|
26
103
|
metadata=dict(
|
27
104
|
description='The container attribute ID for the feature command.'
|
28
105
|
)
|
29
106
|
)
|
30
107
|
|
31
|
-
# * attribute:
|
32
|
-
|
33
|
-
|
108
|
+
# * attribute: parameters
|
109
|
+
parameters = DictType(
|
110
|
+
StringType(),
|
34
111
|
default={},
|
35
112
|
metadata=dict(
|
36
113
|
description='The custom parameters for the feature handler.'
|
37
114
|
)
|
38
115
|
)
|
39
116
|
|
40
|
-
# * attribute: return_to_data
|
41
|
-
return_to_data =
|
117
|
+
# * attribute: return_to_data (obsolete)
|
118
|
+
return_to_data = BooleanType(
|
119
|
+
default=False,
|
42
120
|
metadata=dict(
|
43
121
|
description='Whether to return the feature command result to the feature data context.'
|
44
122
|
)
|
45
123
|
)
|
46
124
|
|
47
125
|
# * attribute: data_key
|
48
|
-
data_key =
|
126
|
+
data_key = StringType(
|
49
127
|
metadata=dict(
|
50
128
|
description='The data key to store the feature command result in if Return to Data is True.'
|
51
129
|
)
|
52
130
|
)
|
53
131
|
|
54
132
|
# * attribute: pass_on_error
|
55
|
-
pass_on_error =
|
133
|
+
pass_on_error = BooleanType(
|
56
134
|
metadata=dict(
|
57
135
|
description='Whether to pass on the error if the feature handler fails.'
|
58
136
|
)
|
59
137
|
)
|
60
138
|
|
61
|
-
# * method: new
|
62
|
-
@staticmethod
|
63
|
-
def new(**kwargs) -> 'FeatureCommand':
|
64
|
-
'''Initializes a new FeatureCommand object.
|
65
|
-
|
66
|
-
:param kwargs: Additional keyword arguments.
|
67
|
-
:type kwargs: dict
|
68
|
-
:return: A new FeatureCommand object.
|
69
|
-
'''
|
70
|
-
|
71
|
-
# Create a new FeatureCommand object.
|
72
|
-
obj = FeatureCommand(dict(
|
73
|
-
**kwargs
|
74
|
-
), strict=False)
|
75
|
-
|
76
|
-
# Validate and return the new FeatureCommand object.
|
77
|
-
obj.validate()
|
78
|
-
return obj
|
79
|
-
|
80
139
|
|
81
140
|
# ** model: feature
|
82
141
|
class Feature(Entity):
|
@@ -85,7 +144,7 @@ class Feature(Entity):
|
|
85
144
|
'''
|
86
145
|
|
87
146
|
# * attribute: name
|
88
|
-
name =
|
147
|
+
name = StringType(
|
89
148
|
required=True,
|
90
149
|
metadata=dict(
|
91
150
|
description='The name of the feature.'
|
@@ -93,23 +152,23 @@ class Feature(Entity):
|
|
93
152
|
)
|
94
153
|
|
95
154
|
# * attribute: group_id
|
96
|
-
group_id =
|
155
|
+
group_id = StringType(
|
97
156
|
required=True,
|
98
157
|
metadata=dict(
|
99
158
|
description='The context group identifier for the feature.'
|
100
159
|
)
|
101
160
|
)
|
102
161
|
|
103
|
-
|
104
|
-
|
162
|
+
feature_key = StringType(
|
163
|
+
required=True,
|
105
164
|
metadata=dict(
|
106
|
-
description='The
|
165
|
+
description='The key of the feature.'
|
107
166
|
)
|
108
167
|
)
|
109
168
|
|
110
169
|
# * attribute: commands
|
111
|
-
commands =
|
112
|
-
|
170
|
+
commands = ListType(
|
171
|
+
ModelType(FeatureCommand),
|
113
172
|
default=[],
|
114
173
|
metadata=dict(
|
115
174
|
description='The command handler workflow for the feature.'
|
@@ -117,8 +176,8 @@ class Feature(Entity):
|
|
117
176
|
)
|
118
177
|
|
119
178
|
# * attribute: log_params
|
120
|
-
log_params =
|
121
|
-
|
179
|
+
log_params = DictType(
|
180
|
+
StringType(),
|
122
181
|
default={},
|
123
182
|
metadata=dict(
|
124
183
|
description='The parameters to log for the feature.'
|
@@ -158,27 +217,28 @@ class Feature(Entity):
|
|
158
217
|
description = name
|
159
218
|
|
160
219
|
# Create and return a new Feature object.
|
161
|
-
return
|
220
|
+
return Entity.new(
|
162
221
|
Feature,
|
163
222
|
id=id,
|
164
223
|
name=name,
|
165
224
|
group_id=group_id,
|
225
|
+
feature_key=feature_key,
|
166
226
|
description=description,
|
167
227
|
**kwargs
|
168
228
|
)
|
169
229
|
|
170
|
-
# * method:
|
171
|
-
def
|
172
|
-
'''Adds a
|
230
|
+
# * method: add_command
|
231
|
+
def add_command(self, command: FeatureCommand, position: int = None):
|
232
|
+
'''Adds a service command to the feature.
|
173
233
|
|
174
|
-
:param
|
175
|
-
:type
|
234
|
+
:param command: The service command to add.
|
235
|
+
:type command: FeatureCommand
|
176
236
|
:param position: The position to add the handler at.
|
177
237
|
:type position: int
|
178
238
|
'''
|
179
239
|
|
180
|
-
# Add the
|
240
|
+
# Add the feature command to the feature.
|
181
241
|
if position is not None:
|
182
|
-
self.commands.insert(position,
|
242
|
+
self.commands.insert(position, command)
|
183
243
|
else:
|
184
|
-
self.commands.append(
|
244
|
+
self.commands.append(command)
|