naeural-client 2.0.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.
- naeural_client/__init__.py +13 -0
- naeural_client/_ver.py +13 -0
- naeural_client/base/__init__.py +6 -0
- naeural_client/base/distributed_custom_code_presets.py +44 -0
- naeural_client/base/generic_session.py +1763 -0
- naeural_client/base/instance.py +616 -0
- naeural_client/base/payload/__init__.py +1 -0
- naeural_client/base/payload/payload.py +66 -0
- naeural_client/base/pipeline.py +1499 -0
- naeural_client/base/plugin_template.py +5209 -0
- naeural_client/base/responses.py +209 -0
- naeural_client/base/transaction.py +157 -0
- naeural_client/base_decentra_object.py +143 -0
- naeural_client/bc/__init__.py +3 -0
- naeural_client/bc/base.py +1046 -0
- naeural_client/bc/chain.py +0 -0
- naeural_client/bc/ec.py +324 -0
- naeural_client/certs/__init__.py +0 -0
- naeural_client/certs/r9092118.ala.eu-central-1.emqxsl.com.crt +22 -0
- naeural_client/code_cheker/__init__.py +1 -0
- naeural_client/code_cheker/base.py +520 -0
- naeural_client/code_cheker/checker.py +294 -0
- naeural_client/comm/__init__.py +2 -0
- naeural_client/comm/amqp_wrapper.py +338 -0
- naeural_client/comm/mqtt_wrapper.py +539 -0
- naeural_client/const/README.md +3 -0
- naeural_client/const/__init__.py +9 -0
- naeural_client/const/base.py +101 -0
- naeural_client/const/comms.py +80 -0
- naeural_client/const/environment.py +26 -0
- naeural_client/const/formatter.py +7 -0
- naeural_client/const/heartbeat.py +111 -0
- naeural_client/const/misc.py +20 -0
- naeural_client/const/payload.py +190 -0
- naeural_client/default/__init__.py +1 -0
- naeural_client/default/instance/__init__.py +4 -0
- naeural_client/default/instance/chain_dist_custom_job_01_plugin.py +54 -0
- naeural_client/default/instance/custom_web_app_01_plugin.py +118 -0
- naeural_client/default/instance/net_mon_01_plugin.py +45 -0
- naeural_client/default/instance/view_scene_01_plugin.py +28 -0
- naeural_client/default/session/mqtt_session.py +72 -0
- naeural_client/io_formatter/__init__.py +2 -0
- naeural_client/io_formatter/base/__init__.py +1 -0
- naeural_client/io_formatter/base/base_formatter.py +80 -0
- naeural_client/io_formatter/default/__init__.py +3 -0
- naeural_client/io_formatter/default/a_dummy.py +51 -0
- naeural_client/io_formatter/default/aixp1.py +113 -0
- naeural_client/io_formatter/default/default.py +22 -0
- naeural_client/io_formatter/io_formatter_manager.py +96 -0
- naeural_client/logging/__init__.py +1 -0
- naeural_client/logging/base_logger.py +2056 -0
- naeural_client/logging/logger_mixins/__init__.py +12 -0
- naeural_client/logging/logger_mixins/class_instance_mixin.py +92 -0
- naeural_client/logging/logger_mixins/computer_vision_mixin.py +443 -0
- naeural_client/logging/logger_mixins/datetime_mixin.py +344 -0
- naeural_client/logging/logger_mixins/download_mixin.py +421 -0
- naeural_client/logging/logger_mixins/general_serialization_mixin.py +242 -0
- naeural_client/logging/logger_mixins/json_serialization_mixin.py +481 -0
- naeural_client/logging/logger_mixins/pickle_serialization_mixin.py +301 -0
- naeural_client/logging/logger_mixins/process_mixin.py +63 -0
- naeural_client/logging/logger_mixins/resource_size_mixin.py +81 -0
- naeural_client/logging/logger_mixins/timers_mixin.py +501 -0
- naeural_client/logging/logger_mixins/upload_mixin.py +260 -0
- naeural_client/logging/logger_mixins/utils_mixin.py +675 -0
- naeural_client/logging/small_logger.py +93 -0
- naeural_client/logging/tzlocal/__init__.py +20 -0
- naeural_client/logging/tzlocal/unix.py +231 -0
- naeural_client/logging/tzlocal/utils.py +113 -0
- naeural_client/logging/tzlocal/win32.py +151 -0
- naeural_client/logging/tzlocal/windows_tz.py +718 -0
- naeural_client/plugins_manager_mixin.py +273 -0
- naeural_client/utils/__init__.py +2 -0
- naeural_client/utils/comm_utils.py +44 -0
- naeural_client/utils/dotenv.py +75 -0
- naeural_client-2.0.0.dist-info/METADATA +365 -0
- naeural_client-2.0.0.dist-info/RECORD +78 -0
- naeural_client-2.0.0.dist-info/WHEEL +4 -0
- naeural_client-2.0.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,344 @@
|
|
1
|
+
from datetime import datetime as dt, timedelta
|
2
|
+
from dateutil.relativedelta import relativedelta
|
3
|
+
from ...const import WEEKDAYS_SHORT
|
4
|
+
|
5
|
+
|
6
|
+
class _DateTimeMixin(object):
|
7
|
+
"""
|
8
|
+
Mixin for date and time functionalities that are attached to `pye2.Logger`.
|
9
|
+
|
10
|
+
This mixin cannot be instantiated because it is built just to provide some additional
|
11
|
+
functionalities for `pye2.Logger`
|
12
|
+
|
13
|
+
In this mixin we can use any attribute/method of the Logger.
|
14
|
+
"""
|
15
|
+
|
16
|
+
def __init__(self):
|
17
|
+
super(_DateTimeMixin, self).__init__()
|
18
|
+
return
|
19
|
+
|
20
|
+
@staticmethod
|
21
|
+
def get_delta_date(date, delta=None, period=None):
|
22
|
+
daily_periods = ['d']
|
23
|
+
weekly_periods = ['w', 'w-mon', 'w-tue', 'w-wed', 'w-thu', 'w-fri', 'w-sat', 'w-sun']
|
24
|
+
monthly_periods = ['m']
|
25
|
+
|
26
|
+
if delta is None:
|
27
|
+
delta = 1
|
28
|
+
|
29
|
+
if period is None:
|
30
|
+
period = 'd'
|
31
|
+
|
32
|
+
period = period.lower()
|
33
|
+
assert period in daily_periods + weekly_periods + monthly_periods
|
34
|
+
|
35
|
+
is_string_date = False
|
36
|
+
fmt = '%Y-%m-%d'
|
37
|
+
if type(date) is str:
|
38
|
+
is_string_date = True
|
39
|
+
date = dt.strptime(date, fmt)
|
40
|
+
|
41
|
+
if period in daily_periods:
|
42
|
+
delta_date = date + relativedelta(days=delta)
|
43
|
+
elif period in monthly_periods:
|
44
|
+
delta_date = date + relativedelta(months=delta)
|
45
|
+
elif period in weekly_periods:
|
46
|
+
delta_date = date + relativedelta(weeks=delta)
|
47
|
+
|
48
|
+
if is_string_date:
|
49
|
+
delta_date = dt.strftime(delta_date, fmt)
|
50
|
+
|
51
|
+
return delta_date
|
52
|
+
|
53
|
+
@staticmethod
|
54
|
+
def split_time_intervals(start, stop, seconds_interval):
|
55
|
+
"""splits a predefined timeinterval [start, stop] into smaller intervals
|
56
|
+
each of length seconds_interval.
|
57
|
+
the method returns a list of dt tuples intervals"""
|
58
|
+
lst = []
|
59
|
+
_start = None
|
60
|
+
_stop = start
|
61
|
+
while _stop <= stop:
|
62
|
+
_start = _stop
|
63
|
+
_stop = _start + timedelta(seconds=seconds_interval)
|
64
|
+
lst.append((_start, _stop))
|
65
|
+
# endwhile
|
66
|
+
return lst
|
67
|
+
|
68
|
+
@staticmethod
|
69
|
+
def timestamp_begin(ts, begin_of):
|
70
|
+
"""returns a new timestamp as if it were the start of minute/hour/day/week/month/year"""
|
71
|
+
if ts is None:
|
72
|
+
ts = dt.now()
|
73
|
+
# endif
|
74
|
+
if begin_of == 'minute':
|
75
|
+
ts = dt(
|
76
|
+
year=ts.year, month=ts.month, day=ts.day,
|
77
|
+
hour=ts.hour, minute=ts.minute, second=0
|
78
|
+
)
|
79
|
+
elif begin_of == 'hour':
|
80
|
+
ts = dt(
|
81
|
+
year=ts.year, month=ts.month, day=ts.day,
|
82
|
+
hour=ts.hour, minute=0, second=0
|
83
|
+
)
|
84
|
+
elif begin_of == 'day':
|
85
|
+
ts = dt(
|
86
|
+
year=ts.year, month=ts.month, day=ts.day,
|
87
|
+
hour=0, minute=0, second=0
|
88
|
+
)
|
89
|
+
elif begin_of == 'month':
|
90
|
+
ts = dt(
|
91
|
+
year=ts.year, month=ts.month, day=1,
|
92
|
+
hour=0, minute=0, second=0
|
93
|
+
)
|
94
|
+
elif begin_of == 'year':
|
95
|
+
ts = dt(
|
96
|
+
year=ts.year, month=1, day=1,
|
97
|
+
hour=0, minute=0, second=0
|
98
|
+
)
|
99
|
+
# endif
|
100
|
+
return ts
|
101
|
+
|
102
|
+
@staticmethod
|
103
|
+
def time_in_interval_hours(ts, start, end):
|
104
|
+
"""
|
105
|
+
Parameters:
|
106
|
+
ts: datetime timestamp
|
107
|
+
start = 'hh:mm'
|
108
|
+
end = 'hh:mm'
|
109
|
+
Returns:
|
110
|
+
True if given timestamp is in given interval
|
111
|
+
"""
|
112
|
+
h_start, m_start = start.split(':')
|
113
|
+
h_end, m_end = end.split(':')
|
114
|
+
start_time = int(h_start) * 60 + int(m_start)
|
115
|
+
end_time = int(h_end) * 60 + int(m_end)
|
116
|
+
current_time = ts.hour * 60 + ts.minute
|
117
|
+
is_inside_interval = start_time <= current_time < end_time
|
118
|
+
if end_time < start_time:
|
119
|
+
# e.g. for interval (22:30, 14:30) we will check that the current time is not in (14:30, 22:30)
|
120
|
+
is_inside_interval = not (end_time <= current_time < start_time)
|
121
|
+
return is_inside_interval
|
122
|
+
|
123
|
+
@staticmethod
|
124
|
+
def now_in_interval_hours(start, end):
|
125
|
+
"""
|
126
|
+
Parameters:
|
127
|
+
start = 'hh:mm'
|
128
|
+
end = 'hh:mm'
|
129
|
+
Returns:
|
130
|
+
True if current time is in given interval
|
131
|
+
"""
|
132
|
+
return _DateTimeMixin.time_in_interval_hours(
|
133
|
+
ts=dt.now(),
|
134
|
+
start=start,
|
135
|
+
end=end
|
136
|
+
)
|
137
|
+
|
138
|
+
@staticmethod
|
139
|
+
def extract_hour_interval_idx(ts, lst_schedule):
|
140
|
+
"""
|
141
|
+
Method for extracting index of interval in which ts is situated.
|
142
|
+
Parameters
|
143
|
+
----------
|
144
|
+
ts - datetime timestamp - the searched timestamp
|
145
|
+
schedule - list of format [
|
146
|
+
['hh:mm', 'hh:mm'],
|
147
|
+
...
|
148
|
+
] describing intervals of time
|
149
|
+
|
150
|
+
Returns
|
151
|
+
-------
|
152
|
+
idx - int or None
|
153
|
+
If found in an interval idx will be the index of that interval in schedule
|
154
|
+
Otherwise it will be None
|
155
|
+
"""
|
156
|
+
for idx, (start, end) in enumerate(lst_schedule):
|
157
|
+
if _DateTimeMixin.time_in_interval_hours(ts=ts, start=start, end=end):
|
158
|
+
return idx
|
159
|
+
return None
|
160
|
+
|
161
|
+
@staticmethod
|
162
|
+
def extract_weekday_schedule(ts, schedule, weekdays=None, return_day_name=False):
|
163
|
+
"""
|
164
|
+
Method for extracting the working hour intervals corresponding to the weekday
|
165
|
+
indicated by ts in case the schedule is defined using weekdays.
|
166
|
+
Parameters
|
167
|
+
----------
|
168
|
+
ts - datetime timestamp - the timestamp for which we need the working hours
|
169
|
+
schedule - dict or any
|
170
|
+
- if dict it will be able to provide different working hours for each weekday
|
171
|
+
- the keys from schedule need to be in weekdays of if weekdays not provided in ['MON', 'TUE', ..., 'SUN']
|
172
|
+
- otherwise it will be returned as it is
|
173
|
+
weekdays - list of aliases for the weekdays
|
174
|
+
- if this is not provided it will default to ['MON', 'TUE', ..., 'SUN']
|
175
|
+
- this has to be of length 7 if provided
|
176
|
+
return_day_name - boolean that indicates if we will provide only
|
177
|
+
the working hours or the name of the week day too
|
178
|
+
|
179
|
+
Returns
|
180
|
+
-------
|
181
|
+
if return_day_name:
|
182
|
+
res
|
183
|
+
list of format [
|
184
|
+
['hh:mm', 'hh:mm'],
|
185
|
+
...
|
186
|
+
] describing intervals of time
|
187
|
+
OR
|
188
|
+
None
|
189
|
+
otherwise:
|
190
|
+
res, day_name - res described as above and day_name as a string or None in case schedule is not dict
|
191
|
+
"""
|
192
|
+
if isinstance(schedule, dict):
|
193
|
+
if weekdays is None:
|
194
|
+
weekdays = WEEKDAYS_SHORT
|
195
|
+
assert len(weekdays) == 7, \
|
196
|
+
f"`weekdays` should be a list of length 7, but it is {weekdays} with length {len(weekdays)}"
|
197
|
+
|
198
|
+
normalized_weekdays = [x.upper() for x in weekdays]
|
199
|
+
normalized_schedule = {
|
200
|
+
key.upper(): value
|
201
|
+
for (key, value) in schedule.items()
|
202
|
+
}
|
203
|
+
for key in schedule.keys():
|
204
|
+
if key.upper() not in normalized_weekdays:
|
205
|
+
raise Exception(f'Key {key} should not be in the schedule dictionary!'
|
206
|
+
f'The keys in the schedule dictionary can only be from {normalized_weekdays}')
|
207
|
+
# endfor key in schedule.keys()
|
208
|
+
|
209
|
+
ts_weekday_str = normalized_weekdays[ts.weekday()]
|
210
|
+
res = normalized_schedule.get(ts_weekday_str, None)
|
211
|
+
return res if not return_day_name else (res, ts_weekday_str)
|
212
|
+
return schedule if not return_day_name else (schedule, None)
|
213
|
+
|
214
|
+
@staticmethod
|
215
|
+
def extract_weekday_schedule_now(schedule, weekdays=None, return_day_name=False):
|
216
|
+
"""
|
217
|
+
Shortcut extract_weekday_schedule with ts=datetime.now()
|
218
|
+
"""
|
219
|
+
return _DateTimeMixin.extract_weekday_schedule(
|
220
|
+
ts=dt.now(),
|
221
|
+
schedule=schedule,
|
222
|
+
weekdays=weekdays,
|
223
|
+
return_day_name=return_day_name
|
224
|
+
)
|
225
|
+
|
226
|
+
@staticmethod
|
227
|
+
def time_in_schedule(ts, schedule, weekdays=None):
|
228
|
+
"""
|
229
|
+
Method for checking if the provided timestamp in ts is in some interval specified in schedule.
|
230
|
+
Parameters
|
231
|
+
----------
|
232
|
+
ts - datetime timestamp - the timestamp to be checked
|
233
|
+
schedule - dict or any
|
234
|
+
- if dict it will be able to provide different working hours for each weekday
|
235
|
+
- the keys from schedule need to be in weekdays of if weekdays not provided in ['MON', 'TUE', ..., 'SUN']
|
236
|
+
- otherwise it will be returned as it is
|
237
|
+
weekdays - list of aliases for the weekdays
|
238
|
+
- if this is not provided it will default to ['MON', 'TUE', ..., 'SUN']
|
239
|
+
- this has to be of length 7 if provided
|
240
|
+
return_day_name - boolean that indicates if we will provide only
|
241
|
+
the working hours or the name of the week day too
|
242
|
+
|
243
|
+
Returns
|
244
|
+
-------
|
245
|
+
False if:
|
246
|
+
- schedule is None
|
247
|
+
- schedule provides hour intervals but ts is not in any of them
|
248
|
+
True otherwise
|
249
|
+
"""
|
250
|
+
if schedule is None:
|
251
|
+
return False
|
252
|
+
if len(schedule) < 1:
|
253
|
+
return True
|
254
|
+
if isinstance(schedule, list):
|
255
|
+
# ts in schedule ignoring the weekday
|
256
|
+
if len(schedule) < 1:
|
257
|
+
return True
|
258
|
+
for (start, end) in schedule:
|
259
|
+
if _DateTimeMixin.time_in_interval_hours(ts=ts, start=start, end=end):
|
260
|
+
return True
|
261
|
+
return False
|
262
|
+
elif isinstance(schedule, dict):
|
263
|
+
# ts in schedule considering the weekday
|
264
|
+
return _DateTimeMixin.time_in_schedule(
|
265
|
+
ts=ts,
|
266
|
+
schedule=_DateTimeMixin.extract_weekday_schedule(
|
267
|
+
ts=ts,
|
268
|
+
schedule=schedule,
|
269
|
+
weekdays=weekdays
|
270
|
+
)
|
271
|
+
)
|
272
|
+
# endif isinstance(schedule, list)
|
273
|
+
raise Exception(f'`schedule` should be either list, dict or None, but instead is {type(schedule)}')
|
274
|
+
|
275
|
+
@staticmethod
|
276
|
+
def now_in_schedule(schedule, weekdays=None):
|
277
|
+
return _DateTimeMixin.time_in_schedule(
|
278
|
+
ts=dt.now(),
|
279
|
+
schedule=schedule,
|
280
|
+
weekdays=weekdays
|
281
|
+
)
|
282
|
+
|
283
|
+
|
284
|
+
if __name__ == '__main__':
|
285
|
+
from PyE2 import Logger
|
286
|
+
log = Logger(
|
287
|
+
'gigi',
|
288
|
+
base_folder='.',
|
289
|
+
app_folder='_local_cache'
|
290
|
+
)
|
291
|
+
|
292
|
+
working_hours_tests = [
|
293
|
+
[ # list of universal working hours interval for any day
|
294
|
+
['10:10', '21:10']
|
295
|
+
],
|
296
|
+
[ # list of universal working hours intervals for any day
|
297
|
+
['21:10', '10:10'],
|
298
|
+
['11:10', '11:25']
|
299
|
+
],
|
300
|
+
{ # dict of working hours intervals based on the week day with all the days described
|
301
|
+
"mon": [["07:00", "18:00"]],
|
302
|
+
"tue": [["07:00", "15:00"], ["16:30", "19:30"]],
|
303
|
+
"wEd": [["07:00", "18:00"]],
|
304
|
+
"thU": [["07:00", "18:00"]],
|
305
|
+
"FRI": [], # when [] given the entire day will be considered opened
|
306
|
+
"sat": [["00:00", "24:00"]],
|
307
|
+
"sun": [["10:00", "15:00"]]
|
308
|
+
},
|
309
|
+
{ # dict of working hours intervals based on the week day with some the days described
|
310
|
+
# (the undescribed days will be considered fully closed)
|
311
|
+
"mon": None, # when None given the specified date will also be considered fully closed
|
312
|
+
"tue": [["07:00", "15:00"], ["16:30", "19:30"]],
|
313
|
+
"wed": [["07:00", "18:00"]],
|
314
|
+
},
|
315
|
+
{ # dict of working hours intervals based on the week day with some the days described,
|
316
|
+
# but with unexpected fields => an exception should be raised
|
317
|
+
"mon": [],
|
318
|
+
"TuesdayWednesday": [["07:00", "15:11"]]
|
319
|
+
}
|
320
|
+
]
|
321
|
+
|
322
|
+
should_raise = [False, False, False, False, True]
|
323
|
+
it = 0
|
324
|
+
for cfg_test in working_hours_tests:
|
325
|
+
log.P(f'Starting test {it + 1}/{len(working_hours_tests)}')
|
326
|
+
log.P(f'Current schedule is: {cfg_test}')
|
327
|
+
current_ts = dt.now()
|
328
|
+
log.P(f'Now the time is: {current_ts}({WEEKDAYS_SHORT[current_ts.weekday()]})')
|
329
|
+
try:
|
330
|
+
if log.time_in_schedule(ts=current_ts, schedule=cfg_test):
|
331
|
+
log.P('We are in working hours!')
|
332
|
+
else:
|
333
|
+
log.P('We are not in working hours!')
|
334
|
+
log.P(f'Test {it + 1}/{len(working_hours_tests)} passed!')
|
335
|
+
except Exception as e:
|
336
|
+
log.P(f'Exception occured `{e}`')
|
337
|
+
if should_raise[it]:
|
338
|
+
log.P(f'Test {it + 1}/{len(working_hours_tests)} (expected exception) passed!')
|
339
|
+
else:
|
340
|
+
log.P(f'Test {it + 1}/{len(working_hours_tests)} failed!')
|
341
|
+
|
342
|
+
it += 1
|
343
|
+
# endfor cfg_test in working_hours_tests
|
344
|
+
|