encommon 0.10.0__tar.gz → 0.11.1__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.10.0/encommon.egg-info → encommon-0.11.1}/PKG-INFO +1 -1
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/__init__.py +3 -3
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/config.py +19 -7
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/files.py +3 -3
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/logger.py +39 -7
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/params.py +21 -1
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/paths.py +2 -2
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_logger.py +4 -1
- encommon-0.10.0/encommon/config/test/test_common.py → encommon-0.11.1/encommon/config/test/test_utils.py +3 -3
- encommon-0.10.0/encommon/config/common.py → encommon-0.11.1/encommon/config/utils.py +1 -10
- {encommon-0.10.0 → encommon-0.11.1}/encommon/conftest.py +2 -1
- {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/crypts.py +68 -18
- {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/params.py +14 -1
- {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/test/test_crypts.py +56 -13
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/__init__.py +14 -2
- encommon-0.11.1/encommon/times/common.py +63 -0
- encommon-0.11.1/encommon/times/params.py +155 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/parse.py +5 -5
- encommon-0.11.1/encommon/times/test/test_params.py +64 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_parse.py +1 -1
- encommon-0.11.1/encommon/times/test/test_timer.py +86 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_timers.py +81 -41
- encommon-0.10.0/encommon/times/test/test_common.py → encommon-0.11.1/encommon/times/test/test_utils.py +3 -3
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_window.py +101 -51
- encommon-0.11.1/encommon/times/test/test_windows.py +250 -0
- encommon-0.11.1/encommon/times/timer.py +147 -0
- encommon-0.11.1/encommon/times/timers.py +405 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/times.py +6 -6
- encommon-0.10.0/encommon/times/common.py → encommon-0.11.1/encommon/times/utils.py +24 -66
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/window.py +124 -85
- encommon-0.11.1/encommon/times/windows.py +472 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/notate.py +0 -2
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/__init__.py +2 -2
- encommon-0.11.1/encommon/utils/common.py +33 -0
- encommon-0.10.0/encommon/utils/common.py → encommon-0.11.1/encommon/utils/files.py +22 -23
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/paths.py +1 -1
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/sample.py +2 -2
- encommon-0.10.0/encommon/utils/test/test_common.py → encommon-0.11.1/encommon/utils/test/test_files.py +2 -2
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_paths.py +2 -1
- encommon-0.11.1/encommon/version.txt +1 -0
- {encommon-0.10.0 → encommon-0.11.1/encommon.egg-info}/PKG-INFO +1 -1
- {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/SOURCES.txt +12 -4
- {encommon-0.10.0 → encommon-0.11.1}/setup.cfg +3 -1
- encommon-0.10.0/encommon/times/timers.py +0 -318
- encommon-0.10.0/encommon/version.txt +0 -1
- {encommon-0.10.0 → encommon-0.11.1}/LICENSE +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/MANIFEST.in +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/README.md +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_config.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_files.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/config/test/test_paths.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/hashes.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/test/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/crypts/test/test_hashes.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/py.typed +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/duration.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_duration.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/times/test/test_times.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/dicts.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/empty.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/strings.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_dicts.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_empty.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_notate.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/types/test/test_strings.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/match.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/stdout.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/__init__.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_match.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_sample.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon/utils/test/test_stdout.py +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/dependency_links.txt +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/requires.txt +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/encommon.egg-info/top_level.txt +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/pyproject.toml +0 -0
- {encommon-0.10.0 → encommon-0.11.1}/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,11 +13,11 @@ 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
23
|
from ..types import setate
|
@@ -35,6 +35,16 @@ class Config:
|
|
35
35
|
Configuration loaded from files is validated with the
|
36
36
|
Pydantic model :class:`encommon.config.Params`.
|
37
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
|
+
|
38
48
|
:param files: Complete or relative path to config files.
|
39
49
|
:param paths: Complete or relative path to config paths.
|
40
50
|
:param cargs: Configuration arguments in dictionary form,
|
@@ -200,16 +210,17 @@ class Config:
|
|
200
210
|
) -> Logger:
|
201
211
|
"""
|
202
212
|
Initialize the Python logging library using parameters.
|
213
|
+
|
214
|
+
:returns: Instance of Python logging library created.
|
203
215
|
"""
|
204
216
|
|
205
217
|
if self.__logger is not None:
|
206
218
|
return self.__logger
|
207
219
|
|
208
|
-
|
220
|
+
logger = Logger(
|
209
221
|
self.params.enlogger)
|
210
222
|
|
211
|
-
self.__logger =
|
212
|
-
Logger(params=enlogger))
|
223
|
+
self.__logger = logger
|
213
224
|
|
214
225
|
return self.__logger
|
215
226
|
|
@@ -220,15 +231,16 @@ class Config:
|
|
220
231
|
) -> Crypts:
|
221
232
|
"""
|
222
233
|
Initialize the encryption instance using the parameters.
|
234
|
+
|
235
|
+
:returns: Instance of the encryption instance created.
|
223
236
|
"""
|
224
237
|
|
225
238
|
if self.__crypts is not None:
|
226
239
|
return self.__crypts
|
227
240
|
|
228
|
-
|
241
|
+
crypts = Crypts(
|
229
242
|
self.params.encrypts)
|
230
243
|
|
231
|
-
self.__crypts =
|
232
|
-
Crypts(params=encrypts))
|
244
|
+
self.__crypts = crypts
|
233
245
|
|
234
246
|
return self.__crypts
|
@@ -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:
|
@@ -7,6 +7,7 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from copy import deepcopy
|
10
11
|
from json import dumps
|
11
12
|
from logging import CRITICAL
|
12
13
|
from logging import DEBUG
|
@@ -26,8 +27,7 @@ from typing import Literal
|
|
26
27
|
from typing import Optional
|
27
28
|
from typing import TYPE_CHECKING
|
28
29
|
|
29
|
-
from .
|
30
|
-
from .common import config_path
|
30
|
+
from .utils import config_path
|
31
31
|
from ..times import Times
|
32
32
|
from ..types import Empty
|
33
33
|
from ..types.strings import COMMAD
|
@@ -45,6 +45,13 @@ if TYPE_CHECKING:
|
|
45
45
|
LOGR_FILE = 'encommon.logger.file'
|
46
46
|
LOGR_STDO = 'encommon.logger.stdo'
|
47
47
|
|
48
|
+
LOGLEVELS = Literal[
|
49
|
+
'critical',
|
50
|
+
'debug',
|
51
|
+
'error',
|
52
|
+
'info',
|
53
|
+
'warning']
|
54
|
+
|
48
55
|
LOGSEVERS = {
|
49
56
|
'critical': int(CRITICAL),
|
50
57
|
'debug': int(DEBUG),
|
@@ -270,6 +277,7 @@ class FileFormatter(Formatter):
|
|
270
277
|
Specifically overrides method for formatting exceptions.
|
271
278
|
|
272
279
|
:param ei: Exception information provided by the logger.
|
280
|
+
:returns: String representation for the filesystem path.
|
273
281
|
"""
|
274
282
|
|
275
283
|
reason = super().formatException(ei)
|
@@ -316,6 +324,8 @@ class Logger:
|
|
316
324
|
:param params: Parameters for instantiating the instance.
|
317
325
|
"""
|
318
326
|
|
327
|
+
__params: 'LoggerParams'
|
328
|
+
|
319
329
|
__stdo_level: Optional[LOGLEVELS]
|
320
330
|
__file_level: Optional[LOGLEVELS]
|
321
331
|
__file_path: Optional[Path]
|
@@ -328,20 +338,29 @@ class Logger:
|
|
328
338
|
|
329
339
|
def __init__(
|
330
340
|
self,
|
341
|
+
params: Optional['LoggerParams'] = None,
|
331
342
|
*,
|
332
343
|
stdo_level: Optional[LOGLEVELS] = None,
|
333
344
|
file_level: Optional[LOGLEVELS] = None,
|
334
345
|
file_path: Optional[str | Path] = None,
|
335
|
-
params: Optional['LoggerParams'] = None,
|
336
346
|
) -> None:
|
337
347
|
"""
|
338
348
|
Initialize instance for class using provided parameters.
|
339
349
|
"""
|
340
350
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
351
|
+
from .params import LoggerParams
|
352
|
+
|
353
|
+
if params is None:
|
354
|
+
params = LoggerParams(
|
355
|
+
stdo_level=stdo_level,
|
356
|
+
file_level=file_level,
|
357
|
+
file_path=file_path)
|
358
|
+
|
359
|
+
self.__params = deepcopy(params)
|
360
|
+
|
361
|
+
stdo_level = params.stdo_level
|
362
|
+
file_level = params.file_level
|
363
|
+
file_path = params.file_path
|
345
364
|
|
346
365
|
if file_path is not None:
|
347
366
|
file_path = config_path(file_path)
|
@@ -359,6 +378,19 @@ class Logger:
|
|
359
378
|
self.__logr_file = logr_file
|
360
379
|
|
361
380
|
|
381
|
+
@property
|
382
|
+
def params(
|
383
|
+
self,
|
384
|
+
) -> 'LoggerParams':
|
385
|
+
"""
|
386
|
+
Return the Pydantic model containing the configuration.
|
387
|
+
|
388
|
+
:returns: Pydantic model containing the configuration.
|
389
|
+
"""
|
390
|
+
|
391
|
+
return self.__params
|
392
|
+
|
393
|
+
|
362
394
|
@property
|
363
395
|
def stdo_level(
|
364
396
|
self,
|
@@ -7,11 +7,12 @@ 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
|
|
@@ -45,6 +46,25 @@ 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
|
"""
|
@@ -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
|
@@ -44,7 +44,7 @@ def logger(
|
|
44
44
|
file_level='info',
|
45
45
|
file_path=f'{tmp_path}/test.log')
|
46
46
|
|
47
|
-
return Logger(params
|
47
|
+
return Logger(params)
|
48
48
|
|
49
49
|
|
50
50
|
|
@@ -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
|
|
@@ -7,6 +7,7 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from copy import deepcopy
|
10
11
|
from re import compile
|
11
12
|
from re import match as re_match
|
12
13
|
from re import sub as re_sub
|
@@ -18,6 +19,7 @@ from cryptography.fernet import Fernet
|
|
18
19
|
from ..types.strings import SEMPTY
|
19
20
|
|
20
21
|
if TYPE_CHECKING:
|
22
|
+
from .params import CryptParams
|
21
23
|
from .params import CryptsParams
|
22
24
|
|
23
25
|
|
@@ -31,52 +33,54 @@ class Crypts:
|
|
31
33
|
"""
|
32
34
|
Encrypt and decrypt values using passphrase dictionary.
|
33
35
|
|
36
|
+
.. testsetup::
|
37
|
+
>>> from .params import CryptsParams
|
38
|
+
|
34
39
|
Example
|
35
40
|
-------
|
36
41
|
>>> phrase = Crypts.keygen()
|
37
|
-
>>>
|
42
|
+
>>> source = {'default': {'phrase': phrase}}
|
43
|
+
>>> params = CryptsParams(phrases=source)
|
44
|
+
>>> crypts = Crypts(params)
|
38
45
|
>>> encrypt = crypts.encrypt('example')
|
46
|
+
>>> encrypt
|
47
|
+
'$ENCRYPT;1.0;default;...
|
39
48
|
>>> crypts.decrypt(encrypt)
|
40
49
|
'example'
|
41
50
|
|
42
|
-
:param phrases: Passphrases that are used in operations.
|
43
51
|
:param params: Parameters for instantiating the instance.
|
44
52
|
"""
|
45
53
|
|
46
|
-
|
54
|
+
__params: 'CryptsParams'
|
47
55
|
|
48
56
|
|
49
57
|
def __init__(
|
50
58
|
self,
|
51
|
-
phrases: Optional[dict[str, str]] = None,
|
52
59
|
params: Optional['CryptsParams'] = None,
|
53
60
|
) -> None:
|
54
61
|
"""
|
55
62
|
Initialize instance for class using provided parameters.
|
56
63
|
"""
|
57
64
|
|
58
|
-
|
59
|
-
|
60
|
-
if params is not None:
|
61
|
-
phrases |= params.phrases
|
65
|
+
from .params import CryptsParams
|
62
66
|
|
63
|
-
if
|
64
|
-
|
67
|
+
if params is None:
|
68
|
+
params = CryptsParams()
|
65
69
|
|
66
|
-
self.
|
70
|
+
self.__params = deepcopy(params)
|
67
71
|
|
68
72
|
|
69
73
|
@property
|
70
|
-
def
|
74
|
+
def params(
|
71
75
|
self,
|
72
|
-
) ->
|
76
|
+
) -> 'CryptsParams':
|
73
77
|
"""
|
74
|
-
Return the
|
78
|
+
Return the Pydantic model containing the configuration.
|
75
79
|
|
76
|
-
:returns:
|
80
|
+
:returns: Pydantic model containing the configuration.
|
77
81
|
"""
|
78
82
|
|
79
|
-
return
|
83
|
+
return self.__params
|
80
84
|
|
81
85
|
|
82
86
|
def encrypt(
|
@@ -92,7 +96,12 @@ class Crypts:
|
|
92
96
|
:returns: Encrypted value using the relevant passphrase.
|
93
97
|
"""
|
94
98
|
|
95
|
-
|
99
|
+
phrases = self.params.phrases
|
100
|
+
|
101
|
+
if unique not in phrases:
|
102
|
+
raise ValueError('unique')
|
103
|
+
|
104
|
+
phrase = phrases[unique].phrase
|
96
105
|
|
97
106
|
encrypt = (
|
98
107
|
Fernet(phrase)
|
@@ -115,6 +124,8 @@ class Crypts:
|
|
115
124
|
:returns: Decrypted value using the relevant passphrase.
|
116
125
|
"""
|
117
126
|
|
127
|
+
phrases = self.params.phrases
|
128
|
+
|
118
129
|
value = crypt_clean(value)
|
119
130
|
|
120
131
|
if not re_match(ENCRYPT, value):
|
@@ -126,7 +137,7 @@ class Crypts:
|
|
126
137
|
if version != '1.0':
|
127
138
|
raise ValueError('version')
|
128
139
|
|
129
|
-
phrase =
|
140
|
+
phrase = phrases[unique].phrase
|
130
141
|
|
131
142
|
return (
|
132
143
|
Fernet(phrase)
|
@@ -134,6 +145,44 @@ class Crypts:
|
|
134
145
|
.decode())
|
135
146
|
|
136
147
|
|
148
|
+
def create(
|
149
|
+
self,
|
150
|
+
unique: str,
|
151
|
+
params: 'CryptParams',
|
152
|
+
) -> None:
|
153
|
+
"""
|
154
|
+
Create a new phrase using the provided input parameters.
|
155
|
+
|
156
|
+
:param unique: Unique identifier of mapping passphrase.
|
157
|
+
:param params: Parameters for instantiating the instance.
|
158
|
+
"""
|
159
|
+
|
160
|
+
phrases = self.params.phrases
|
161
|
+
|
162
|
+
if unique in phrases:
|
163
|
+
raise ValueError('unique')
|
164
|
+
|
165
|
+
phrases[unique] = params
|
166
|
+
|
167
|
+
|
168
|
+
def delete(
|
169
|
+
self,
|
170
|
+
unique: str,
|
171
|
+
) -> None:
|
172
|
+
"""
|
173
|
+
Delete the phrase from the internal dictionary reference.
|
174
|
+
|
175
|
+
:param unique: Unique identifier of mapping passphrase.
|
176
|
+
"""
|
177
|
+
|
178
|
+
phrases = self.params.phrases
|
179
|
+
|
180
|
+
if unique not in phrases:
|
181
|
+
raise ValueError('unique')
|
182
|
+
|
183
|
+
del phrases[unique]
|
184
|
+
|
185
|
+
|
137
186
|
@classmethod
|
138
187
|
def keygen(
|
139
188
|
cls: object,
|
@@ -157,6 +206,7 @@ def crypt_clean(
|
|
157
206
|
Return the parsed and normalized encrypted string value.
|
158
207
|
|
159
208
|
:param value: String value that will returned decrypted.
|
209
|
+
:returns: Parsed and normalized encrypted string value.
|
160
210
|
"""
|
161
211
|
|
162
212
|
return re_sub(r'[\n\s]', SEMPTY, value)
|
@@ -11,6 +11,19 @@ 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
29
|
Process and validate the core configuration parameters.
|
@@ -20,4 +33,4 @@ class CryptsParams(BaseModel, extra='forbid'):
|
|
20
33
|
Parameter is picked up by autodoc, please ignore.
|
21
34
|
"""
|
22
35
|
|
23
|
-
phrases: dict[str,
|
36
|
+
phrases: dict[str, CryptParams] = {}
|
@@ -7,11 +7,14 @@ 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
|
13
15
|
|
14
16
|
from ..crypts import Crypts
|
17
|
+
from ..params import CryptParams
|
15
18
|
from ..params import CryptsParams
|
16
19
|
from ...types import inrepr
|
17
20
|
from ...types import instr
|
@@ -26,14 +29,14 @@ def crypts() -> Crypts:
|
|
26
29
|
:returns: Newly constructed instance of related class.
|
27
30
|
"""
|
28
31
|
|
29
|
-
|
30
|
-
'default': Crypts.keygen(),
|
31
|
-
'secrets': Crypts.keygen()}
|
32
|
+
source: dict[str, Any] = {
|
33
|
+
'default': {'phrase': Crypts.keygen()},
|
34
|
+
'secrets': {'phrase': Crypts.keygen()}}
|
32
35
|
|
33
36
|
params = CryptsParams(
|
34
|
-
phrases=
|
37
|
+
phrases=source)
|
35
38
|
|
36
|
-
return Crypts(params
|
39
|
+
return Crypts(params)
|
37
40
|
|
38
41
|
|
39
42
|
|
@@ -50,7 +53,7 @@ def test_Crypts(
|
|
50
53
|
attrs = list(crypts.__dict__)
|
51
54
|
|
52
55
|
assert attrs == [
|
53
|
-
'
|
56
|
+
'_Crypts__params']
|
54
57
|
|
55
58
|
|
56
59
|
assert inrepr(
|
@@ -64,7 +67,7 @@ def test_Crypts(
|
|
64
67
|
crypts)
|
65
68
|
|
66
69
|
|
67
|
-
assert
|
70
|
+
assert crypts.params is not None
|
68
71
|
|
69
72
|
assert len(crypts.keygen()) == 44
|
70
73
|
|
@@ -101,6 +104,28 @@ def test_Crypts_iterate(
|
|
101
104
|
|
102
105
|
|
103
106
|
|
107
|
+
def test_Crypts_cover(
|
108
|
+
crypts: Crypts,
|
109
|
+
) -> None:
|
110
|
+
"""
|
111
|
+
Perform various tests associated with relevant routines.
|
112
|
+
|
113
|
+
:param crypts: Primary class instance for the encryption.
|
114
|
+
"""
|
115
|
+
|
116
|
+
|
117
|
+
crypts = Crypts()
|
118
|
+
|
119
|
+
|
120
|
+
params = CryptParams(
|
121
|
+
phrase=Crypts.keygen())
|
122
|
+
|
123
|
+
crypts.create('testing', params)
|
124
|
+
|
125
|
+
crypts.delete('testing')
|
126
|
+
|
127
|
+
|
128
|
+
|
104
129
|
def test_Crypts_raises(
|
105
130
|
crypts: Crypts,
|
106
131
|
) -> None:
|
@@ -114,15 +139,11 @@ def test_Crypts_raises(
|
|
114
139
|
_raises = raises(ValueError)
|
115
140
|
|
116
141
|
with _raises as reason:
|
117
|
-
|
142
|
+
crypts.encrypt('foo', 'dne')
|
118
143
|
|
119
144
|
_reason = str(reason.value)
|
120
145
|
|
121
|
-
assert _reason == '
|
122
|
-
|
123
|
-
|
124
|
-
crypts = Crypts(
|
125
|
-
crypts.phrases)
|
146
|
+
assert _reason == 'unique'
|
126
147
|
|
127
148
|
|
128
149
|
_raises = raises(ValueError)
|
@@ -144,3 +165,25 @@ def test_Crypts_raises(
|
|
144
165
|
_reason = str(reason.value)
|
145
166
|
|
146
167
|
assert _reason == 'version'
|
168
|
+
|
169
|
+
|
170
|
+
_raises = raises(ValueError)
|
171
|
+
|
172
|
+
params = CryptParams(phrase='foo')
|
173
|
+
|
174
|
+
with _raises as reason:
|
175
|
+
crypts.create('default', params)
|
176
|
+
|
177
|
+
_reason = str(reason.value)
|
178
|
+
|
179
|
+
assert _reason == 'unique'
|
180
|
+
|
181
|
+
|
182
|
+
_raises = raises(ValueError)
|
183
|
+
|
184
|
+
with _raises as reason:
|
185
|
+
crypts.delete('dne')
|
186
|
+
|
187
|
+
_reason = str(reason.value)
|
188
|
+
|
189
|
+
assert _reason == 'unique'
|