encommon 0.11.1__py3-none-any.whl → 0.12.1__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/logger.py CHANGED
@@ -266,6 +266,9 @@ class Message:
266
266
  class FileFormatter(Formatter):
267
267
  """
268
268
  Supplement class for built-in logger exception formatter.
269
+
270
+ .. note::
271
+ Input parameters are not defined, check parent class.
269
272
  """
270
273
 
271
274
 
encommon/config/params.py CHANGED
@@ -37,8 +37,6 @@ class LoggerParams(BaseModel, extra='forbid'):
37
37
  :param stdo_level: Minimum level for the message to pass.
38
38
  :param file_level: Minimum level for the message to pass.
39
39
  :param file_path: Enables writing to the filesystem path.
40
- :param data: Keyword arguments passed to Pydantic model.
41
- Parameter is picked up by autodoc, please ignore.
42
40
  """
43
41
 
44
42
  stdo_level: Optional[LOGLEVELS] = None
encommon/times/params.py CHANGED
@@ -24,8 +24,6 @@ class TimerParams(BaseModel, extra='forbid'):
24
24
 
25
25
  :param timer: Seconds that are used for related timer.
26
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
27
  """
30
28
 
31
29
  timer: float
@@ -81,8 +79,6 @@ class WindowParams(BaseModel, extra='forbid'):
81
79
  :param stop: Determine the ending for scheduling window.
82
80
  :param anchor: Optionally define time anchor for window.
83
81
  :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
82
  """
87
83
 
88
84
  window: SCHEDULE
@@ -17,6 +17,7 @@ from pytest import raises
17
17
  from ..params import TimerParams
18
18
  from ..params import TimersParams
19
19
  from ..timers import Timers
20
+ from ..timers import TimersTable
20
21
  from ..times import Times
21
22
  from ...types import inrepr
22
23
  from ...types import instr
@@ -34,40 +35,45 @@ def timers(
34
35
  :returns: Newly constructed instance of related class.
35
36
  """
36
37
 
38
+
37
39
  source: dict[str, Any] = {
38
40
  'one': {'timer': 1},
39
41
  'two': {'timer': 1}}
40
42
 
43
+
41
44
  params = TimersParams(
42
45
  timers=source)
43
46
 
47
+ store = (
48
+ f'sqlite:///{tmp_path}'
49
+ '/cache.db')
50
+
44
51
  timers = Timers(
45
52
  params,
46
- file=f'{tmp_path}/cache.db')
47
-
48
- sqlite = timers.sqlite
49
-
50
- sqlite.execute(
51
- """
52
- insert into timers
53
- ("group", "unique",
54
- "update")
55
- values (
56
- "default", "two",
57
- "1970-01-01T00:00:00Z")
58
- """) # noqa: LIT003
59
-
60
- sqlite.execute(
61
- """
62
- insert into timers
63
- ("group", "unique",
64
- "update")
65
- values (
66
- "default", "tre",
67
- "1970-01-01T00:00:00Z")
68
- """) # noqa: LIT003
69
-
70
- sqlite.commit()
53
+ store=store)
54
+
55
+ session = timers.store_session
56
+
57
+
58
+ timer = TimersTable(
59
+ group='default',
60
+ unique='two',
61
+ update='1970-01-01T00:00:00Z')
62
+
63
+ session.add(timer)
64
+
65
+ session.commit()
66
+
67
+
68
+ timer = TimersTable(
69
+ group='default',
70
+ unique='tre',
71
+ update='1970-01-01T00:00:00Z')
72
+
73
+ session.add(timer)
74
+
75
+ session.commit()
76
+
71
77
 
72
78
  timers.load_children()
73
79
 
