encommon 0.9.0__tar.gz → 0.11.0__tar.gz
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.
- {encommon-0.9.0/encommon.egg-info → encommon-0.11.0}/PKG-INFO +1 -1
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/__init__.py +3 -3
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/config.py +28 -2
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/files.py +3 -3
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/logger.py +37 -6
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/params.py +24 -4
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/paths.py +2 -2
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/test/test_logger.py +3 -0
- encommon-0.9.0/encommon/config/test/test_common.py → encommon-0.11.0/encommon/config/test/test_utils.py +3 -3
- encommon-0.9.0/encommon/config/common.py → encommon-0.11.0/encommon/config/utils.py +1 -10
- {encommon-0.9.0 → encommon-0.11.0}/encommon/conftest.py +4 -4
- {encommon-0.9.0 → encommon-0.11.0}/encommon/crypts/crypts.py +23 -22
- {encommon-0.9.0 → encommon-0.11.0}/encommon/crypts/params.py +15 -2
- {encommon-0.9.0 → encommon-0.11.0}/encommon/crypts/test/test_crypts.py +8 -20
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/__init__.py +14 -2
- encommon-0.11.0/encommon/times/common.py +63 -0
- encommon-0.11.0/encommon/times/params.py +155 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/parse.py +5 -5
- encommon-0.11.0/encommon/times/test/test_params.py +64 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/test/test_parse.py +1 -1
- encommon-0.11.0/encommon/times/test/test_timer.py +86 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/test/test_timers.py +87 -36
- encommon-0.9.0/encommon/times/test/test_common.py → encommon-0.11.0/encommon/times/test/test_utils.py +3 -3
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/test/test_window.py +101 -51
- encommon-0.11.0/encommon/times/test/test_windows.py +264 -0
- encommon-0.11.0/encommon/times/timer.py +147 -0
- encommon-0.11.0/encommon/times/timers.py +392 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/times.py +6 -6
- encommon-0.9.0/encommon/times/common.py → encommon-0.11.0/encommon/times/utils.py +24 -66
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/window.py +124 -85
- encommon-0.11.0/encommon/times/windows.py +459 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/types/__init__.py +6 -0
- encommon-0.11.0/encommon/types/notate.py +319 -0
- encommon-0.11.0/encommon/types/test/__init__.py +43 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/types/test/test_dicts.py +23 -28
- encommon-0.11.0/encommon/types/test/test_notate.py +217 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/__init__.py +2 -2
- encommon-0.11.0/encommon/utils/common.py +33 -0
- encommon-0.9.0/encommon/utils/common.py → encommon-0.11.0/encommon/utils/files.py +22 -23
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/paths.py +1 -1
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/sample.py +2 -2
- encommon-0.9.0/encommon/utils/test/test_common.py → encommon-0.11.0/encommon/utils/test/test_files.py +2 -2
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/test/test_paths.py +2 -1
- encommon-0.11.0/encommon/version.txt +1 -0
- {encommon-0.9.0 → encommon-0.11.0/encommon.egg-info}/PKG-INFO +1 -1
- {encommon-0.9.0 → encommon-0.11.0}/encommon.egg-info/SOURCES.txt +14 -4
- {encommon-0.9.0 → encommon-0.11.0}/setup.cfg +3 -1
- encommon-0.9.0/encommon/times/timers.py +0 -318
- encommon-0.9.0/encommon/utils/test/__init__.py +0 -6
- encommon-0.9.0/encommon/version.txt +0 -1
- {encommon-0.9.0 → encommon-0.11.0}/LICENSE +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/MANIFEST.in +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/README.md +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/__init__.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/test/__init__.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/test/test_config.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/test/test_files.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/config/test/test_paths.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/crypts/__init__.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/crypts/hashes.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/crypts/test/__init__.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/crypts/test/test_hashes.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/py.typed +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/duration.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/test/__init__.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/test/test_duration.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/times/test/test_times.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/types/dicts.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/types/empty.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/types/strings.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/types/test/test_empty.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/types/test/test_strings.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/match.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/stdout.py +0 -0
- {encommon-0.9.0/encommon/types → encommon-0.11.0/encommon/utils}/test/__init__.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/test/test_match.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/test/test_sample.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon/utils/test/test_stdout.py +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon.egg-info/dependency_links.txt +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon.egg-info/requires.txt +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/encommon.egg-info/top_level.txt +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/pyproject.toml +0 -0
- {encommon-0.9.0 → encommon-0.11.0}/reqs-install.txt +0 -0
@@ -7,9 +7,6 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
-
from .common import config_load
|
11
|
-
from .common import config_path
|
12
|
-
from .common import config_paths
|
13
10
|
from .config import Config
|
14
11
|
from .files import ConfigFile
|
15
12
|
from .files import ConfigFiles
|
@@ -20,6 +17,9 @@ from .params import LoggerParams
|
|
20
17
|
from .params import Params
|
21
18
|
from .paths import ConfigPath
|
22
19
|
from .paths import ConfigPaths
|
20
|
+
from .utils import config_load
|
21
|
+
from .utils import config_path
|
22
|
+
from .utils import config_paths
|
23
23
|
|
24
24
|
|
25
25
|
|
@@ -13,13 +13,14 @@ from typing import Callable
|
|
13
13
|
from typing import Optional
|
14
14
|
from typing import TYPE_CHECKING
|
15
15
|
|
16
|
-
from .common import config_paths
|
17
16
|
from .files import ConfigFiles
|
18
17
|
from .logger import Logger
|
19
18
|
from .params import Params
|
20
19
|
from .paths import ConfigPaths
|
20
|
+
from .utils import config_paths
|
21
21
|
from ..crypts import Crypts
|
22
22
|
from ..types import merge_dicts
|
23
|
+
from ..types import setate
|
23
24
|
|
24
25
|
if TYPE_CHECKING:
|
25
26
|
from ..utils.common import PATHABLE
|
@@ -34,6 +35,16 @@ class Config:
|
|
34
35
|
Configuration loaded from files is validated with the
|
35
36
|
Pydantic model :class:`encommon.config.Params`.
|
36
37
|
|
38
|
+
.. testsetup::
|
39
|
+
>>> from pathlib import Path
|
40
|
+
>>> path = str(getfixture('tmpdir'))
|
41
|
+
|
42
|
+
Example
|
43
|
+
-------
|
44
|
+
>>> config = Config()
|
45
|
+
>>> config.config
|
46
|
+
{'enconfig': None, 'enlogger': None, 'encrypts': None}
|
47
|
+
|
37
48
|
:param files: Complete or relative path to config files.
|
38
49
|
:param paths: Complete or relative path to config paths.
|
39
50
|
:param cargs: Configuration arguments in dictionary form,
|
@@ -124,7 +135,16 @@ class Config:
|
|
124
135
|
:returns: Value for the attribute from class instance.
|
125
136
|
"""
|
126
137
|
|
127
|
-
|
138
|
+
returned: dict[str, Any] = {}
|
139
|
+
|
140
|
+
cargs = deepcopy(self.__cargs)
|
141
|
+
|
142
|
+
items = cargs.items()
|
143
|
+
|
144
|
+
for key, value in items:
|
145
|
+
setate(returned, key, value)
|
146
|
+
|
147
|
+
return deepcopy(returned)
|
128
148
|
|
129
149
|
|
130
150
|
@property
|
@@ -190,6 +210,8 @@ class Config:
|
|
190
210
|
) -> Logger:
|
191
211
|
"""
|
192
212
|
Initialize the Python logging library using parameters.
|
213
|
+
|
214
|
+
:returns: Instance of Python logging library created.
|
193
215
|
"""
|
194
216
|
|
195
217
|
if self.__logger is not None:
|
@@ -210,6 +232,8 @@ class Config:
|
|
210
232
|
) -> Crypts:
|
211
233
|
"""
|
212
234
|
Initialize the encryption instance using the parameters.
|
235
|
+
|
236
|
+
:returns: Instance of the encryption instance created.
|
213
237
|
"""
|
214
238
|
|
215
239
|
if self.__crypts is not None:
|
@@ -218,6 +242,8 @@ class Config:
|
|
218
242
|
encrypts = (
|
219
243
|
self.params.encrypts)
|
220
244
|
|
245
|
+
assert encrypts is not None
|
246
|
+
|
221
247
|
self.__crypts = (
|
222
248
|
Crypts(params=encrypts))
|
223
249
|
|
@@ -13,9 +13,9 @@ from typing import Any
|
|
13
13
|
from typing import Optional
|
14
14
|
from typing import TYPE_CHECKING
|
15
15
|
|
16
|
-
from .
|
17
|
-
from .
|
18
|
-
from .
|
16
|
+
from .utils import config_load
|
17
|
+
from .utils import config_path
|
18
|
+
from .utils import config_paths
|
19
19
|
from ..types import merge_dicts
|
20
20
|
|
21
21
|
if TYPE_CHECKING:
|
@@ -26,8 +26,7 @@ from typing import Literal
|
|
26
26
|
from typing import Optional
|
27
27
|
from typing import TYPE_CHECKING
|
28
28
|
|
29
|
-
from .
|
30
|
-
from .common import config_path
|
29
|
+
from .utils import config_path
|
31
30
|
from ..times import Times
|
32
31
|
from ..types import Empty
|
33
32
|
from ..types.strings import COMMAD
|
@@ -45,6 +44,13 @@ if TYPE_CHECKING:
|
|
45
44
|
LOGR_FILE = 'encommon.logger.file'
|
46
45
|
LOGR_STDO = 'encommon.logger.stdo'
|
47
46
|
|
47
|
+
LOGLEVELS = Literal[
|
48
|
+
'critical',
|
49
|
+
'debug',
|
50
|
+
'error',
|
51
|
+
'info',
|
52
|
+
'warning']
|
53
|
+
|
48
54
|
LOGSEVERS = {
|
49
55
|
'critical': int(CRITICAL),
|
50
56
|
'debug': int(DEBUG),
|
@@ -270,6 +276,7 @@ class FileFormatter(Formatter):
|
|
270
276
|
Specifically overrides method for formatting exceptions.
|
271
277
|
|
272
278
|
:param ei: Exception information provided by the logger.
|
279
|
+
:returns: String representation for the filesystem path.
|
273
280
|
"""
|
274
281
|
|
275
282
|
reason = super().formatException(ei)
|
@@ -316,6 +323,8 @@ class Logger:
|
|
316
323
|
:param params: Parameters for instantiating the instance.
|
317
324
|
"""
|
318
325
|
|
326
|
+
__params: 'LoggerParams'
|
327
|
+
|
319
328
|
__stdo_level: Optional[LOGLEVELS]
|
320
329
|
__file_level: Optional[LOGLEVELS]
|
321
330
|
__file_path: Optional[Path]
|
@@ -338,10 +347,19 @@ class Logger:
|
|
338
347
|
Initialize instance for class using provided parameters.
|
339
348
|
"""
|
340
349
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
350
|
+
from .params import LoggerParams
|
351
|
+
|
352
|
+
if params is None:
|
353
|
+
params = LoggerParams(
|
354
|
+
stdo_level=stdo_level,
|
355
|
+
file_level=file_level,
|
356
|
+
file_path=file_path)
|
357
|
+
|
358
|
+
self.__params = params
|
359
|
+
|
360
|
+
stdo_level = params.stdo_level
|
361
|
+
file_level = params.file_level
|
362
|
+
file_path = params.file_path
|
345
363
|
|
346
364
|
if file_path is not None:
|
347
365
|
file_path = config_path(file_path)
|
@@ -359,6 +377,19 @@ class Logger:
|
|
359
377
|
self.__logr_file = logr_file
|
360
378
|
|
361
379
|
|
380
|
+
@property
|
381
|
+
def params(
|
382
|
+
self,
|
383
|
+
) -> 'LoggerParams':
|
384
|
+
"""
|
385
|
+
Return the Pydantic model containing the configuration.
|
386
|
+
|
387
|
+
:returns: Pydantic model containing the configuration.
|
388
|
+
"""
|
389
|
+
|
390
|
+
return self.__params
|
391
|
+
|
392
|
+
|
362
393
|
@property
|
363
394
|
def stdo_level(
|
364
395
|
self,
|
@@ -7,18 +7,19 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from pathlib import Path
|
10
11
|
from typing import Optional
|
11
12
|
|
12
13
|
from pydantic import BaseModel
|
13
14
|
|
14
|
-
from .
|
15
|
+
from .logger import LOGLEVELS
|
15
16
|
from ..crypts import CryptsParams
|
16
17
|
|
17
18
|
|
18
19
|
|
19
20
|
class ConfigParams(BaseModel, extra='forbid'):
|
20
21
|
"""
|
21
|
-
Process and validate the
|
22
|
+
Process and validate the core configuration parameters.
|
22
23
|
|
23
24
|
:param paths: Complete or relative path to config paths.
|
24
25
|
:param data: Keyword arguments passed to Pydantic model.
|
@@ -31,7 +32,7 @@ class ConfigParams(BaseModel, extra='forbid'):
|
|
31
32
|
|
32
33
|
class LoggerParams(BaseModel, extra='forbid'):
|
33
34
|
"""
|
34
|
-
Process and validate the
|
35
|
+
Process and validate the core configuration parameters.
|
35
36
|
|
36
37
|
:param stdo_level: Minimum level for the message to pass.
|
37
38
|
:param file_level: Minimum level for the message to pass.
|
@@ -45,10 +46,29 @@ class LoggerParams(BaseModel, extra='forbid'):
|
|
45
46
|
file_path: Optional[str] = None
|
46
47
|
|
47
48
|
|
49
|
+
def __init__(
|
50
|
+
self,
|
51
|
+
stdo_level: Optional[LOGLEVELS] = None,
|
52
|
+
file_level: Optional[LOGLEVELS] = None,
|
53
|
+
file_path: Optional[str | Path] = None,
|
54
|
+
) -> None:
|
55
|
+
"""
|
56
|
+
Initialize instance for class using provided parameters.
|
57
|
+
"""
|
58
|
+
|
59
|
+
if file_path is not None:
|
60
|
+
file_path = str(file_path)
|
61
|
+
|
62
|
+
super().__init__(
|
63
|
+
stdo_level=stdo_level,
|
64
|
+
file_level=file_level,
|
65
|
+
file_path=file_path)
|
66
|
+
|
67
|
+
|
48
68
|
|
49
69
|
class Params(BaseModel, extra='forbid'):
|
50
70
|
"""
|
51
|
-
Process and validate the
|
71
|
+
Process and validate the core configuration parameters.
|
52
72
|
|
53
73
|
:param enconfig: Configuration for the Config instance.
|
54
74
|
:param enlogger: Configuration for the Logger instance.
|
@@ -14,9 +14,9 @@ from typing import Any
|
|
14
14
|
from typing import Optional
|
15
15
|
from typing import TYPE_CHECKING
|
16
16
|
|
17
|
-
from .common import config_path
|
18
|
-
from .common import config_paths
|
19
17
|
from .files import ConfigFile
|
18
|
+
from .utils import config_path
|
19
|
+
from .utils import config_paths
|
20
20
|
|
21
21
|
if TYPE_CHECKING:
|
22
22
|
from ..utils.common import PATHABLE
|
@@ -142,6 +142,7 @@ def test_Logger(
|
|
142
142
|
attrs = list(logger.__dict__)
|
143
143
|
|
144
144
|
assert attrs == [
|
145
|
+
'_Logger__params',
|
145
146
|
'_Logger__stdo_level',
|
146
147
|
'_Logger__file_level',
|
147
148
|
'_Logger__file_path',
|
@@ -161,6 +162,8 @@ def test_Logger(
|
|
161
162
|
logger)
|
162
163
|
|
163
164
|
|
165
|
+
assert logger.params is not None
|
166
|
+
|
164
167
|
assert logger.stdo_level == 'info'
|
165
168
|
|
166
169
|
assert logger.file_level == 'info'
|
@@ -7,9 +7,9 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
-
from ..
|
11
|
-
from ..
|
12
|
-
from ..
|
10
|
+
from ..utils import config_load
|
11
|
+
from ..utils import config_path
|
12
|
+
from ..utils import config_paths
|
13
13
|
from ... import PROJECT
|
14
14
|
from ... import WORKSPACE
|
15
15
|
|
@@ -9,7 +9,6 @@ is permitted, for more information consult the project license file.
|
|
9
9
|
|
10
10
|
from pathlib import Path
|
11
11
|
from typing import Any
|
12
|
-
from typing import Literal
|
13
12
|
from typing import Optional
|
14
13
|
from typing import TYPE_CHECKING
|
15
14
|
|
@@ -28,15 +27,6 @@ if TYPE_CHECKING:
|
|
28
27
|
|
29
28
|
|
30
29
|
|
31
|
-
LOGLEVELS = Literal[
|
32
|
-
'critical',
|
33
|
-
'debug',
|
34
|
-
'error',
|
35
|
-
'info',
|
36
|
-
'warning']
|
37
|
-
|
38
|
-
|
39
|
-
|
40
30
|
def config_load(
|
41
31
|
path: str | Path,
|
42
32
|
) -> dict[str, Any]:
|
@@ -90,6 +80,7 @@ def config_paths(
|
|
90
80
|
This function simply wraps one from utils subpackage.
|
91
81
|
|
92
82
|
:param paths: Complete or relative paths for processing.
|
83
|
+
:param replace: Optional values to replace in the path.
|
93
84
|
:returns: New resolved filesystem path object instances.
|
94
85
|
"""
|
95
86
|
|
@@ -38,14 +38,14 @@ def config_factory(
|
|
38
38
|
' stdo_level: info\n'
|
39
39
|
'encrypts:\n'
|
40
40
|
' phrases:\n'
|
41
|
-
' default
|
41
|
+
' default:\n'
|
42
|
+
' phrase: phrase\n'))
|
42
43
|
|
43
44
|
config_log = f'{tmp_path}/config.log'
|
44
45
|
|
45
46
|
cargs = {
|
46
|
-
'enlogger':
|
47
|
-
|
48
|
-
'file_level': 'info'}}
|
47
|
+
'enlogger/file_path': config_log,
|
48
|
+
'enlogger/file_level': 'info'}
|
49
49
|
|
50
50
|
return Config(
|
51
51
|
files=f'{tmp_path}/config.yml',
|
@@ -10,7 +10,6 @@ is permitted, for more information consult the project license file.
|
|
10
10
|
from re import compile
|
11
11
|
from re import match as re_match
|
12
12
|
from re import sub as re_sub
|
13
|
-
from typing import Optional
|
14
13
|
from typing import TYPE_CHECKING
|
15
14
|
|
16
15
|
from cryptography.fernet import Fernet
|
@@ -31,52 +30,49 @@ class Crypts:
|
|
31
30
|
"""
|
32
31
|
Encrypt and decrypt values using passphrase dictionary.
|
33
32
|
|
33
|
+
.. testsetup::
|
34
|
+
>>> from .params import CryptsParams
|
35
|
+
|
34
36
|
Example
|
35
37
|
-------
|
36
38
|
>>> phrase = Crypts.keygen()
|
37
|
-
>>>
|
39
|
+
>>> source = {'default': {'phrase': phrase}}
|
40
|
+
>>> params = CryptsParams(phrases=source)
|
41
|
+
>>> crypts = Crypts(params)
|
38
42
|
>>> encrypt = crypts.encrypt('example')
|
43
|
+
>>> encrypt
|
44
|
+
'$ENCRYPT;1.0;default;...
|
39
45
|
>>> crypts.decrypt(encrypt)
|
40
46
|
'example'
|
41
47
|
|
42
|
-
:param phrases: Passphrases that are used in operations.
|
43
48
|
:param params: Parameters for instantiating the instance.
|
44
49
|
"""
|
45
50
|
|
46
|
-
|
51
|
+
__params: 'CryptsParams'
|
47
52
|
|
48
53
|
|
49
54
|
def __init__(
|
50
55
|
self,
|
51
|
-
|
52
|
-
params: Optional['CryptsParams'] = None,
|
56
|
+
params: 'CryptsParams',
|
53
57
|
) -> None:
|
54
58
|
"""
|
55
59
|
Initialize instance for class using provided parameters.
|
56
60
|
"""
|
57
61
|
|
58
|
-
|
59
|
-
|
60
|
-
if params is not None:
|
61
|
-
phrases |= params.phrases
|
62
|
-
|
63
|
-
if 'default' not in phrases:
|
64
|
-
raise ValueError('default')
|
65
|
-
|
66
|
-
self.__phrases = dict(phrases)
|
62
|
+
self.__params = params
|
67
63
|
|
68
64
|
|
69
65
|
@property
|
70
|
-
def
|
66
|
+
def params(
|
71
67
|
self,
|
72
|
-
) ->
|
68
|
+
) -> 'CryptsParams':
|
73
69
|
"""
|
74
|
-
Return the
|
70
|
+
Return the Pydantic model containing the configuration.
|
75
71
|
|
76
|
-
:returns:
|
72
|
+
:returns: Pydantic model containing the configuration.
|
77
73
|
"""
|
78
74
|
|
79
|
-
return
|
75
|
+
return self.__params
|
80
76
|
|
81
77
|
|
82
78
|
def encrypt(
|
@@ -92,7 +88,9 @@ class Crypts:
|
|
92
88
|
:returns: Encrypted value using the relevant passphrase.
|
93
89
|
"""
|
94
90
|
|
95
|
-
|
91
|
+
phrases = self.params.phrases
|
92
|
+
|
93
|
+
phrase = phrases[unique].phrase
|
96
94
|
|
97
95
|
encrypt = (
|
98
96
|
Fernet(phrase)
|
@@ -115,6 +113,8 @@ class Crypts:
|
|
115
113
|
:returns: Decrypted value using the relevant passphrase.
|
116
114
|
"""
|
117
115
|
|
116
|
+
phrases = self.params.phrases
|
117
|
+
|
118
118
|
value = crypt_clean(value)
|
119
119
|
|
120
120
|
if not re_match(ENCRYPT, value):
|
@@ -126,7 +126,7 @@ class Crypts:
|
|
126
126
|
if version != '1.0':
|
127
127
|
raise ValueError('version')
|
128
128
|
|
129
|
-
phrase =
|
129
|
+
phrase = phrases[unique].phrase
|
130
130
|
|
131
131
|
return (
|
132
132
|
Fernet(phrase)
|
@@ -157,6 +157,7 @@ def crypt_clean(
|
|
157
157
|
Return the parsed and normalized encrypted string value.
|
158
158
|
|
159
159
|
:param value: String value that will returned decrypted.
|
160
|
+
:returns: Parsed and normalized encrypted string value.
|
160
161
|
"""
|
161
162
|
|
162
163
|
return re_sub(r'[\n\s]', SEMPTY, value)
|
@@ -11,13 +11,26 @@ from pydantic import BaseModel
|
|
11
11
|
|
12
12
|
|
13
13
|
|
14
|
+
class CryptParams(BaseModel, extra='forbid'):
|
15
|
+
"""
|
16
|
+
Process and validate the core configuration parameters.
|
17
|
+
|
18
|
+
:param phrase: Passphrases that are used in operations.
|
19
|
+
:param data: Keyword arguments passed to Pydantic model.
|
20
|
+
Parameter is picked up by autodoc, please ignore.
|
21
|
+
"""
|
22
|
+
|
23
|
+
phrase: str
|
24
|
+
|
25
|
+
|
26
|
+
|
14
27
|
class CryptsParams(BaseModel, extra='forbid'):
|
15
28
|
"""
|
16
|
-
Process and validate the
|
29
|
+
Process and validate the core configuration parameters.
|
17
30
|
|
18
31
|
:param phrases: Passphrases that are used in operations.
|
19
32
|
:param data: Keyword arguments passed to Pydantic model.
|
20
33
|
Parameter is picked up by autodoc, please ignore.
|
21
34
|
"""
|
22
35
|
|
23
|
-
phrases: dict[str,
|
36
|
+
phrases: dict[str, CryptParams]
|
@@ -7,6 +7,8 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from typing import Any
|
11
|
+
|
10
12
|
from pytest import fixture
|
11
13
|
from pytest import mark
|
12
14
|
from pytest import raises
|
@@ -26,12 +28,12 @@ def crypts() -> Crypts:
|
|
26
28
|
:returns: Newly constructed instance of related class.
|
27
29
|
"""
|
28
30
|
|
29
|
-
|
30
|
-
'default': Crypts.keygen(),
|
31
|
-
'secrets': Crypts.keygen()}
|
31
|
+
source: dict[str, Any] = {
|
32
|
+
'default': {'phrase': Crypts.keygen()},
|
33
|
+
'secrets': {'phrase': Crypts.keygen()}}
|
32
34
|
|
33
35
|
params = CryptsParams(
|
34
|
-
phrases=
|
36
|
+
phrases=source)
|
35
37
|
|
36
38
|
return Crypts(params=params)
|
37
39
|
|
@@ -50,7 +52,7 @@ def test_Crypts(
|
|
50
52
|
attrs = list(crypts.__dict__)
|
51
53
|
|
52
54
|
assert attrs == [
|
53
|
-
'
|
55
|
+
'_Crypts__params']
|
54
56
|
|
55
57
|
|
56
58
|
assert inrepr(
|
@@ -64,7 +66,7 @@ def test_Crypts(
|
|
64
66
|
crypts)
|
65
67
|
|
66
68
|
|
67
|
-
assert
|
69
|
+
assert crypts.params is not None
|
68
70
|
|
69
71
|
assert len(crypts.keygen()) == 44
|
70
72
|
|
@@ -111,20 +113,6 @@ def test_Crypts_raises(
|
|
111
113
|
"""
|
112
114
|
|
113
115
|
|
114
|
-
_raises = raises(ValueError)
|
115
|
-
|
116
|
-
with _raises as reason:
|
117
|
-
Crypts({'foo': 'bar'})
|
118
|
-
|
119
|
-
_reason = str(reason.value)
|
120
|
-
|
121
|
-
assert _reason == 'default'
|
122
|
-
|
123
|
-
|
124
|
-
crypts = Crypts(
|
125
|
-
crypts.phrases)
|
126
|
-
|
127
|
-
|
128
116
|
_raises = raises(ValueError)
|
129
117
|
|
130
118
|
with _raises as reason:
|
@@ -7,24 +7,36 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
-
from .common import findtz
|
11
10
|
from .duration import Duration
|
11
|
+
from .params import TimerParams
|
12
|
+
from .params import TimersParams
|
13
|
+
from .params import WindowParams
|
14
|
+
from .params import WindowsParams
|
12
15
|
from .parse import parse_time
|
13
16
|
from .parse import shift_time
|
14
17
|
from .parse import since_time
|
15
18
|
from .parse import string_time
|
19
|
+
from .timer import Timer
|
16
20
|
from .timers import Timers
|
17
21
|
from .times import Times
|
22
|
+
from .utils import findtz
|
18
23
|
from .window import Window
|
24
|
+
from .windows import Windows
|
19
25
|
|
20
26
|
|
21
27
|
|
22
28
|
__all__ = [
|
23
29
|
'Duration',
|
24
|
-
'
|
30
|
+
'Timer',
|
31
|
+
'TimerParams',
|
25
32
|
'Timers',
|
33
|
+
'TimersParams',
|
26
34
|
'Times',
|
27
35
|
'Window',
|
36
|
+
'WindowParams',
|
37
|
+
'Windows',
|
38
|
+
'WindowsParams',
|
39
|
+
'findtz',
|
28
40
|
'parse_time',
|
29
41
|
'shift_time',
|
30
42
|
'since_time',
|
@@ -0,0 +1,63 @@
|
|
1
|
+
"""
|
2
|
+
Functions and routines associated with Enasis Network Common Library.
|
3
|
+
|
4
|
+
This file is part of Enasis Network software eco-system. Distribution
|
5
|
+
is permitted, for more information consult the project license file.
|
6
|
+
"""
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
from datetime import datetime
|
11
|
+
from re import compile
|
12
|
+
from typing import TYPE_CHECKING
|
13
|
+
from typing import Union
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from .times import Times
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
NUMERISH = compile(
|
21
|
+
r'^\-?\d+(\.\d+)?$')
|
22
|
+
|
23
|
+
SNAPABLE = compile(
|
24
|
+
r'^(\-|\+)[\d\@a-z\-\+]+$')
|
25
|
+
|
26
|
+
STRINGNOW = {
|
27
|
+
'None', 'null', 'now'}
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
NUMERIC = Union[int, float]
|
32
|
+
|
33
|
+
PARSABLE = Union[
|
34
|
+
str, NUMERIC,
|
35
|
+
datetime, 'Times']
|
36
|
+
|
37
|
+
SCHEDULE = Union[
|
38
|
+
str, dict[str, int]]
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
UNIXEPOCH = (
|
43
|
+
'1970-01-01T00:00:00+0000')
|
44
|
+
|
45
|
+
UNIXMPOCH = (
|
46
|
+
'1970-01-01T00:00:00.000000+0000')
|
47
|
+
|
48
|
+
UNIXSPOCH = (
|
49
|
+
'1970-01-01T00:00:00Z')
|
50
|
+
|
51
|
+
UNIXHPOCH = (
|
52
|
+
'01/01/1970 12:00AM UTC')
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
STAMP_SIMPLE = (
|
57
|
+
'%Y-%m-%dT%H:%M:%S%z')
|
58
|
+
|
59
|
+
STAMP_SUBSEC = (
|
60
|
+
'%Y-%m-%dT%H:%M:%S.%f%z')
|
61
|
+
|
62
|
+
STAMP_HUMAN = (
|
63
|
+
'%m/%d/%Y %I:%M%p %Z')
|