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
tiferet/contexts/app.py
CHANGED
@@ -1,104 +1,48 @@
|
|
1
1
|
# *** imports
|
2
2
|
|
3
3
|
# ** core
|
4
|
-
from typing import Dict, Any
|
4
|
+
from typing import Dict, Any
|
5
5
|
|
6
6
|
# ** app
|
7
|
-
from .request import RequestContext
|
8
7
|
from .feature import FeatureContext
|
9
8
|
from .error import ErrorContext
|
10
|
-
from .
|
11
|
-
from ..
|
12
|
-
|
13
|
-
|
9
|
+
from ..models.feature import Request
|
10
|
+
from ..commands import (
|
11
|
+
Command,
|
12
|
+
ModelObject,
|
13
|
+
import_dependency,
|
14
|
+
TiferetError
|
15
|
+
)
|
16
|
+
from ..commands.app import (
|
17
|
+
AppInterface,
|
18
|
+
AppRepository,
|
19
|
+
ImportAppRepository
|
20
|
+
)
|
21
|
+
from ..commands.dependencies import create_injector, Injector
|
14
22
|
|
15
23
|
|
16
24
|
# *** contexts
|
17
25
|
|
18
26
|
# ** context: app_context
|
19
|
-
class AppContext(
|
20
|
-
|
21
|
-
# * attribute: app_repo_module_path
|
22
|
-
app_repo_module_path = StringType(
|
23
|
-
required=True,
|
24
|
-
default='tiferet.repos.app',
|
25
|
-
metadata=dict(
|
26
|
-
description='The application repository module path.'
|
27
|
-
),
|
28
|
-
)
|
29
|
-
|
30
|
-
# * attribute: app_repo_class_name
|
31
|
-
app_repo_class_name = StringType(
|
32
|
-
required=True,
|
33
|
-
default='AppYamlProxy',
|
34
|
-
metadata=dict(
|
35
|
-
description='The application repository class name.'
|
36
|
-
),
|
37
|
-
)
|
38
|
-
|
39
|
-
# * attribute: app_repo_parameters
|
40
|
-
app_repo_parameters = DictType(
|
41
|
-
StringType(),
|
42
|
-
default=dict(
|
43
|
-
app_config_file='app/configs/app.yml'
|
44
|
-
),
|
45
|
-
metadata=dict(
|
46
|
-
description='The application repository parameters.'
|
47
|
-
),
|
48
|
-
)
|
27
|
+
class AppContext(object):
|
49
28
|
|
50
|
-
# *
|
51
|
-
|
52
|
-
'''
|
53
|
-
Run the application interface.
|
54
|
-
|
55
|
-
:param interface_id: The interface ID.
|
56
|
-
:type interface_id: str
|
57
|
-
:param dependencies: The dependencies.
|
58
|
-
:type dependencies: dict
|
59
|
-
:param kwargs: Additional keyword arguments.
|
60
|
-
:type kwargs: dict
|
61
|
-
:return: The response.
|
62
|
-
:rtype: Any
|
63
|
-
'''
|
64
|
-
|
65
|
-
# Load the interface.
|
66
|
-
app_interface = self.load_interface(interface_id, **dependencies)
|
29
|
+
# * attribute: settings
|
30
|
+
settings: Dict[str, Any]
|
67
31
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
# * method: load_interface
|
72
|
-
def load_interface(self, interface_id: str, **dependencies) -> AppInterface:
|
32
|
+
# * method: init
|
33
|
+
def __init__(self, settings: Dict[str, Any] = {}):
|
73
34
|
'''
|
74
|
-
|
75
|
-
|
76
|
-
:param
|
77
|
-
:type
|
78
|
-
:param dependencies: The dependencies.
|
79
|
-
:type dependencies: dict
|
80
|
-
:return: The application interface.
|
81
|
-
:rtype: AppInterface
|
35
|
+
Initialize the application context.
|
36
|
+
|
37
|
+
:param settings: The application settings.
|
38
|
+
:type settings: dict
|
82
39
|
'''
|
83
40
|
|
84
|
-
#
|
85
|
-
|
86
|
-
self.app_repo_module_path,
|
87
|
-
self.app_repo_class_name,
|
88
|
-
**self.app_repo_parameters
|
89
|
-
)
|
90
|
-
|
91
|
-
# Get the app interface.
|
92
|
-
app_interface = app_repo.get_interface(interface_id)
|
93
|
-
|
94
|
-
# Create the injector.
|
95
|
-
injector = self.create_injector(app_interface, **dependencies)
|
96
|
-
|
97
|
-
# Load the app interface context.
|
98
|
-
return getattr(injector, 'app_context')
|
41
|
+
# Assign settings attribute.
|
42
|
+
self.settings = settings
|
99
43
|
|
100
44
|
# * method: import_app_repo
|
101
|
-
def import_app_repo(self
|
45
|
+
def import_app_repo(self) -> AppRepository:
|
102
46
|
'''
|
103
47
|
Import the app repository.
|
104
48
|
|
@@ -112,92 +56,140 @@ class AppContext(Model):
|
|
112
56
|
:rtype: AppRepository
|
113
57
|
'''
|
114
58
|
|
115
|
-
#
|
116
|
-
|
117
|
-
|
59
|
+
# Run and return the import app repository command.
|
60
|
+
return Command.handle(
|
61
|
+
ImportAppRepository,
|
62
|
+
**self.settings
|
63
|
+
)
|
64
|
+
|
65
|
+
# * method: get_interface_settings
|
66
|
+
def get_interface_settings(self, interface_id: str) -> AppInterface:
|
67
|
+
'''
|
68
|
+
Get the settings for the application interface.
|
118
69
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
# ** method: create_injector
|
124
|
-
def create_injector(self, app_interface: AppInterface, **kwargs) -> Any:
|
70
|
+
:param interface_id: The interface ID.
|
71
|
+
:type interface_id: str
|
72
|
+
:return: The application interface settings.
|
73
|
+
:rtype: AppInterface
|
125
74
|
'''
|
126
|
-
|
75
|
+
|
76
|
+
# Import the app repository.
|
77
|
+
app_repo = self.import_app_repo()
|
78
|
+
|
79
|
+
# Get the app interface.
|
80
|
+
return app_repo.get_interface(interface_id)
|
81
|
+
|
82
|
+
# ** method: create_app_injector
|
83
|
+
def create_app_injector(self, app_interface: AppInterface) -> Injector:
|
84
|
+
'''
|
85
|
+
Create the app dependency injector.
|
127
86
|
|
128
87
|
:param app_interface: The app interface.
|
129
88
|
:type app_interface: AppInterface
|
130
89
|
:param kwargs: Additional keyword arguments.
|
131
90
|
:type kwargs: dict
|
132
|
-
:return: The injector.
|
133
|
-
:rtype:
|
91
|
+
:return: The dependencies injector.
|
92
|
+
:rtype: Injector
|
134
93
|
'''
|
135
94
|
|
136
95
|
# Retrieve the app context dependency.
|
137
|
-
app_context = app_interface.get_dependency('app_context')
|
138
|
-
|
139
|
-
# Get the dependencies for the app interface.
|
140
96
|
dependencies = dict(
|
97
|
+
app_context=import_dependency.execute(
|
98
|
+
app_interface.module_path,
|
99
|
+
app_interface.class_name,
|
100
|
+
)
|
101
|
+
)
|
102
|
+
|
103
|
+
# Add the remaining app context attributes.
|
104
|
+
for attr in app_interface.attributes:
|
105
|
+
dependencies[attr.attribute_id] = import_dependency.execute(
|
106
|
+
attr.module_path,
|
107
|
+
attr.class_name,
|
108
|
+
)
|
109
|
+
|
110
|
+
# Create the injector.
|
111
|
+
injector = create_injector.execute(
|
112
|
+
app_interface.id,
|
113
|
+
dependencies,
|
141
114
|
interface_id=app_interface.id,
|
142
|
-
app_name=app_interface.name,
|
143
|
-
feature_flag=app_interface.feature_flag,
|
144
|
-
data_flag=app_interface.data_flag,
|
145
|
-
app_context=import_dependency(
|
146
|
-
app_context.module_path,
|
147
|
-
app_context.class_name,
|
148
|
-
),
|
149
115
|
**app_interface.constants
|
150
116
|
)
|
151
117
|
|
152
|
-
#
|
153
|
-
|
118
|
+
# Return the injector.
|
119
|
+
return injector
|
120
|
+
|
121
|
+
# * method: load_interface
|
122
|
+
def load_interface(self, interface_id: str) -> 'AppInterfaceContext':
|
123
|
+
'''
|
124
|
+
Load the application interface.
|
154
125
|
|
155
|
-
|
156
|
-
|
126
|
+
:param interface_id: The interface ID.
|
127
|
+
:type interface_id: str
|
128
|
+
:return: The application interface context.
|
129
|
+
:rtype: AppInterfaceContext
|
130
|
+
'''
|
131
|
+
|
132
|
+
# Get the app interface.
|
133
|
+
app_interface = self.get_interface_settings(interface_id)
|
134
|
+
|
135
|
+
# Create the app injector.
|
136
|
+
injector = self.create_app_injector(app_interface)
|
137
|
+
|
138
|
+
# Load the app interface context.
|
139
|
+
return getattr(injector, 'app_context')
|
140
|
+
|
141
|
+
# * method: run
|
142
|
+
def run(self,
|
143
|
+
interface_id: str,
|
144
|
+
feature_id: str,
|
145
|
+
headers: Dict[str, str] = {},
|
146
|
+
data: Dict[str, Any] = {},
|
147
|
+
debug: bool = False,
|
148
|
+
**kwargs
|
149
|
+
) -> Any:
|
150
|
+
'''
|
151
|
+
Run the application interface.
|
152
|
+
|
153
|
+
:param interface_id: The interface ID.
|
154
|
+
:type interface_id: str
|
155
|
+
:param dependencies: The dependencies.
|
156
|
+
:type dependencies: dict
|
157
|
+
:param kwargs: Additional keyword arguments.
|
158
|
+
:type kwargs: dict
|
159
|
+
:return: The response.
|
160
|
+
:rtype: Any
|
161
|
+
'''
|
162
|
+
|
163
|
+
# Load the interface.
|
164
|
+
app_interface = self.load_interface(interface_id)
|
165
|
+
|
166
|
+
# Run the interface.
|
167
|
+
return app_interface.run(
|
168
|
+
feature_id,
|
169
|
+
headers,
|
170
|
+
data,
|
171
|
+
debug=debug,
|
172
|
+
**kwargs
|
173
|
+
)
|
157
174
|
|
158
175
|
|
159
176
|
# ** context: app_interface_context
|
160
|
-
class AppInterfaceContext(
|
177
|
+
class AppInterfaceContext(object):
|
161
178
|
'''
|
162
179
|
The application interface context is a class that is used to create and run the application interface.
|
163
180
|
'''
|
164
181
|
|
165
182
|
# * attribute: interface_id
|
166
|
-
interface_id
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
# * attribute: name
|
174
|
-
name = StringType(
|
175
|
-
required=True,
|
176
|
-
metadata=dict(
|
177
|
-
description='The application name.'
|
178
|
-
),
|
179
|
-
)
|
180
|
-
|
181
|
-
# * field: features
|
182
|
-
features = ModelType(
|
183
|
-
FeatureContext,
|
184
|
-
required=True,
|
185
|
-
metadata=dict(
|
186
|
-
description='The feature context.'
|
187
|
-
),
|
188
|
-
)
|
189
|
-
|
190
|
-
# * field: errors
|
191
|
-
errors = ModelType(
|
192
|
-
ErrorContext,
|
193
|
-
required=True,
|
194
|
-
metadata=dict(
|
195
|
-
description='The error context.'
|
196
|
-
),
|
197
|
-
)
|
183
|
+
interface_id: str
|
184
|
+
|
185
|
+
# * attribute: features
|
186
|
+
features: FeatureContext
|
187
|
+
|
188
|
+
# * attribute: errors
|
189
|
+
errors: ErrorContext
|
198
190
|
|
199
191
|
# * method: init
|
200
|
-
def __init__(self, interface_id: str,
|
192
|
+
def __init__(self, interface_id: str, features: FeatureContext, errors: ErrorContext):
|
201
193
|
'''
|
202
194
|
Initialize the application interface context.
|
203
195
|
|
@@ -205,85 +197,126 @@ class AppInterfaceContext(Model):
|
|
205
197
|
:type interface_id: str
|
206
198
|
:param app_name: The application name.
|
207
199
|
:type app_name: str
|
208
|
-
:param
|
209
|
-
:type
|
210
|
-
:param
|
211
|
-
:type
|
200
|
+
:param features: The feature context.
|
201
|
+
:type features: FeatureContext
|
202
|
+
:param errors: The error context.
|
203
|
+
:type errors: ErrorContext
|
212
204
|
'''
|
213
205
|
|
214
|
-
#
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
))
|
219
|
-
self.features = feature_context
|
220
|
-
self.errors = error_context
|
206
|
+
# Assign instance variables.
|
207
|
+
self.interface_id = interface_id
|
208
|
+
self.features = features
|
209
|
+
self.errors = errors
|
221
210
|
|
222
211
|
# * method: parse_request
|
223
|
-
def parse_request(self,
|
212
|
+
def parse_request(self, headers: Dict[str, str] = {}, data: Dict[str, Any] = {}) -> Request:
|
224
213
|
'''
|
225
214
|
Parse the incoming request.
|
226
215
|
|
227
|
-
:param
|
228
|
-
:type
|
229
|
-
:param
|
230
|
-
:type
|
231
|
-
:return: The request
|
232
|
-
:rtype:
|
216
|
+
:param headers: The request headers.
|
217
|
+
:type headers: dict
|
218
|
+
:param data: The request data.
|
219
|
+
:type data: dict
|
220
|
+
:return: The parsed request.
|
221
|
+
:rtype: Request
|
233
222
|
'''
|
234
223
|
|
235
|
-
#
|
236
|
-
|
224
|
+
# Add the interface id to the request headers.
|
225
|
+
headers.update(dict(
|
226
|
+
interface_id=self.interface_id,
|
227
|
+
))
|
228
|
+
|
229
|
+
# Create the request model object.
|
230
|
+
request = ModelObject.new(
|
231
|
+
Request,
|
232
|
+
headers=headers,
|
233
|
+
data=data,
|
234
|
+
)
|
235
|
+
|
236
|
+
# Return the request model object.
|
237
|
+
return request
|
237
238
|
|
238
239
|
# * method: execute_feature
|
239
|
-
def execute_feature(self, request:
|
240
|
+
def execute_feature(self, feature_id: str, request: Request, **kwargs):
|
240
241
|
'''
|
241
242
|
Execute the feature context.
|
242
243
|
|
243
|
-
:param
|
244
|
-
:type
|
244
|
+
:param feature_id: The feature identifier.
|
245
|
+
:type feature_id: str
|
246
|
+
:param request: The request.
|
247
|
+
:type request: Request
|
248
|
+
:param kwargs: Additional keyword arguments.
|
249
|
+
:type kwargs: dict
|
245
250
|
'''
|
246
251
|
|
252
|
+
# Add the feature id to the request headers.
|
253
|
+
request.headers.update(dict(
|
254
|
+
feature_id=feature_id
|
255
|
+
))
|
256
|
+
|
247
257
|
# Execute feature context and return session.
|
248
|
-
self.features.
|
249
|
-
|
258
|
+
self.features.execute_feature(feature_id, request, **kwargs)
|
259
|
+
|
260
|
+
# * method: handle_error
|
261
|
+
def handle_error(self, error: Exception) -> Any:
|
262
|
+
'''
|
263
|
+
Handle the error and return the response.
|
264
|
+
|
265
|
+
:param error: The error to handle.
|
266
|
+
:type error: Exception
|
267
|
+
:return: The error response.
|
268
|
+
:rtype: Any
|
269
|
+
'''
|
270
|
+
|
271
|
+
# Print the error to the console.
|
272
|
+
print('Error:', error)
|
273
|
+
|
274
|
+
# Handle the error and return the response.
|
275
|
+
return self.errors.handle_error(error)
|
276
|
+
|
250
277
|
# * method: handle_response
|
251
|
-
def handle_response(self, request:
|
278
|
+
def handle_response(self, request: Request) -> Any:
|
252
279
|
'''
|
253
|
-
Handle the response.
|
280
|
+
Handle the response from the request.
|
254
281
|
|
255
282
|
:param request: The request context.
|
256
283
|
:type request: RequestContext
|
257
284
|
:return: The response.
|
258
285
|
:rtype: Any
|
259
286
|
'''
|
260
|
-
|
261
|
-
# Import the JSON module.
|
262
|
-
import json
|
263
287
|
|
264
|
-
#
|
265
|
-
return
|
288
|
+
# Handle the response and return it.
|
289
|
+
return request.handle_response()
|
266
290
|
|
267
291
|
# * method: run
|
268
|
-
def run(self,
|
292
|
+
def run(self,
|
293
|
+
feature_id: str,
|
294
|
+
headers: Dict[str, str] = {},
|
295
|
+
data: Dict[str, Any] = {},
|
296
|
+
**kwargs) -> Any:
|
269
297
|
'''
|
270
|
-
Run the application interface.
|
271
|
-
|
298
|
+
Run the application interface by executing the feature.
|
299
|
+
|
300
|
+
:param feature_id: The feature identifier.
|
301
|
+
:type feature_id: str
|
302
|
+
:param headers: The request headers.
|
303
|
+
:type headers: dict
|
304
|
+
:param data: The request data.
|
305
|
+
:type data: dict
|
272
306
|
:param kwargs: Additional keyword arguments.
|
273
307
|
:type kwargs: dict
|
274
308
|
'''
|
275
309
|
|
276
310
|
# Parse request.
|
277
|
-
request
|
311
|
+
request = self.parse_request(headers, data)
|
278
312
|
|
279
313
|
# Execute feature context and return session.
|
280
314
|
try:
|
281
|
-
self.execute_feature(request, **kwargs)
|
315
|
+
self.execute_feature(feature_id, request, **kwargs)
|
282
316
|
|
283
317
|
# Handle error and return response if triggered.
|
284
|
-
except
|
285
|
-
|
286
|
-
return self.errors.handle_error(e)
|
318
|
+
except TiferetError as e:
|
319
|
+
return self.handle_error(e)
|
287
320
|
|
288
321
|
# Handle response.
|
289
322
|
return self.handle_response(request)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# *** imports
|
2
|
+
|
3
|
+
# ** core
|
4
|
+
from typing import Dict, Any
|
5
|
+
|
6
|
+
# ** app
|
7
|
+
from ..configs import *
|
8
|
+
|
9
|
+
|
10
|
+
# *** contexts
|
11
|
+
|
12
|
+
# ** context: cache_context
|
13
|
+
class CacheContext(object):
|
14
|
+
'''
|
15
|
+
A context for managing cache operations within Tiferet applications.
|
16
|
+
'''
|
17
|
+
|
18
|
+
# * attribute: cache (private)
|
19
|
+
_cache = Dict[str, Any]
|
20
|
+
|
21
|
+
# * method: init
|
22
|
+
def __init__(self, cache: Dict[str, Any] = {}):
|
23
|
+
'''
|
24
|
+
Initialize the cache context.
|
25
|
+
:param cache: An optional initial cache dictionary.
|
26
|
+
:type cache: dict
|
27
|
+
'''
|
28
|
+
|
29
|
+
# Initialize the cache with the provided dictionary.
|
30
|
+
self._cache = cache
|
31
|
+
|
32
|
+
# * method: get
|
33
|
+
def get(self, key: str) -> Any:
|
34
|
+
'''
|
35
|
+
Retrieve an item from the cache.
|
36
|
+
:param key: The key of the item to retrieve.
|
37
|
+
:type key: str
|
38
|
+
:return: The cached item or None if not found.
|
39
|
+
:rtype: Any
|
40
|
+
'''
|
41
|
+
|
42
|
+
# Return the item from the cache.
|
43
|
+
return self._cache.get(key)
|
44
|
+
|
45
|
+
# * method: set
|
46
|
+
def set(self, key: str, value: Any):
|
47
|
+
'''
|
48
|
+
Store an item in the cache.
|
49
|
+
:param key: The key to store the value under.
|
50
|
+
:type key: str
|
51
|
+
:param value: The value to store.
|
52
|
+
:type value: Any
|
53
|
+
'''
|
54
|
+
|
55
|
+
# Store the value in the cache.
|
56
|
+
self._cache[key] = value
|
57
|
+
|
58
|
+
# * method: delete
|
59
|
+
def delete(self, key: str):
|
60
|
+
'''
|
61
|
+
Remove an item from the cache.
|
62
|
+
:param key: The key of the item to remove.
|
63
|
+
:type key: str
|
64
|
+
'''
|
65
|
+
|
66
|
+
# Remove the item from the cache.
|
67
|
+
self._cache.pop(key, None)
|
68
|
+
|
69
|
+
# * method: clear
|
70
|
+
def clear(self):
|
71
|
+
'''
|
72
|
+
Clear all items from the cache.
|
73
|
+
'''
|
74
|
+
|
75
|
+
# Clear the cache.
|
76
|
+
self._cache.clear()
|