@@ -89,10 +95,10 @@ def test_Timers(
89
95
 
90
96
  assert attrs == [
91
97
  '_Timers__params',
92
- '_Timers__sqlite',
93
- '_Timers__file',
94
- '_Timers__table',
98
+ '_Timers__store',
95
99
  '_Timers__group',
100
+ '_Timers__store_engine',
101
+ '_Timers__store_session',
96
102
  '_Timers__timers']
97
103
 
98
104
 
@@ -109,13 +115,13 @@ def test_Timers(
109
115
 
110
116
  assert timers.params is not None
111
117
 
112
- assert timers.sqlite is not None
118
+ assert timers.store[:6] == 'sqlite'
113
119
 
114
- assert timers.file[-8:] == 'cache.db'
120
+ assert timers.group == 'default'
115
121
 
116
- assert timers.table == 'timers'
122
+ assert timers.store_engine is not None
117
123
 
118
- assert timers.group == 'default'
124
+ assert timers.store_session is not None
119
125
 
120
126
  assert len(timers.children) == 2
121
127
 
@@ -17,6 +17,7 @@ from pytest import raises
17
17
  from ..params import WindowParams
18
18
  from ..params import WindowsParams
19
19
  from ..windows import Windows
20
+ from ..windows import WindowsTable
20
21
  from ...types import inrepr
21
22
  from ...types import instr
22
23
 
@@ -33,6 +34,7 @@ def windows(
33
34
  :returns: Newly constructed instance of related class.
34
35
  """
35
36
 
37
+
36
38
  source: dict[str, Any] = {
37
39
  'one': WindowParams(
38
40
  window='* * * * *',
@@ -45,46 +47,46 @@ def windows(
45
47
  stop=620,
46
48
  delay=10)}
47
49
 
50
+
48
51
  params = WindowsParams(
49
52
  windows=source)
50
53
 
54
+ store = (
55
+ f'sqlite:///{tmp_path}'
56
+ '/cache.db')
57
+
51
58
  windows = Windows(
52
59
  params,
53
60
  start=310,
54
61
  stop=610,
55
- file=f'{tmp_path}/cache.db')
56
-
57
- sqlite = windows.sqlite
58
-
59
- sqlite.execute(
60
- """
61
- insert into windows
62
- ("group", "unique",
63
- "last", "next",
64
- "update")
65
- values (
66
- "default", "two",
67
- "1970-01-01T00:06:00Z",
68
- "1970-01-01T00:07:00Z",
69
- "1970-01-01T01:00:00Z")
70
- """) # noqa: LIT003
71
-
72
- sqlite.commit()
73
-
74
- sqlite.execute(
75
- """
76
- insert into windows
77
- ("group", "unique",
78
- "last", "next",
79
- "update")
80
- values (
81
- "default", "tre",
82
- "1970-01-01T00:06:00Z",
83
- "1970-01-01T00:07:00Z",
84
- "1970-01-01T01:00:00Z")
85
- """) # noqa: LIT003
86
-
87
- sqlite.commit()
62
+ store=store)
63
+
64
+ session = windows.store_session
65
+
66
+
67
+ window = WindowsTable(
68
+ group='default',
69
+ unique='two',
70
+ last='1970-01-01T00:06:00Z',
71
+ next='1970-01-01T00:07:00Z',
72
+ update='1970-01-01T01:00:00Z')
73
+
74
+ session.add(window)
75
+
76
+ session.commit()
77
+
78
+
79
+ window = WindowsTable(
80
+ group='default',
81
+ unique='tre',
82
+ last='1970-01-01T00:06:00Z',
83
+ next='1970-01-01T00:07:00Z',
84
+ update='1970-01-01T01:00:00Z')
85
+
86
+ session.add(window)
87
+
88
+ session.commit()
89
+
88
90
 
89
91
  windows.load_children()
90
92
 
@@ -106,12 +108,12 @@ def test_Windows(
106
108
 
107
109
  assert attrs == [
108
110
  '_Windows__params',
111
+ '_Windows__store',
112
+ '_Windows__group',
113
+ '_Windows__store_engine',
114
+ '_Windows__store_session',
109
115
  '_Windows__start',
110
116
  '_Windows__stop',
111
- '_Windows__sqlite',
112
- '_Windows__file',
113
- '_Windows__table',
114
- '_Windows__group',
115
117
  '_Windows__windows']
116
118
 
117
119
 
@@ -128,19 +130,19 @@ def test_Windows(
128
130
 
129
131
  assert windows.params is not None
130
132
 
131
- assert windows.start == (
132
- '1970-01-01T00:05:10Z')
133
+ assert windows.store[:6] == 'sqlite'
133
134
 
134
- assert windows.stop == (
135
- '1970-01-01T00:10:10Z')
135
+ assert windows.group == 'default'
136
136
 
137
- assert windows.sqlite is not None
137
+ assert windows.store_engine is not None
138
138
 
139
- assert windows.file[-8:] == 'cache.db'
139
+ assert windows.store_session is not None
140
140
 
141
- assert windows.table == 'windows'
141
+ assert windows.start == (
142
+ '1970-01-01T00:05:10Z')
142
143
 
143
- assert windows.group == 'default'
144
+ assert windows.stop == (
145
+ '1970-01-01T00:10:10Z')
144
146
 
145
147
  assert len(windows.children) == 2
146
148
 
encommon/times/timers.py CHANGED
@@ -8,35 +8,64 @@ is permitted, for more information consult the project license file.
8
8
 
9
9
 
10
10
  from copy import deepcopy
11
- from sqlite3 import Connection
12
- from sqlite3 import connect as SQLite
13
11
  from typing import Optional
14
12
  from typing import TYPE_CHECKING
15
13
 
14
+ from sqlalchemy import Column
15
+ from sqlalchemy import String
16
+ from sqlalchemy import create_engine
17
+ from sqlalchemy.engine import Engine
18
+ from sqlalchemy.orm import DeclarativeBase
19
+ from sqlalchemy.orm import Session
20
+ from sqlalchemy.orm import sessionmaker
21
+
16
22
  from .common import PARSABLE
23
+ from .params import TimersParams
17
24
  from .timer import Timer
18
25
  from .times import Times
19
26
 
20
27
  if TYPE_CHECKING:
21
28
  from .params import TimerParams
22
- from .params import TimersParams
23
29
 
24
30
 
25
31
 
26
- CACHE_TABLE = (
32
+ TIMERS = dict[str, Timer]
33
+
34
+
35
+
36
+ class SQLBase(DeclarativeBase):
27
37
  """
28
- create table if not exists
29
- {0} (
30
- "group" text not null,
31
- "unique" text not null,
32
- "update" text not null,
33
- primary key (
34
- "group", "unique"));
35
- """) # noqa: LIT003
38
+ Some additional class that SQLAlchemy requires to work.
36
39
 
40
+ .. note::
41
+ Input parameters are not defined, check parent class.
42
+ """
37
43
 
38
44
 
39
- TIMERS = dict[str, Timer]
45
+
46
+ class TimersTable(SQLBase):
47
+ """
48
+ Schematic for the database operations using SQLAlchemy.
49
+
50
+ .. note::
51
+ Fields are not completely documented for this model.
52
+ """
53
+
54
+ group = Column(
55
+ String,
56
+ primary_key=True,
57
+ nullable=False)
58
+
59
+ unique = Column(
60
+ String,
61
+ primary_key=True,
62
+ nullable=False)
63
+
64
+ update = Column(
65
+ String,
66
+ nullable=False)
67
+
68
+ __tablename__ = 'timers'
40
69
 
41
70
 
42
71
 
@@ -65,19 +94,20 @@ class Timers:
65
94
  True
66
95
 
67
96
  :param params: Parameters for instantiating the instance.
68
- :param file: Optional path to file for SQLite database,
69
- allowing for state retention between the executions.
70
- :param table: Optional override for default table name.
97
+ :param store: Optional database path for keeping state.
71
98
  :param group: Optional override for default group name.
72
99
  """
73
100
 
74
101
  __params: 'TimersParams'
75
102
 
76
- __sqlite: Connection
77
- __file: str
78
- __table: str
103
+ __store: str
79
104
  __group: str
80
105
 
106
+ __store_engine: Engine
107
+ __store_session: (
108
+ # pylint: disable=unsubscriptable-object
109
+ sessionmaker[Session])
110
+
81
111
  __timers: TIMERS
82
112
 
83
113
 
@@ -85,41 +115,52 @@ class Timers:
85
115
  self,
86
116
  params: Optional['TimersParams'] = None,
87
117
  *,
88
- file: str = ':memory:',
89
- table: str = 'timers',
118
+ store: str = 'sqlite:///:memory:',
90
119
  group: str = 'default',
91
120
  ) -> None:
92
121
  """
93
122
  Initialize instance for class using provided parameters.
94
123
  """
95
124
 
96
- from .params import TimersParams
125
+ params = deepcopy(params)
97
126
 
98
127
  if params is None:
99
128
  params = TimersParams()
100
129
 
101
- self.__params = deepcopy(params)
102
-
103
-
104
- sqlite = SQLite(file)
130
+ self.__params = params
105
131
 
106
- sqlite.execute(
107
- CACHE_TABLE
108
- .format(table))
109
132
 
110
- sqlite.commit()
111
-
112
- self.__sqlite = sqlite
113
- self.__file = file
114
- self.__table = table
133
+ self.__store = store
115
134
  self.__group = group
116
135
 
136
+ self.__make_engine()
137
+
117
138
 
118
139
  self.__timers = {}
119
140
 
120
141
  self.load_children()
121
142
 
122
143
 
144
+ def __make_engine(
145
+ self,
146
+ ) -> None:
147
+ """
148
+ Construct instances using the configuration parameters.
149
+ """
150
+
151
+ store = self.__store
152
+
153
+ engine = create_engine(store)
154
+
155
+ (SQLBase.metadata
156
+ .create_all(engine))
157
+
158
+ session = sessionmaker(engine)
159
+
160
+ self.__store_engine = engine
161
+ self.__store_session = session
162
+
163
+
123
164
  @property
124
165
  def params(
125
166
  self,
@@ -134,20 +175,20 @@ class Timers:
134
175
 
135
176
 
136
177
  @property
137
- def sqlite(
178
+ def store(
138
179
  self,
139
- ) -> Connection:
180
+ ) -> str:
140
181
  """
141
182
  Return the value for the attribute from class instance.
142
183
 
143
184
  :returns: Value for the attribute from class instance.
144
185
  """
145
186
 
146
- return self.__sqlite
187
+ return self.__store
147
188
 
148
189
 
149
190
  @property
150
- def file(
191
+ def group(
151
192
  self,
152
193
  ) -> str:
153
194
  """
@@ -156,33 +197,33 @@ class Timers:
156
197
  :returns: Value for the attribute from class instance.
157
198
  """
158
199
 
159
- return self.__file
200
+ return self.__group
160
201
 
161
202
 
162
203
  @property
163
- def table(
204
+ def store_engine(
164
205
  self,
165
- ) -> str:
206
+ ) -> Engine:
166
207
  """
167
208
  Return the value for the attribute from class instance.
168
209
 
169
210
  :returns: Value for the attribute from class instance.
170
211
  """
171
212
 
172
- return self.__table
213
+ return self.__store_engine
173
214
 
174
215
 
175
216
  @property
176
- def group(
217
+ def store_session(
177
218
  self,
178
- ) -> str:
219
+ ) -> Session:
179
220
  """
180
221
  Return the value for the attribute from class instance.
181
222
 
182
223
  :returns: Value for the attribute from class instance.
183
224
  """
184
225
 
185
- return self.__group
226
+ return self.__store_session()
186
227
 
187
228
 
188
229
  @property
@@ -208,27 +249,26 @@ class Timers:
208
249
  params = self.__params
209
250
  timers = self.__timers
210
251
 
211
- sqlite = self.__sqlite
212
- table = self.__table
213
252
  group = self.__group
214
253
 
254
+ session = self.store_session
215
255
 
216
256
  config = params.timers
217
257
 
218
258
 
219
- cursor = sqlite.execute(
220
- f"""
221
- select * from {table}
222
- where "group"="{group}"
223
- order by "unique" asc
224
- """) # noqa: LIT003
259
+ _table = TimersTable
260
+ _group = _table.group
261
+ _unique = _table.unique
225
262
 
226
- records = cursor.fetchall()
263
+ query = (
264
+ session.query(_table)
265
+ .filter(_group == group)
266
+ .order_by(_unique))
227
267
 
228
- for record in records:
268
+ for record in query.all():
229
269
 
230
- unique = record[1]
231
- update = record[2]
270
+ unique = str(record.unique)
271
+ update = str(record.update)
232
272
 
233
273
  if unique not in config:
234
274
  continue
@@ -246,8 +286,7 @@ class Timers:
246
286
 
247
287
  timer = timers[key]
248
288
 
249
- timer.update(
250
- value.start)
289
+ timer.update(value.start)
251
290
 
252
291
  continue
253
292
 
@@ -270,42 +309,27 @@ class Timers:
270
309
 
271
310
  timers = self.__timers
272
311
 
273
- sqlite = self.__sqlite
274
- table = self.__table
275
312
  group = self.__group
276
313
 
314
+ session = self.store_session
277
315
 
278
- insert = tuple[
279
- str, # group
280
- str, # unique
281
- str] # update
282
-
283
- inserts: list[insert] = []
284
316
 
285
317
  items = timers.items()
286
318
 
287
319
  for unique, timer in items:
288
320
 
289
- append = (
290
- group, unique,
291
- Times('now').subsec)
292
-
293
- inserts.append(append)
321
+ update = Times('now')
294
322
 
323
+ append = TimersTable(
324
+ group=group,
325
+ unique=unique,
326
+ update=update.subsec)
295
327
 
296
- statement = (
297
- f"""
298
- replace into {table}
299
- ("group", "unique",
300
- "update")
301
- values (?, ?, ?)
302
- """) # noqa: LIT003
328
+ session.merge(append)
303
329
 
304
- sqlite.executemany(
305
- statement,
306
- tuple(sorted(inserts)))
307
330
 
308
- sqlite.commit()
331
+ session.commit()
332
+ session.close()
309
333
 
310
334
 
311
335
  def ready(
encommon/times/windows.py CHANGED
@@ -8,37 +8,72 @@ is permitted, for more information consult the project license file.
8
8
 
9
9
 
10
10
  from copy import deepcopy
11
- from sqlite3 import Connection
12
- from sqlite3 import connect as SQLite
13
11
  from typing import Optional
14
12
  from typing import TYPE_CHECKING
15
13
 
14
+ from sqlalchemy import Column
15
+ from sqlalchemy import String
16
+ from sqlalchemy import create_engine
17
+ from sqlalchemy.engine import Engine
18
+ from sqlalchemy.orm import DeclarativeBase
19
+ from sqlalchemy.orm import Session
20
+ from sqlalchemy.orm import sessionmaker
21
+
16
22
  from .common import PARSABLE
23
+ from .params import WindowsParams
17
24
  from .times import Times
18
25
  from .window import Window
19
26
 
20
27
  if TYPE_CHECKING:
21
28
  from .params import WindowParams
22
- from .params import WindowsParams
23
29
 
24
30
 
25
31
 
26
- CACHE_TABLE = (
32
+ WINDOWS = dict[str, Window]
33
+
34
+
35
+
36
+ class SQLBase(DeclarativeBase):
37
+ """
38
+ Some additional class that SQLAlchemy requires to work.
39
+
40
+ .. note::
41
+ Input parameters are not defined, check parent class.
27
42
  """
28
- create table if not exists
29
- {0} (
30
- "group" text not null,
31
- "unique" text not null,
32
- "last" text not null,
33
- "next" text not null,
34
- "update" text not null,
35
- primary key (
36
- "group", "unique"));
37
- """) # noqa: LIT003
38
43
 
39
44
 
40
45
 
41
- WINDOWS = dict[str, Window]
46
+ class WindowsTable(SQLBase):
47
+ """
48
+ Schematic for the database operations using SQLAlchemy.
49
+
50
+ .. note::
51
+ Fields are not completely documented for this model.
52
+ """
53
+
54
+ group = Column(
55
+ String,
56
+ primary_key=True,
57
+ nullable=False)
58
+
59
+ unique = Column(
60
+ String,
61
+ primary_key=True,
62
+ nullable=False)
63
+
64
+ last = Column(
65
+ String,
66
+ nullable=False)
67
+
68
+ next = Column(
69
+ String,
70
+ nullable=False)
71
+
72
+ update = Column(
73
+ String,
74
+ nullable=False)
75
+
76
+ __tablename__ = 'windows'
42
77
 
43
78
 
44
79
 
@@ -65,45 +100,51 @@ class Windows:
65
100
  :param params: Parameters for instantiating the instance.
66
101
  :param start: Determine the start for scheduling window.
67
102
  :param stop: Determine the ending for scheduling window.
68
- :param file: Optional path to file for SQLite database,
69
- allowing for state retention between the executions.
70
- :param table: Optional override for default table name.
103
+ :param store: Optional database path for keeping state.
71
104
  :param group: Optional override for default group name.
72
105
  """
73
106
 
74
107
  __params: 'WindowsParams'
75
108
 
109
+ __store: str
110
+ __group: str
111
+
112
+ __store_engine: Engine
113
+ __store_session: (
114
+ # pylint: disable=unsubscriptable-object
115
+ sessionmaker[Session])
116
+
76
117
  __start: Times
77
118
  __stop: Times
78
119
 
79
- __sqlite: Connection
80
- __file: str
81
- __table: str
82
- __group: str
83
-
84
120
  __windows: WINDOWS
85
121
 
86
122
 
87
- def __init__( # noqa: CFQ002
123
+ def __init__(
88
124
  self,
89
125
  params: Optional['WindowsParams'] = None,
90
126
  start: PARSABLE = 'now',
91
127
  stop: PARSABLE = '3000-01-01',
92
128
  *,
93
- file: str = ':memory:',
94
- table: str = 'windows',
129
+ store: str = 'sqlite:///:memory:',
95
130
  group: str = 'default',
96
131
  ) -> None:
97
132
  """
98
133
  Initialize instance for class using provided parameters.
99
134
  """
100
135
 
101
- from .params import WindowsParams
136
+ params = deepcopy(params)
102
137
 
103
138
  if params is None:
104
139
  params = WindowsParams()
105
140
 
106
- self.__params = deepcopy(params)
141
+ self.__params = params
142
+
143
+
144
+ self.__store = store
145
+ self.__group = group
146
+
147
+ self.__make_engine()
107
148
 
108
149
 
109
150
  start = Times(start)
@@ -115,23 +156,29 @@ class Windows:
115
156
  self.__stop = stop
116
157
 
117
158
 
118
- sqlite = SQLite(file)
159
+ self.__windows = {}
119
160
 
120
- sqlite.execute(
121
- CACHE_TABLE
122
- .format(table))
161
+ self.load_children()
123
162
 
124
- sqlite.commit()
125
163
 
126
- self.__sqlite = sqlite
127
- self.__file = file
128
- self.__table = table
129
- self.__group = group
164
+ def __make_engine(
165
+ self,
166
+ ) -> None:
167
+ """
168
+ Construct instances using the configuration parameters.
169
+ """
130
170
 
171
+ store = self.__store
131
172
 
132
- self.__windows = {}
173
+ engine = create_engine(store)
133
174
 
134
- self.load_children()
175
+ (SQLBase.metadata
176
+ .create_all(engine))
177
+
178
+ session = sessionmaker(engine)
179
+
180
+ self.__store_engine = engine
181
+ self.__store_session = session
135
182
 
136
183
 
137
184
  @property
@@ -148,81 +195,81 @@ class Windows:
148
195
 
149
196
 
150
197
  @property
151
- def start(
198
+ def store(
152
199
  self,
153
- ) -> Times:
200
+ ) -> str:
154
201
  """
155
202
  Return the value for the attribute from class instance.
156
203
 
157
204
  :returns: Value for the attribute from class instance.
158
205
  """
159
206
 
160
- return Times(self.__start)
207
+ return self.__store
161
208
 
162
209
 
163
210
  @property
164
- def stop(
211
+ def group(
165
212
  self,
166
- ) -> Times:
213
+ ) -> str:
167
214
  """
168
215
  Return the value for the attribute from class instance.
169
216
 
170
217
  :returns: Value for the attribute from class instance.
171
218
  """
172
219
 
173
- return Times(self.__stop)
220
+ return self.__group
174
221
 
175
222
 
176
223
  @property
177
- def sqlite(
224
+ def store_engine(
178
225
  self,
179
- ) -> Connection:
226
+ ) -> Engine:
180
227
  """
181
228
  Return the value for the attribute from class instance.
182
229
 
183
230
  :returns: Value for the attribute from class instance.
184
231
  """
185
232
 
186
- return self.__sqlite
233
+ return self.__store_engine
187
234
 
188
235
 
189
236
  @property
190
- def file(
237
+ def store_session(
191
238
  self,
192
- ) -> str:
239
+ ) -> Session:
193
240
  """
194
241
  Return the value for the attribute from class instance.
195
242
 
196
243
  :returns: Value for the attribute from class instance.
197
244
  """
198
245
 
199
- return self.__file
246
+ return self.__store_session()
200
247
 
201
248
 
202
249
  @property
203
- def table(
250
+ def start(
204
251
  self,
205
- ) -> str:
252
+ ) -> Times:
206
253
  """
207
254
  Return the value for the attribute from class instance.
208
255
 
209
256
  :returns: Value for the attribute from class instance.
210
257
  """
211
258
 
212
- return self.__table
259
+ return Times(self.__start)
213
260
 
214
261
 
215
262
  @property
216
- def group(
263
+ def stop(
217
264
  self,
218
- ) -> str:
265
+ ) -> Times:
219
266
  """
220
267
  Return the value for the attribute from class instance.
221
268
 
222
269
  :returns: Value for the attribute from class instance.
223
270
  """
224
271
 
225
- return self.__group
272
+ return Times(self.__stop)
226
273
 
227
274
 
228
275
  @property
@@ -251,27 +298,26 @@ class Windows:
251
298
  start = self.__start
252
299
  stop = self.__stop
253
300
 
254
- sqlite = self.__sqlite
255
- table = self.__table
256
301
  group = self.__group
257
302
 
303
+ session = self.store_session
258
304
 
259
305
  config = params.windows
260
306
 
261
307
 
262
- cursor = sqlite.execute(
263
- f"""
264
- select * from {table}
265
- where "group"="{group}"
266
- order by "unique" asc
267
- """) # noqa: LIT003
308
+ _table = WindowsTable
309
+ _group = _table.group
310
+ _unique = _table.unique
268
311
 
269
- records = cursor.fetchall()
312
+ query = (
313
+ session.query(_table)
314
+ .filter(_group == group)
315
+ .order_by(_unique))
270
316
 
271
- for record in records:
317
+ for record in query.all():
272
318
 
273
- unique = record[1]
274
- next = record[3]
319
+ unique = str(record.unique)
320
+ next = str(record.next)
275
321
 
276
322
  if unique not in config:
277
323
  continue
@@ -290,8 +336,7 @@ class Windows:
290
336
 
291
337
  window = windows[key]
292
338
 
293
- window.update(
294
- value.start)
339
+ window.update(value.start)
295
340
 
296
341
  continue
297
342
 
@@ -332,47 +377,29 @@ class Windows:
332
377
 
333
378
  windows = self.__windows
334
379
 
335
- sqlite = self.__sqlite
336
- table = self.__table
337
380
  group = self.__group
338
381
 
382
+ session = self.store_session
339
383
 
340
- insert = tuple[
341
- str, # group
342
- str, # unique
343
- str, # last
344
- str, # next
345
- str] # update
346
-
347
- inserts: list[insert] = []
348
384
 
349
385
  items = windows.items()
350
386
 
351
387
  for unique, window in items:
352
388
 
353
- append = (
354
- group, unique,
355
- window.last.subsec,
356
- window.next.subsec,
357
- Times('now').subsec)
358
-
359
- inserts.append(append)
389
+ update = Times('now')
360
390
 
391
+ append = WindowsTable(
392
+ group=group,
393
+ unique=unique,
394
+ last=window.last.subsec,
395
+ next=window.next.subsec,
396
+ update=update.subsec)
361
397
 
362
- statement = (
363
- f"""
364
- replace into {table}
365
- ("group", "unique",
366
- "next", "last",
367
- "update")
368
- values (?, ?, ?, ?, ?)
369
- """) # noqa: LIT003
398
+ session.merge(append)
370
399
 
371
- sqlite.executemany(
372
- statement,
373
- tuple(sorted(inserts)))
374
400
 
375
- sqlite.commit()
401
+ session.commit()
402
+ session.close()
376
403
 
377
404
 
378
405
  def ready(
encommon/version.txt CHANGED
@@ -1 +1 @@
1
- 0.11.1
1
+ 0.12.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: encommon
3
- Version: 0.11.1
3
+ Version: 0.12.1
4
4
  Summary: Enasis Network Common Library
5
5
  License: MIT
6
6
  Classifier: Programming Language :: Python :: 3
@@ -15,6 +15,7 @@ Requires-Dist: pydantic
15
15
  Requires-Dist: python-dateutil
16
16
  Requires-Dist: pyyaml
17
17
  Requires-Dist: snaptime
18
+ Requires-Dist: sqlalchemy
18
19
 
19
20
  # Enasis Network Common Library
20
21
 
@@ -73,16 +74,33 @@ information found in the `htmlcov` folder in the root of the project.
73
74
  make -s pytest
74
75
  ```
75
76
 
76
- ## Build and upload to PyPi
77
- Build the package.
78
- ```
79
- make -s pypackage
80
- ```
81
- Upload to the test PyPi.
82
- ```
83
- make -s pypi-upload-test
84
- ```
85
- Upload to the prod PyPi.
86
- ```
87
- make -s pypi-upload-prod
88
- ```
77
+ ## Version management
78
+ :warning: Ensure that no changes are pending.
79
+
80
+ 1. Rebuild the environment.
81
+ ```
82
+ make -s check-revenv
83
+ ```
84
+
85
+ 1. Update the [version.txt](encommon/version.txt) file.
86
+
87
+ 1. Push to the `main` branch.
88
+
89
+ 1. Create [repository](https://github.com/enasisnetwork/encommon) release.
90
+
91
+ 1. Build the Python package.<br>
92
+ ```
93
+ make -s pypackage
94
+ ```
95
+
96
+ 1. Upload Python package to PyPi test.
97
+ ```
98
+ make -s pypi-upload-test
99
+ ```
100
+
101
+ 1. Upload Python package to PyPi prod.
102
+ ```
103
+ make -s pypi-upload-prod
104
+ ```
105
+
106
+ 1. Update [Read the Docs](https://encommon.readthedocs.io) documentation.
@@ -1,12 +1,12 @@
1
1
  encommon/__init__.py,sha256=VoXUcphq-gcXCraaU47EtXBftF6UVuQPMGr0fuCTt9A,525
2
2
  encommon/conftest.py,sha256=zoshfXjo2y_NsmWSHErOaTZx7A5tSYxNAhUf4TmUZKE,1827
3
3
  encommon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- encommon/version.txt,sha256=_osjQQwNkAPnDBQcpybzxmm7wL9-Ost7o18jz3JgMys,7
4
+ encommon/version.txt,sha256=9u5pvxxLJ6JCJmzLWutKqMgwY0W56-T_czW4yUBFK4E,7
5
5
  encommon/config/__init__.py,sha256=iZdbW7A4m7iN4xt5cEeQqo0Klqs-CaPLdD5ocLmUYi8,856
6
6
  encommon/config/config.py,sha256=ldq1LfXGq0kfZwmlWE9mGG_hCdRuLT98QyLqnZY6ms8,5312
7
7
  encommon/config/files.py,sha256=ueXiKTOqlQ4GKUT9lLyOlE-tfr6QAkSxdUs0VPbwEnE,2385
8
- encommon/config/logger.py,sha256=qNizCbFNWtgb2tISJRiVx_KvNnS67mkkRrEgVzx6J_o,14141
9
- encommon/config/params.py,sha256=4bQ7Zz9DMLa5MrYtr89LuEkp0gAAsh7qG-b2wsSDLzI,2311
8
+ encommon/config/logger.py,sha256=7qjujhs0pI02gazhGpPCNa18qnuYpajVCTDlBkCtiro,14217
9
+ encommon/config/params.py,sha256=xygONdnwagGn06791nTX_mCR9hmdFl60RMe7MZr6ICw,2192
10
10
  encommon/config/paths.py,sha256=f0JDqkmd1xVd9KJ6s0b5KaFk-N6MlOjz4n1W39A5JHM,2533
11
11
  encommon/config/utils.py,sha256=VzTpBSZ-l6codt6vk4p4SpcmKk-H1OBy-9IUBPKP3t4,2039
12
12
  encommon/config/test/__init__.py,sha256=i0JAeRcM-0YH2StGfwpaDbZV9dVribNSgFDcYcPPay8,313
@@ -25,24 +25,24 @@ encommon/crypts/test/test_hashes.py,sha256=JYpPit7ISv6u-5-HbC3wSCxuieySDLKawgnE7
25
25
  encommon/times/__init__.py,sha256=aa3Wb2WBpZcf_RBgZu4vM3lEyPZhyuZicG5Fcg0DgEI,931
26
26
  encommon/times/common.py,sha256=g7kkZLyodZCIPpdiPCZh0-UMHwn-rwCv_Y6gdSvek6k,988
27
27
  encommon/times/duration.py,sha256=LTROiKcRXvPcs2Gz9KaB5Cmxo9NXd3TcMo5-jnTxPo0,10794
28
- encommon/times/params.py,sha256=llTThgIgoaKlAqPhONK1WA5RaDWURISp6XLdXxci0Tw,3753
28
+ encommon/times/params.py,sha256=qwfy7cw9_UlWUm2xWm1aRjJJZzZp36w3Bo3Rc-HU2hM,3515
29
29
  encommon/times/parse.py,sha256=DXoT_NyWL2Ea_j3vlGHMDY-5P6NBeYHyGhJoiavgBS0,6144
30
30
  encommon/times/timer.py,sha256=19dt7A5nJEUdr_0p3WDFGO-Q49OHt3sgPW4R2zHoScU,2901
31
- encommon/times/timers.py,sha256=CWm_flWVADIpjdKXaba1wbRtHqKy85Pm07eAG7k1aDw,8295
31
+ encommon/times/timers.py,sha256=uFzgfG1OFexXE-lW9muN_QYioDPXJMdOofpNxxuF_5Y,8696
32
32
  encommon/times/times.py,sha256=FBOAVY1H21OV4BjGHj6iJrYbGQpSkWPj3Ss2Vepdvu4,9682
33
33
  encommon/times/utils.py,sha256=PJ5QsKb3_pYEnD3Sz81d8QDhYQtTIj4HJfMoC9gNwmo,3100
34
34
  encommon/times/window.py,sha256=3ctrDd0UWvnwrqxRZf7M-mVeEYVWvet6GZTj17YQ9sU,8526
35
- encommon/times/windows.py,sha256=0ayWmfCBYlxc5e199ycj3HHupQOluWrooR8zn3eIRM8,9913
35
+ encommon/times/windows.py,sha256=PKGE_8lUUZs6ZsCB3anFmFnGTKK3-G4R4_n98F74gaI,10287
36
36
  encommon/times/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
37
37
  encommon/times/test/test_duration.py,sha256=ofCBdQ4-tOKP5W5U2xyTaZrCVvD-dWEgnYoCvZ99MuA,4189
38
38
  encommon/times/test/test_params.py,sha256=kHvs-WvKfPQCdCDnPU9tAyMVXmzH3eUjwQN-QdWBeh4,1407
39
39
  encommon/times/test/test_parse.py,sha256=ozP8PBgIsqdknK8cEtlYA3KusKnJzbjfAUKhcFv_eFk,4054
40
40
  encommon/times/test/test_timer.py,sha256=A5pBmkd1i71LTpG-uA9-9UGNJUK8tkw6by8Adm0AbGE,1400
41
- encommon/times/test/test_timers.py,sha256=pH-7QGVI0YUJUGXWD1Q9crmVswPqtOO3auiYnyYaskI,3851
41
+ encommon/times/test/test_timers.py,sha256=DxIiX4g7tbub4MAP3Z3-vAES5HbEzjDXMQPSAsIFavA,3845
42
42
  encommon/times/test/test_times.py,sha256=vxEtXI9gYFlWnBLsyPyi17a96MJzgcI79SCy8U1Co8I,1748
43
43
  encommon/times/test/test_utils.py,sha256=WkzHJY6zOt02Ujg5FItOo1nPtktz5ss8ODmG1tRQaaw,2056
44
44
  encommon/times/test/test_window.py,sha256=Sx_fd0J1ofaFx52t-uWz9Isa9KqBxPFnynzfGfiG7uo,6098
45
- encommon/times/test/test_windows.py,sha256=tw0SvutfP2eTB6R5P4stLRcQJcgr0pkmbxKEs49-0rs,4699
45
+ encommon/times/test/test_windows.py,sha256=dY7QYQ5BCBfAGotHrmkWkPGjRsI2od-8PbWkPwZ-QIM,4643
46
46
  encommon/types/__init__.py,sha256=L1pdigJyPNPEoAkkbCHM9IhmFtU2GjFRxHMRTAnPqKk,667
47
47
  encommon/types/dicts.py,sha256=lC2FmPzMEj9L73jUjf3o6OVQ-LqK_3gp5nBwYibdGfo,2265
48
48
  encommon/types/empty.py,sha256=n5y5maXkcM3xNYNYGK6iqvk98ivQSeguaedwc0HoMv4,2739
@@ -66,8 +66,8 @@ encommon/utils/test/test_match.py,sha256=QagKpTFdRo23-Y55fSaJrSMpt5jIebScKbz0h8t
66
66
  encommon/utils/test/test_paths.py,sha256=1yiZp5PCxljGk0J6fwIfWOUl-KWz40INybrwrN3JIog,1945
67
67
  encommon/utils/test/test_sample.py,sha256=sHAeWOL1mchTGYGQaFK_A3Z28tThuULumm9kQebnIdk,1710
68
68
  encommon/utils/test/test_stdout.py,sha256=TA7xQuFoPZUYW2l00e04MGp4P9gHkkVxVflvPlhpQXg,4878
69
- encommon-0.11.1.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
70
- encommon-0.11.1.dist-info/METADATA,sha256=LdI5NoYcQNPKSDWIdSjtwHPJquyKIY1qMd9hxCcUbRA,2918
71
- encommon-0.11.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
72
- encommon-0.11.1.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
73
- encommon-0.11.1.dist-info/RECORD,,
69
+ encommon-0.12.1.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
70
+ encommon-0.12.1.dist-info/METADATA,sha256=SjY2NeW39K-EjlErEdgmjS2069BIn39gle7zjAuqYcA,3362
71
+ encommon-0.12.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
72
+ encommon-0.12.1.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
73
+ encommon-0.12.1.dist-info/RECORD,,