encommon 0.10.0__py3-none-any.whl → 0.11.0__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.
- encommon/config/__init__.py +3 -3
- encommon/config/config.py +17 -1
- encommon/config/files.py +3 -3
- encommon/config/logger.py +37 -6
- encommon/config/params.py +21 -1
- encommon/config/paths.py +2 -2
- encommon/config/test/test_logger.py +3 -0
- encommon/config/test/{test_common.py → test_utils.py} +3 -3
- encommon/config/{common.py → utils.py} +1 -10
- encommon/conftest.py +2 -1
- encommon/crypts/crypts.py +23 -22
- encommon/crypts/params.py +14 -1
- encommon/crypts/test/test_crypts.py +8 -20
- encommon/times/__init__.py +14 -2
- encommon/times/common.py +0 -127
- encommon/times/params.py +155 -0
- encommon/times/parse.py +5 -5
- encommon/times/test/test_params.py +64 -0
- encommon/times/test/test_parse.py +1 -1
- encommon/times/test/test_timer.py +86 -0
- encommon/times/test/test_timers.py +87 -36
- encommon/times/test/{test_common.py → test_utils.py} +3 -3
- encommon/times/test/test_window.py +101 -51
- encommon/times/test/test_windows.py +264 -0
- encommon/times/timer.py +147 -0
- encommon/times/timers.py +207 -133
- encommon/times/times.py +6 -6
- encommon/times/utils.py +148 -0
- encommon/times/window.py +124 -85
- encommon/times/windows.py +459 -0
- encommon/types/notate.py +0 -2
- encommon/utils/__init__.py +2 -2
- encommon/utils/common.py +0 -39
- encommon/utils/files.py +71 -0
- encommon/utils/paths.py +1 -1
- encommon/utils/sample.py +2 -2
- encommon/utils/test/{test_common.py → test_files.py} +2 -2
- encommon/utils/test/test_paths.py +2 -1
- encommon/version.txt +1 -1
- {encommon-0.10.0.dist-info → encommon-0.11.0.dist-info}/METADATA +1 -1
- encommon-0.11.0.dist-info/RECORD +73 -0
- encommon-0.10.0.dist-info/RECORD +0 -65
- {encommon-0.10.0.dist-info → encommon-0.11.0.dist-info}/LICENSE +0 -0
- {encommon-0.10.0.dist-info → encommon-0.11.0.dist-info}/WHEEL +0 -0
- {encommon-0.10.0.dist-info → encommon-0.11.0.dist-info}/top_level.txt +0 -0
encommon/times/params.py
ADDED
@@ -0,0 +1,155 @@
|
|
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 typing import Any
|
11
|
+
from typing import Optional
|
12
|
+
|
13
|
+
from pydantic import BaseModel
|
14
|
+
|
15
|
+
from .common import PARSABLE
|
16
|
+
from .common import SCHEDULE
|
17
|
+
from .times import Times
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
class TimerParams(BaseModel, extra='forbid'):
|
22
|
+
"""
|
23
|
+
Process and validate the core configuration parameters.
|
24
|
+
|
25
|
+
:param timer: Seconds that are used for related timer.
|
26
|
+
:param start: Optional time for when the timer started.
|
27
|
+
:param data: Keyword arguments passed to Pydantic model.
|
28
|
+
Parameter is picked up by autodoc, please ignore.
|
29
|
+
"""
|
30
|
+
|
31
|
+
timer: float
|
32
|
+
start: Optional[str] = None
|
33
|
+
|
34
|
+
|
35
|
+
def __init__(
|
36
|
+
self,
|
37
|
+
timer: int | float,
|
38
|
+
start: Optional[PARSABLE] = None,
|
39
|
+
) -> None:
|
40
|
+
"""
|
41
|
+
Initialize instance for class using provided parameters.
|
42
|
+
"""
|
43
|
+
|
44
|
+
if timer is not None:
|
45
|
+
timer = float(timer)
|
46
|
+
|
47
|
+
if start is not None:
|
48
|
+
start = Times(start)
|
49
|
+
|
50
|
+
|
51
|
+
data: dict[str, Any] = {
|
52
|
+
'timer': timer}
|
53
|
+
|
54
|
+
if start is not None:
|
55
|
+
data['start'] = start.subsec
|
56
|
+
|
57
|
+
|
58
|
+
super().__init__(**data)
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
class TimersParams(BaseModel, extra='forbid'):
|
63
|
+
"""
|
64
|
+
Process and validate the core configuration parameters.
|
65
|
+
|
66
|
+
:param timers: Seconds that are used for related timer.
|
67
|
+
:param data: Keyword arguments passed to Pydantic model.
|
68
|
+
Parameter is picked up by autodoc, please ignore.
|
69
|
+
"""
|
70
|
+
|
71
|
+
timers: dict[str, TimerParams]
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
class WindowParams(BaseModel, extra='forbid'):
|
76
|
+
"""
|
77
|
+
Process and validate the core configuration parameters.
|
78
|
+
|
79
|
+
:param window: Parameters for defining scheduled time.
|
80
|
+
:param start: Determine the start for scheduling window.
|
81
|
+
:param stop: Determine the ending for scheduling window.
|
82
|
+
:param anchor: Optionally define time anchor for window.
|
83
|
+
:param delay: Period of time schedulng will be delayed.
|
84
|
+
:param data: Keyword arguments passed to Pydantic model.
|
85
|
+
Parameter is picked up by autodoc, please ignore.
|
86
|
+
"""
|
87
|
+
|
88
|
+
window: SCHEDULE
|
89
|
+
|
90
|
+
start: Optional[str] = None
|
91
|
+
stop: Optional[str] = None
|
92
|
+
anchor: Optional[str] = None
|
93
|
+
delay: float = 0.0
|
94
|
+
|
95
|
+
|
96
|
+
def __init__(
|
97
|
+
self,
|
98
|
+
window: SCHEDULE | int,
|
99
|
+
start: Optional[PARSABLE] = None,
|
100
|
+
stop: Optional[PARSABLE] = None,
|
101
|
+
anchor: Optional[PARSABLE] = None,
|
102
|
+
delay: Optional[int | float] = None,
|
103
|
+
) -> None:
|
104
|
+
"""
|
105
|
+
Initialize instance for class using provided parameters.
|
106
|
+
"""
|
107
|
+
|
108
|
+
|
109
|
+
if isinstance(window, int):
|
110
|
+
window = {'seconds': window}
|
111
|
+
|
112
|
+
|
113
|
+
if start is not None:
|
114
|
+
start = Times(start)
|
115
|
+
|
116
|
+
if stop is not None:
|
117
|
+
stop = Times(stop)
|
118
|
+
|
119
|
+
if anchor is not None:
|
120
|
+
anchor = Times(stop)
|
121
|
+
|
122
|
+
if delay is not None:
|
123
|
+
delay = float(delay)
|
124
|
+
|
125
|
+
|
126
|
+
data: dict[str, Any] = {
|
127
|
+
'window': window}
|
128
|
+
|
129
|
+
if start is not None:
|
130
|
+
data['start'] = start.subsec
|
131
|
+
|
132
|
+
if stop is not None:
|
133
|
+
data['stop'] = stop.subsec
|
134
|
+
|
135
|
+
if anchor is not None:
|
136
|
+
data['anchor'] = anchor.subsec
|
137
|
+
|
138
|
+
if delay is not None:
|
139
|
+
data['delay'] = delay
|
140
|
+
|
141
|
+
|
142
|
+
super().__init__(**data)
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
class WindowsParams(BaseModel, extra='forbid'):
|
147
|
+
"""
|
148
|
+
Process and validate the core configuration parameters.
|
149
|
+
|
150
|
+
:param windows: Parameters for defining scheduled time.
|
151
|
+
:param data: Keyword arguments passed to Pydantic model.
|
152
|
+
Parameter is picked up by autodoc, please ignore.
|
153
|
+
"""
|
154
|
+
|
155
|
+
windows: dict[str, WindowParams]
|
encommon/times/parse.py
CHANGED
@@ -22,9 +22,9 @@ from .common import NUMERISH
|
|
22
22
|
from .common import PARSABLE
|
23
23
|
from .common import SNAPABLE
|
24
24
|
from .common import STRINGNOW
|
25
|
-
from .
|
26
|
-
from .
|
27
|
-
from .
|
25
|
+
from .utils import findtz
|
26
|
+
from .utils import strptime
|
27
|
+
from .utils import utcdatetime
|
28
28
|
|
29
29
|
if TYPE_CHECKING:
|
30
30
|
from .times import Times # noqa: F401
|
@@ -201,7 +201,7 @@ def since_time(
|
|
201
201
|
stop: Optional[PARSABLE] = None,
|
202
202
|
) -> float:
|
203
203
|
"""
|
204
|
-
Determine the time in seconds
|
204
|
+
Determine the time in seconds occurring between values.
|
205
205
|
|
206
206
|
Example
|
207
207
|
-------
|
@@ -212,7 +212,7 @@ def since_time(
|
|
212
212
|
|
213
213
|
:param start: Time in various forms that will be parsed.
|
214
214
|
:param stop: Time in various forms that will be parsed.
|
215
|
-
:returns: Time in seconds
|
215
|
+
:returns: Time in seconds occurring between the values.
|
216
216
|
"""
|
217
217
|
|
218
218
|
start = parse_time(start)
|
@@ -0,0 +1,64 @@
|
|
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 ..params import TimerParams
|
11
|
+
from ..params import WindowParams
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
def test_TimerParams() -> None:
|
16
|
+
"""
|
17
|
+
Perform various tests associated with relevant routines.
|
18
|
+
"""
|
19
|
+
|
20
|
+
params = TimerParams(
|
21
|
+
timer=1,
|
22
|
+
start='1980-01-01T00:00:00Z')
|
23
|
+
|
24
|
+
assert params.start == (
|
25
|
+
'1980-01-01T00:00:00.000000+0000')
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
def test_WindowParams() -> None:
|
30
|
+
"""
|
31
|
+
Perform various tests associated with relevant routines.
|
32
|
+
"""
|
33
|
+
|
34
|
+
|
35
|
+
params = WindowParams(
|
36
|
+
window='* * * * *',
|
37
|
+
start='1980-01-01T00:00:00Z',
|
38
|
+
stop='1980-01-02T00:00:00Z',
|
39
|
+
anchor='1980-01-01T00:00:00Z',
|
40
|
+
delay=10)
|
41
|
+
|
42
|
+
assert params.start == (
|
43
|
+
'1980-01-01T00:00:00.000000+0000')
|
44
|
+
|
45
|
+
assert params.stop == (
|
46
|
+
'1980-01-02T00:00:00.000000+0000')
|
47
|
+
|
48
|
+
assert str(params.delay) == '10.0'
|
49
|
+
|
50
|
+
|
51
|
+
params = WindowParams(
|
52
|
+
window=60,
|
53
|
+
start='1980-01-01T00:00:00Z',
|
54
|
+
stop='1980-01-02T00:00:00Z',
|
55
|
+
anchor='1980-01-01T00:00:00Z',
|
56
|
+
delay=10)
|
57
|
+
|
58
|
+
assert params.start == (
|
59
|
+
'1980-01-01T00:00:00.000000+0000')
|
60
|
+
|
61
|
+
assert params.stop == (
|
62
|
+
'1980-01-02T00:00:00.000000+0000')
|
63
|
+
|
64
|
+
assert str(params.delay) == '10.0'
|
@@ -11,11 +11,11 @@ from datetime import timedelta
|
|
11
11
|
|
12
12
|
from pytest import mark
|
13
13
|
|
14
|
-
from ..common import utcdatetime
|
15
14
|
from ..parse import parse_time
|
16
15
|
from ..parse import shift_time
|
17
16
|
from ..parse import since_time
|
18
17
|
from ..parse import string_time
|
18
|
+
from ..utils import utcdatetime
|
19
19
|
|
20
20
|
|
21
21
|
|
@@ -0,0 +1,86 @@
|
|
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 time import sleep
|
11
|
+
|
12
|
+
from pytest import fixture
|
13
|
+
|
14
|
+
from ..timer import Timer
|
15
|
+
from ..times import Times
|
16
|
+
from ...types import inrepr
|
17
|
+
from ...types import instr
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
@fixture
|
22
|
+
def timer() -> Timer:
|
23
|
+
"""
|
24
|
+
Construct the instance for use in the downstream tests.
|
25
|
+
|
26
|
+
:returns: Newly constructed instance of related class.
|
27
|
+
"""
|
28
|
+
|
29
|
+
return Timer(1)
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
def test_Timer(
|
34
|
+
timer: Timer,
|
35
|
+
) -> None:
|
36
|
+
"""
|
37
|
+
Perform various tests associated with relevant routines.
|
38
|
+
|
39
|
+
:param timer: Primary class instance for timer object.
|
40
|
+
"""
|
41
|
+
|
42
|
+
|
43
|
+
attrs = list(timer.__dict__)
|
44
|
+
|
45
|
+
assert attrs == [
|
46
|
+
'_Timer__timer',
|
47
|
+
'_Timer__times']
|
48
|
+
|
49
|
+
|
50
|
+
assert inrepr(
|
51
|
+
'timer.Timer object',
|
52
|
+
timer)
|
53
|
+
|
54
|
+
assert hash(timer) > 0
|
55
|
+
|
56
|
+
assert instr(
|
57
|
+
'timer.Timer object',
|
58
|
+
timer)
|
59
|
+
|
60
|
+
|
61
|
+
assert timer.timer == 1
|
62
|
+
|
63
|
+
assert timer.times >= Times('-1s')
|
64
|
+
|
65
|
+
assert timer.since <= 1
|
66
|
+
|
67
|
+
assert timer.remains <= 1
|
68
|
+
|
69
|
+
assert not timer.ready()
|
70
|
+
|
71
|
+
|
72
|
+
sleep(1)
|
73
|
+
|
74
|
+
assert timer.since > 1
|
75
|
+
|
76
|
+
assert timer.remains == 0
|
77
|
+
|
78
|
+
assert timer.ready()
|
79
|
+
|
80
|
+
assert not timer.ready()
|
81
|
+
|
82
|
+
timer.update('1980-01-01')
|
83
|
+
|
84
|
+
assert timer.ready()
|
85
|
+
|
86
|
+
assert not timer.ready()
|
@@ -8,12 +8,15 @@ is permitted, for more information consult the project license file.
|
|
8
8
|
|
9
9
|
|
10
10
|
from pathlib import Path
|
11
|
-
from
|
11
|
+
from typing import Any
|
12
12
|
|
13
13
|
from pytest import fixture
|
14
14
|
from pytest import raises
|
15
15
|
|
16
|
+
from ..params import TimerParams
|
17
|
+
from ..params import TimersParams
|
16
18
|
from ..timers import Timers
|
19
|
+
from ..times import Times
|
17
20
|
from ...types import inrepr
|
18
21
|
from ...types import instr
|
19
22
|
|
@@ -30,10 +33,45 @@ def timers(
|
|
30
33
|
:returns: Newly constructed instance of related class.
|
31
34
|
"""
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
source: dict[str, Any] = {
|
37
|
+
'one': {'timer': 1},
|
38
|
+
'two': {'timer': 1}}
|
39
|
+
|
40
|
+
params = TimersParams(
|
41
|
+
timers=source)
|
42
|
+
|
43
|
+
timers = Timers(
|
44
|
+
params,
|
35
45
|
file=f'{tmp_path}/cache.db')
|
36
46
|
|
47
|
+
sqlite = timers.sqlite
|
48
|
+
|
49
|
+
sqlite.execute(
|
50
|
+
"""
|
51
|
+
insert into timers
|
52
|
+
("group", "unique",
|
53
|
+
"update")
|
54
|
+
values (
|
55
|
+
"default", "two",
|
56
|
+
"1970-01-01T00:00:00Z")
|
57
|
+
""") # noqa: LIT003
|
58
|
+
|
59
|
+
sqlite.execute(
|
60
|
+
"""
|
61
|
+
insert into timers
|
62
|
+
("group", "unique",
|
63
|
+
"update")
|
64
|
+
values (
|
65
|
+
"default", "tre",
|
66
|
+
"1970-01-01T00:00:00Z")
|
67
|
+
""") # noqa: LIT003
|
68
|
+
|
69
|
+
sqlite.commit()
|
70
|
+
|
71
|
+
timers.load_children()
|
72
|
+
|
73
|
+
return timers
|
74
|
+
|
37
75
|
|
38
76
|
|
39
77
|
def test_Timers(
|
@@ -49,11 +87,12 @@ def test_Timers(
|
|
49
87
|
attrs = list(timers.__dict__)
|
50
88
|
|
51
89
|
assert attrs == [
|
52
|
-
'
|
90
|
+
'_Timers__params',
|
53
91
|
'_Timers__sqlite',
|
54
92
|
'_Timers__file',
|
55
93
|
'_Timers__table',
|
56
|
-
'
|
94
|
+
'_Timers__group',
|
95
|
+
'_Timers__timers']
|
57
96
|
|
58
97
|
|
59
98
|
assert inrepr(
|
@@ -67,7 +106,7 @@ def test_Timers(
|
|
67
106
|
timers)
|
68
107
|
|
69
108
|
|
70
|
-
assert timers.
|
109
|
+
assert timers.params is not None
|
71
110
|
|
72
111
|
assert timers.sqlite is not None
|
73
112
|
|
@@ -75,7 +114,19 @@ def test_Timers(
|
|
75
114
|
|
76
115
|
assert timers.table == 'timers'
|
77
116
|
|
78
|
-
assert
|
117
|
+
assert timers.group == 'default'
|
118
|
+
|
119
|
+
assert len(timers.children) == 2
|
120
|
+
|
121
|
+
|
122
|
+
timer = timers.children['one']
|
123
|
+
|
124
|
+
assert timer.times >= Times('-1s')
|
125
|
+
|
126
|
+
|
127
|
+
timer = timers.children['two']
|
128
|
+
|
129
|
+
assert timer.times == '1970-01-01'
|
79
130
|
|
80
131
|
|
81
132
|
|
@@ -91,49 +142,37 @@ def test_Timers_cover(
|
|
91
142
|
|
92
143
|
assert not timers.ready('one')
|
93
144
|
|
94
|
-
|
95
|
-
|
96
|
-
assert timers.ready('one')
|
97
|
-
|
145
|
+
assert timers.ready('two')
|
98
146
|
|
99
|
-
timers.create('two', 2, 0)
|
100
147
|
|
101
|
-
|
148
|
+
timers.update('two', 'now')
|
102
149
|
|
103
150
|
assert not timers.ready('two')
|
104
151
|
|
152
|
+
timers.load_children()
|
105
153
|
|
154
|
+
assert timers.ready('two')
|
106
155
|
|
107
|
-
def test_Timers_cache(
|
108
|
-
timers: Timers,
|
109
|
-
) -> None:
|
110
|
-
"""
|
111
|
-
Perform various tests associated with relevant routines.
|
112
156
|
|
113
|
-
|
114
|
-
"""
|
157
|
+
timers.update('two', 'now')
|
115
158
|
|
116
|
-
|
117
|
-
timers={'uno': 1},
|
118
|
-
file=timers.file)
|
159
|
+
assert not timers.ready('two')
|
119
160
|
|
120
|
-
|
161
|
+
timers.save_children()
|
162
|
+
timers.load_children()
|
121
163
|
|
122
|
-
|
164
|
+
assert not timers.ready('two')
|
123
165
|
|
124
|
-
timers2 = Timers(
|
125
|
-
timers={'uno': 1},
|
126
|
-
file=timers.file)
|
127
166
|
|
128
|
-
|
129
|
-
|
167
|
+
params = TimerParams(
|
168
|
+
timer=1,
|
169
|
+
start='-1s')
|
130
170
|
|
131
|
-
|
171
|
+
timers.create('fur', params)
|
132
172
|
|
133
|
-
|
173
|
+
assert timers.ready('fur')
|
134
174
|
|
135
|
-
|
136
|
-
assert timers2.ready('uno')
|
175
|
+
timers.delete('fur')
|
137
176
|
|
138
177
|
|
139
178
|
|
@@ -157,10 +196,22 @@ def test_Timers_raises(
|
|
157
196
|
assert _reason == 'unique'
|
158
197
|
|
159
198
|
|
199
|
+
_raises = raises(ValueError)
|
200
|
+
|
201
|
+
params = TimerParams(timer=1)
|
202
|
+
|
203
|
+
with _raises as reason:
|
204
|
+
timers.create('one', params)
|
205
|
+
|
206
|
+
_reason = str(reason.value)
|
207
|
+
|
208
|
+
assert _reason == 'unique'
|
209
|
+
|
210
|
+
|
160
211
|
_raises = raises(ValueError)
|
161
212
|
|
162
213
|
with _raises as reason:
|
163
|
-
timers.update('dne')
|
214
|
+
timers.update('dne', 'now')
|
164
215
|
|
165
216
|
_reason = str(reason.value)
|
166
217
|
|
@@ -170,7 +221,7 @@ def test_Timers_raises(
|
|
170
221
|
_raises = raises(ValueError)
|
171
222
|
|
172
223
|
with _raises as reason:
|
173
|
-
timers.
|
224
|
+
timers.delete('dne')
|
174
225
|
|
175
226
|
_reason = str(reason.value)
|
176
227
|
|
@@ -13,9 +13,9 @@ from pytest import raises
|
|
13
13
|
|
14
14
|
from ..common import STAMP_SIMPLE
|
15
15
|
from ..common import UNIXEPOCH
|
16
|
-
from ..
|
17
|
-
from ..
|
18
|
-
from ..
|
16
|
+
from ..utils import findtz
|
17
|
+
from ..utils import strptime
|
18
|
+
from ..utils import utcdatetime
|
19
19
|
|
20
20
|
|
21
21
|
|