easy-utils-dev 2.138__py3-none-any.whl → 2.140__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.
- easy_utils_dev/EasySsh.py +1 -1
- easy_utils_dev/debugger-C-PF4PAMMP.py +486 -0
- easy_utils_dev/debugger.py +9 -0
- easy_utils_dev/temp_memory.py +15 -8
- easy_utils_dev/wsnoclib.py +165 -121
- {easy_utils_dev-2.138.dist-info → easy_utils_dev-2.140.dist-info}/METADATA +8 -6
- {easy_utils_dev-2.138.dist-info → easy_utils_dev-2.140.dist-info}/RECORD +9 -8
- {easy_utils_dev-2.138.dist-info → easy_utils_dev-2.140.dist-info}/WHEEL +1 -1
- {easy_utils_dev-2.138.dist-info → easy_utils_dev-2.140.dist-info}/top_level.txt +0 -0
easy_utils_dev/EasySsh.py
CHANGED
|
@@ -69,7 +69,7 @@ class CREATESSH :
|
|
|
69
69
|
ch.disconnect = disconnect
|
|
70
70
|
return ch
|
|
71
71
|
|
|
72
|
-
def ssh_execute(self ,command , merge_output=False , hide_output=
|
|
72
|
+
def ssh_execute(self ,command , merge_output=False , hide_output=True) :
|
|
73
73
|
self.logger.info(f"executing {command}")
|
|
74
74
|
try :
|
|
75
75
|
stdin_ , stdout_ , stderr_ = self.ssh.exec_command(command)
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from logging.handlers import RotatingFileHandler
|
|
6
|
+
from .utils import getRandomKey , convert_mb_to_bytes , getTimestamp , start_thread
|
|
7
|
+
from .custom_env import custom_env , setupEnvironment
|
|
8
|
+
from .Events import EventEmitter
|
|
9
|
+
from threading import Thread
|
|
10
|
+
from time import sleep
|
|
11
|
+
|
|
12
|
+
gEvent = EventEmitter()
|
|
13
|
+
logging.addLevelName(25, "SCREEN")
|
|
14
|
+
|
|
15
|
+
def setGlobalHomePath( path ) :
|
|
16
|
+
env = custom_env()
|
|
17
|
+
env['debugger_homepath'] = path
|
|
18
|
+
gEvent.dispatchEvent('update_home_path')
|
|
19
|
+
|
|
20
|
+
def setGlobalDisableOnScreen(on_screen=False) :
|
|
21
|
+
env = custom_env()
|
|
22
|
+
env['debugger_on_screen'] = on_screen
|
|
23
|
+
if not on_screen :
|
|
24
|
+
gEvent.dispatchEvent('disable_global_printing')
|
|
25
|
+
else :
|
|
26
|
+
gEvent.dispatchEvent('enable_global_printing')
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def setGlobalDebugLevel(level='info') :
|
|
30
|
+
env = custom_env()
|
|
31
|
+
env['debugger_global_level'] = level
|
|
32
|
+
gEvent.dispatchEvent('update_debug_level')
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DEBUGGER:
|
|
36
|
+
def __init__(self
|
|
37
|
+
, name
|
|
38
|
+
, level='info',
|
|
39
|
+
fullSyntax=True,
|
|
40
|
+
onscreen=True,
|
|
41
|
+
log_rotation=3,
|
|
42
|
+
homePath=None,
|
|
43
|
+
id=getRandomKey(9) ,
|
|
44
|
+
global_debugger=None,
|
|
45
|
+
disable_log_write=False,
|
|
46
|
+
file_name=None,
|
|
47
|
+
seperate_files=True
|
|
48
|
+
):
|
|
49
|
+
env = custom_env()
|
|
50
|
+
setupEnvironment( 'debugger' )
|
|
51
|
+
debugger_on_screen = env.get('debugger_on_screen' , True)
|
|
52
|
+
env['debugger_on_screen'] = debugger_on_screen
|
|
53
|
+
self.env = env
|
|
54
|
+
self.events = gEvent
|
|
55
|
+
self.debuggerLabel = f"{name}"
|
|
56
|
+
self.logger = logging.getLogger(self.debuggerLabel)
|
|
57
|
+
self.set_level(level)
|
|
58
|
+
self.file_handler_class=None
|
|
59
|
+
self.LOG_SIZE_THRESHOLD_IN_BYTES = 10 * 1024 * 1024
|
|
60
|
+
self.BACKUP_COUNT = log_rotation
|
|
61
|
+
self.homePath = homePath
|
|
62
|
+
self.lastAbsoluteHomePath= None
|
|
63
|
+
self.fullSyntax=fullSyntax
|
|
64
|
+
self.onScreen= onscreen
|
|
65
|
+
self.id = id
|
|
66
|
+
self.how_many_times_write= 0
|
|
67
|
+
self.stream_service = None
|
|
68
|
+
if not env['debugger'].get(name) :
|
|
69
|
+
self.console = console_handler = logging.StreamHandler()
|
|
70
|
+
else :
|
|
71
|
+
self.console = console_handler = env['debugger'].get(name).console
|
|
72
|
+
if not self.logger.hasHandlers() :
|
|
73
|
+
self.logger.addHandler(self.console)
|
|
74
|
+
self.name = name
|
|
75
|
+
self.rotate_disabled=False
|
|
76
|
+
self.isInPyinstaller = False
|
|
77
|
+
self.log_iterations=0
|
|
78
|
+
self.log_iterations_threshold = 200
|
|
79
|
+
self.global_debugger = global_debugger
|
|
80
|
+
self.isLogWriteDisabled = disable_log_write
|
|
81
|
+
self.type = "CUSTOM_DEBUGGER"
|
|
82
|
+
self.seperate_files=seperate_files
|
|
83
|
+
if fullSyntax :
|
|
84
|
+
f = f"[%(asctime)s]-[{self.name}]-[%(levelname)s]: %(message)s"
|
|
85
|
+
else :
|
|
86
|
+
f = f"[{self.name}]-[%(levelname)s]: %(message)s"
|
|
87
|
+
self.syntax = f
|
|
88
|
+
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
89
|
+
self.filename = file_name
|
|
90
|
+
path = self.homepath(homePath)
|
|
91
|
+
if not env['debugger'].get(name) :
|
|
92
|
+
console_handler.setFormatter(self.formatter)
|
|
93
|
+
if not disable_log_write :
|
|
94
|
+
if not env['debugger'].get(name) :
|
|
95
|
+
self.file_handler_class = self.createRotateFileHandler(path)
|
|
96
|
+
if onscreen :
|
|
97
|
+
self.enable_print()
|
|
98
|
+
elif not onscreen :
|
|
99
|
+
self.disable_print()
|
|
100
|
+
self.events.addEventListener('disable_global_printing' , self.disable_print )
|
|
101
|
+
self.events.addEventListener('enable_global_printing' , self.enable_print )
|
|
102
|
+
self.events.addEventListener('update_home_path' , self.updateGlobalHomePath )
|
|
103
|
+
self.events.addEventListener('update_debug_level' , self.updateGlobalSetLevel )
|
|
104
|
+
if env['debugger'].get(name) :
|
|
105
|
+
self = env['debugger'].get(name)
|
|
106
|
+
else:
|
|
107
|
+
env['debugger'][id] = self
|
|
108
|
+
env['debugger'][name] = self
|
|
109
|
+
if not env.get('debugger_on_screen' , True ) :
|
|
110
|
+
self.disable_print()
|
|
111
|
+
if env.get('debugger_on_screen' , True ) :
|
|
112
|
+
self.enable_print()
|
|
113
|
+
if os.environ.get("EASY_UTILS_DEBUG_LEVEL") :
|
|
114
|
+
EASY_UTILS_DEBUG_LEVEL = os.environ.get("EASY_UTILS_DEBUG_LEVEL")
|
|
115
|
+
if not EASY_UTILS_DEBUG_LEVEL.lower() in ['info' , 'debug' , 'warning' , 'error' , 'critical'] :
|
|
116
|
+
self.logger.error(f'EASY_UTILS_DEBUG_LEVEL ENV must be one of [info,debug,warning,error,critical] | Current Env Variable Is "{EASY_UTILS_DEBUG_LEVEL}". Skipping ')
|
|
117
|
+
else :
|
|
118
|
+
self.set_level(EASY_UTILS_DEBUG_LEVEL)
|
|
119
|
+
if os.environ.get("EASY_UTILS_ENABLE_PRINT" , '' ).lower() == 'true' :
|
|
120
|
+
self.enable_print()
|
|
121
|
+
|
|
122
|
+
def switch_full_syntax(self , toggle) :
|
|
123
|
+
if toggle :
|
|
124
|
+
f = f"[%(asctime)s]-[{self.name}]-[%(levelname)s]: %(message)s"
|
|
125
|
+
else :
|
|
126
|
+
f = f"[{self.name}]-[%(levelname)s]: %(message)s"
|
|
127
|
+
self.syntax = f
|
|
128
|
+
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
129
|
+
self.console.setFormatter(self.formatter)
|
|
130
|
+
|
|
131
|
+
def custom_log_syntax(self , syntax) :
|
|
132
|
+
'''
|
|
133
|
+
f"[%(asctime)s]-[{self.name}]-[%(levelname)s]: %(message)s"
|
|
134
|
+
'''
|
|
135
|
+
f = syntax
|
|
136
|
+
self.syntax = f
|
|
137
|
+
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
138
|
+
self.console.setFormatter(self.formatter)
|
|
139
|
+
|
|
140
|
+
def updateGlobalHomePath(self ) :
|
|
141
|
+
if not self.isLogWriteDisabled :
|
|
142
|
+
getFromEnv = self.env.get('debugger_homepath' , None )
|
|
143
|
+
self.homepath(getFromEnv)
|
|
144
|
+
if getFromEnv :
|
|
145
|
+
self.file_handler_class = self.createRotateFileHandler(self.homePath)
|
|
146
|
+
|
|
147
|
+
def updateGlobalSetLevel( self ) :
|
|
148
|
+
self.set_level(self.env['debugger_global_level'])
|
|
149
|
+
|
|
150
|
+
def advertiseGlobalDebugLevel(self , level) :
|
|
151
|
+
setGlobalDebugLevel(level)
|
|
152
|
+
|
|
153
|
+
def disable_rotate(self) :
|
|
154
|
+
self.rotate_disabled = True
|
|
155
|
+
|
|
156
|
+
def enable_rotate(self) :
|
|
157
|
+
self.rotate_disabled = False
|
|
158
|
+
|
|
159
|
+
def createRotateFileHandler( self , path ) :
|
|
160
|
+
old = self.file_handler_class
|
|
161
|
+
if old :
|
|
162
|
+
self.logger.removeHandler(old)
|
|
163
|
+
file_handler = RotatingFileHandler(path , maxBytes=self.LOG_SIZE_THRESHOLD_IN_BYTES , backupCount=self.BACKUP_COUNT , delay=True )
|
|
164
|
+
self.file_handler= file_handler.setFormatter(self.formatter)
|
|
165
|
+
self.logger.addHandler(file_handler)
|
|
166
|
+
return file_handler
|
|
167
|
+
|
|
168
|
+
def update_log_iterantions_threshold(self,threshold : int ):
|
|
169
|
+
'''
|
|
170
|
+
set value when rotation should be checked. when every on_log function called.
|
|
171
|
+
by default rotation will be checked every 200 on_log function call.
|
|
172
|
+
'''
|
|
173
|
+
self.log_iterations_threshold = threshold
|
|
174
|
+
|
|
175
|
+
def updateGlobalDebugger(self , logger ) :
|
|
176
|
+
'''
|
|
177
|
+
this function pass the log message to other logger to write the same log message to it.
|
|
178
|
+
logger must be debugger class.
|
|
179
|
+
'''
|
|
180
|
+
if logger.type != 'CUSTOM_DEBUGGER' :
|
|
181
|
+
raise Exception(f'Invalid logger type. must pass debugger class.')
|
|
182
|
+
self.global_debugger = logger
|
|
183
|
+
|
|
184
|
+
def getStreamServiceUrlPath(self) :
|
|
185
|
+
return self.streampath
|
|
186
|
+
|
|
187
|
+
def getStreamService(self) :
|
|
188
|
+
return self.stream_service
|
|
189
|
+
|
|
190
|
+
def isStreamServiceAvailable(self) :
|
|
191
|
+
if self.stream_service :
|
|
192
|
+
return True
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
def addStreamService( self , socketio , streampath='/debugger/stream/log' ) :
|
|
196
|
+
"""
|
|
197
|
+
This function takes a live socketio server. it emit the log message using default path which is /debugger/stream/log
|
|
198
|
+
"""
|
|
199
|
+
self.stream_service = socketio
|
|
200
|
+
self.streampath = streampath
|
|
201
|
+
|
|
202
|
+
def updateLogName( self , name ) :
|
|
203
|
+
self.name = name
|
|
204
|
+
|
|
205
|
+
def disable_log_write(self) :
|
|
206
|
+
'''
|
|
207
|
+
this function is used to disable the log write to file. if onScreen is enabled, logs will be displayed only on screen.
|
|
208
|
+
'''
|
|
209
|
+
self.isLogWriteDisabled = True
|
|
210
|
+
if self.file_handler_class :
|
|
211
|
+
self.logger.removeHandler(self.file_handler_class)
|
|
212
|
+
|
|
213
|
+
def enable_log_write(self) :
|
|
214
|
+
self.createRotateFileHandler(self.homePath)
|
|
215
|
+
|
|
216
|
+
def manage_file_rotation(self, record ) :
|
|
217
|
+
handler = self.get_rotate_handler()
|
|
218
|
+
if handler.shouldRollover(record) :
|
|
219
|
+
handler.doRollover()
|
|
220
|
+
self.log_iterations = 0
|
|
221
|
+
|
|
222
|
+
def get_rotate_handler(self) :
|
|
223
|
+
return self.file_handler_class
|
|
224
|
+
|
|
225
|
+
def change_log_size(self, size) -> bool:
|
|
226
|
+
'''
|
|
227
|
+
change the size of each log file rotation.
|
|
228
|
+
default is 10M
|
|
229
|
+
size should be passed as MB
|
|
230
|
+
'''
|
|
231
|
+
size = convert_mb_to_bytes(size)
|
|
232
|
+
self.LOG_SIZE_THRESHOLD_IN_BYTES = size
|
|
233
|
+
handler = self.get_rotate_handler()
|
|
234
|
+
handler.maxBytes = size
|
|
235
|
+
return True
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def checks_in_bg(self) :
|
|
239
|
+
while True :
|
|
240
|
+
if self.env.get('GLOBAL_DEBUGGER_STREAM_SERVICE') :
|
|
241
|
+
self.addStreamService(socketio=self.env.get('GLOBAL_DEBUGGER_STREAM_SERVICE'))
|
|
242
|
+
if self.env.get('debugger_global_level' , None) :
|
|
243
|
+
self.set_level( level=self.env.get('debugger_global_level') )
|
|
244
|
+
if not self.env.get('debugger_on_screen' , True ) :
|
|
245
|
+
self.disable_print()
|
|
246
|
+
if self.env.get('debugger_on_screen' , True ) :
|
|
247
|
+
self.enable_print()
|
|
248
|
+
if os.environ.get("EASY_UTILS_DEBUG_LEVEL") :
|
|
249
|
+
EASY_UTILS_DEBUG_LEVEL = os.environ.get("EASY_UTILS_DEBUG_LEVEL")
|
|
250
|
+
if not EASY_UTILS_DEBUG_LEVEL.lower() in ['info' , 'debug' , 'warning' , 'error' , 'critical'] :
|
|
251
|
+
self.logger.error(f'EASY_UTILS_DEBUG_LEVEL ENV must be one of [info,debug,warning,error,critical] | Current Env Variable Is "{EASY_UTILS_DEBUG_LEVEL}". Skipping ')
|
|
252
|
+
else :
|
|
253
|
+
self.set_level(EASY_UTILS_DEBUG_LEVEL)
|
|
254
|
+
self.updateGlobalHomePath()
|
|
255
|
+
if os.environ.get("EASY_UTILS_ENABLE_PRINT" , '' ).lower() == 'true' :
|
|
256
|
+
self.enable_print()
|
|
257
|
+
sleep(5)
|
|
258
|
+
|
|
259
|
+
def close(self) :
|
|
260
|
+
try :
|
|
261
|
+
logging.shutdown()
|
|
262
|
+
except :
|
|
263
|
+
pass
|
|
264
|
+
|
|
265
|
+
def homepath(self , path=None ) :
|
|
266
|
+
env = custom_env()
|
|
267
|
+
getFromEnv = env.get('debugger_homepath' , None )
|
|
268
|
+
if getFromEnv is not None :
|
|
269
|
+
self.homePath = getFromEnv
|
|
270
|
+
else :
|
|
271
|
+
if path is not None :
|
|
272
|
+
if self.homePath and '.log' in str(self.homePath):
|
|
273
|
+
self.lastAbsoluteHomePath= self.homePath
|
|
274
|
+
self.homePath = path
|
|
275
|
+
else :
|
|
276
|
+
self.homePath = os.path.join(os.getcwd() , 'debug')
|
|
277
|
+
if not os.path.exists( self.homePath ) :
|
|
278
|
+
try :
|
|
279
|
+
os.makedirs( self.homePath )
|
|
280
|
+
except :
|
|
281
|
+
pass
|
|
282
|
+
if self.filename :
|
|
283
|
+
self.homePath = os.path.join( self.homePath, f'{self.filename}.log' )
|
|
284
|
+
else :
|
|
285
|
+
self.homePath = os.path.join( self.homePath, f'{self.name}.log' )
|
|
286
|
+
return self.homePath
|
|
287
|
+
|
|
288
|
+
def get_current_levels(self):
|
|
289
|
+
"""
|
|
290
|
+
Returns a list of log levels that will be printed based on the current logging level.
|
|
291
|
+
"""
|
|
292
|
+
levels_order = [
|
|
293
|
+
('debug', logging.DEBUG),
|
|
294
|
+
('info', logging.INFO),
|
|
295
|
+
('warning', logging.WARNING),
|
|
296
|
+
('error', logging.ERROR),
|
|
297
|
+
('critical', logging.CRITICAL),
|
|
298
|
+
]
|
|
299
|
+
# Optional custom level
|
|
300
|
+
if hasattr(logging, 'SCREEN'):
|
|
301
|
+
levels_order.append(('screen', logging.SCREEN))
|
|
302
|
+
current_level = self.logger.level
|
|
303
|
+
# Return all levels with numeric value >= current_level
|
|
304
|
+
return [name for name, value in levels_order if value >= current_level]
|
|
305
|
+
|
|
306
|
+
def enable_print(self) :
|
|
307
|
+
self.onScreen = True
|
|
308
|
+
self.logger.addHandler(self.console)
|
|
309
|
+
|
|
310
|
+
def disable_print(self) :
|
|
311
|
+
self.onScreen = False
|
|
312
|
+
self.logger.removeHandler(self.console)
|
|
313
|
+
|
|
314
|
+
def changeHomePath( self , path ) :
|
|
315
|
+
p = self.homepath(path)
|
|
316
|
+
self.file_handler_class = self.createRotateFileHandler(p)
|
|
317
|
+
if self.lastAbsoluteHomePath :
|
|
318
|
+
os.remove(self.lastAbsoluteHomePath)
|
|
319
|
+
|
|
320
|
+
def isGlobalDebuggerDefined(self) :
|
|
321
|
+
if self.global_debugger :
|
|
322
|
+
return True
|
|
323
|
+
else :
|
|
324
|
+
return False
|
|
325
|
+
|
|
326
|
+
def set_level(self, level : str):
|
|
327
|
+
if 'info' in level.lower() : lvl = logging.INFO
|
|
328
|
+
elif 'warn' in level.lower() : lvl = logging.WARNING
|
|
329
|
+
elif 'warning' in level.lower() : lvl = logging.WARNING
|
|
330
|
+
elif 'critical' in level.lower() : lvl = logging.CRITICAL
|
|
331
|
+
elif 'debug' in level.lower() : lvl = logging.DEBUG
|
|
332
|
+
elif 'error' in level.lower() : lvl = logging.ERROR
|
|
333
|
+
elif 'screen' in level.lower() : lvl = logging.SCREEN
|
|
334
|
+
else : raise ValueError('Unknown level, not one of [info,warn,warning,critical,debug,error,screen]')
|
|
335
|
+
self.currentDebugLevel = level
|
|
336
|
+
self.logger.setLevel(lvl)
|
|
337
|
+
|
|
338
|
+
def get_current_debug_level(self) :
|
|
339
|
+
return self.currentDebugLevel
|
|
340
|
+
|
|
341
|
+
def get_logger(self) :
|
|
342
|
+
return self.logger
|
|
343
|
+
|
|
344
|
+
def before_log(self , message , level) :
|
|
345
|
+
|
|
346
|
+
def __call_thread__() :
|
|
347
|
+
if not level in self.get_current_levels() :
|
|
348
|
+
return
|
|
349
|
+
if self.isStreamServiceAvailable() :
|
|
350
|
+
d = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
351
|
+
streamUrl = self.getStreamServiceUrlPath()
|
|
352
|
+
self.stream_service.emit( streamUrl , {
|
|
353
|
+
'message' : message ,
|
|
354
|
+
'level' : level ,
|
|
355
|
+
'msg' : message,
|
|
356
|
+
'date' : d ,
|
|
357
|
+
'id' : self.id,
|
|
358
|
+
'formate' : 'json' ,
|
|
359
|
+
'source' : self.name ,
|
|
360
|
+
'getTimestamp' : getTimestamp()
|
|
361
|
+
})
|
|
362
|
+
try :
|
|
363
|
+
t= Thread(target=__call_thread__)
|
|
364
|
+
# t.daemon=True
|
|
365
|
+
t.start()
|
|
366
|
+
except :
|
|
367
|
+
__call_thread__()
|
|
368
|
+
|
|
369
|
+
params = {
|
|
370
|
+
'screen' : True ,
|
|
371
|
+
'file': True
|
|
372
|
+
}
|
|
373
|
+
if self.onScreen and self.env['debugger_on_screen'] == True :
|
|
374
|
+
params['screen'] = True
|
|
375
|
+
else :
|
|
376
|
+
params['screen'] = False
|
|
377
|
+
return params
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def info(self, message , external_debugger=None,source=None):
|
|
381
|
+
def __call__(message) :
|
|
382
|
+
if source :
|
|
383
|
+
message = f'[{source}]-{message}'
|
|
384
|
+
self.before_log(message , 'info')
|
|
385
|
+
self.logger.info(message)
|
|
386
|
+
if self.isGlobalDebuggerDefined() :
|
|
387
|
+
self.global_debugger.info(message)
|
|
388
|
+
if external_debugger :
|
|
389
|
+
external_debugger.info(message)
|
|
390
|
+
try :
|
|
391
|
+
r=Thread(target=__call__,args=[message])
|
|
392
|
+
r.daemon=True
|
|
393
|
+
r.start()
|
|
394
|
+
r.join()
|
|
395
|
+
except :
|
|
396
|
+
__call__(message)
|
|
397
|
+
|
|
398
|
+
def debug(self, message , external_debugger=None,source=None):
|
|
399
|
+
def __call__(message) :
|
|
400
|
+
if source :
|
|
401
|
+
message = f'[{source}]-{message}'
|
|
402
|
+
self.before_log(message , 'debug')
|
|
403
|
+
self.logger.debug(message)
|
|
404
|
+
if self.isGlobalDebuggerDefined() :
|
|
405
|
+
self.global_debugger.debug(message)
|
|
406
|
+
if external_debugger :
|
|
407
|
+
external_debugger.debug(message)
|
|
408
|
+
try :
|
|
409
|
+
r=Thread(target=__call__,args=[message])
|
|
410
|
+
r.daemon=True
|
|
411
|
+
r.start()
|
|
412
|
+
r.join()
|
|
413
|
+
except :
|
|
414
|
+
__call__(message)
|
|
415
|
+
|
|
416
|
+
def warning(self, message , external_debugger=None,source=None):
|
|
417
|
+
def __call__(message) :
|
|
418
|
+
if source :
|
|
419
|
+
message = f'[{source}]-{message}'
|
|
420
|
+
self.before_log(message , 'warning')
|
|
421
|
+
self.logger.warning(message)
|
|
422
|
+
if self.isGlobalDebuggerDefined() :
|
|
423
|
+
self.global_debugger.warning(message)
|
|
424
|
+
if external_debugger :
|
|
425
|
+
external_debugger.warning(message)
|
|
426
|
+
try :
|
|
427
|
+
r=Thread(target=__call__,args=[message])
|
|
428
|
+
r.daemon=True
|
|
429
|
+
r.start()
|
|
430
|
+
r.join()
|
|
431
|
+
except :
|
|
432
|
+
__call__(message)
|
|
433
|
+
|
|
434
|
+
def error(self, message,external_debugger=None,source=None):
|
|
435
|
+
def __call__(message) :
|
|
436
|
+
if source :
|
|
437
|
+
message = f'[{source}]-{message}'
|
|
438
|
+
self.before_log(message , 'error')
|
|
439
|
+
self.logger.error(message)
|
|
440
|
+
if self.isGlobalDebuggerDefined() :
|
|
441
|
+
self.global_debugger.error(message)
|
|
442
|
+
if external_debugger :
|
|
443
|
+
external_debugger.error(message)
|
|
444
|
+
try :
|
|
445
|
+
r=Thread(target=__call__,args=[message])
|
|
446
|
+
r.daemon=True
|
|
447
|
+
r.start()
|
|
448
|
+
r.join()
|
|
449
|
+
except :
|
|
450
|
+
__call__(message)
|
|
451
|
+
|
|
452
|
+
def critical(self, message,external_debugger=None,source=None):
|
|
453
|
+
def __call__() :
|
|
454
|
+
if source :
|
|
455
|
+
message = f'[{source}]-{message}'
|
|
456
|
+
self.before_log(message , 'critical')
|
|
457
|
+
self.logger.critical(message)
|
|
458
|
+
if self.isGlobalDebuggerDefined() :
|
|
459
|
+
self.global_debugger.critical(message)
|
|
460
|
+
if external_debugger :
|
|
461
|
+
external_debugger.critical(message)
|
|
462
|
+
try :
|
|
463
|
+
r=Thread(target=__call__,args=[message])
|
|
464
|
+
r.daemon=True
|
|
465
|
+
r.start()
|
|
466
|
+
r.join()
|
|
467
|
+
except :
|
|
468
|
+
__call__(message)
|
|
469
|
+
|
|
470
|
+
def screen(self, message,external_debugger=None,source=None):
|
|
471
|
+
def __call__() :
|
|
472
|
+
if source :
|
|
473
|
+
message = f'[{source}]-{message}'
|
|
474
|
+
self.before_log(message , 'critical')
|
|
475
|
+
print(f"{self.syntax}")
|
|
476
|
+
if self.isGlobalDebuggerDefined() :
|
|
477
|
+
self.global_debugger.critical(message)
|
|
478
|
+
if external_debugger :
|
|
479
|
+
external_debugger.critical(message)
|
|
480
|
+
try :
|
|
481
|
+
r=Thread(target=__call__,args=[message])
|
|
482
|
+
r.daemon=True
|
|
483
|
+
r.start()
|
|
484
|
+
r.join()
|
|
485
|
+
except :
|
|
486
|
+
__call__(message)
|
easy_utils_dev/debugger.py
CHANGED
|
@@ -128,6 +128,15 @@ class DEBUGGER:
|
|
|
128
128
|
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
129
129
|
self.console.setFormatter(self.formatter)
|
|
130
130
|
|
|
131
|
+
def custom_log_syntax(self , syntax) :
|
|
132
|
+
'''
|
|
133
|
+
f"[%(asctime)s]-[{self.name}]-[%(levelname)s]: %(message)s"
|
|
134
|
+
'''
|
|
135
|
+
f = syntax
|
|
136
|
+
self.syntax = f
|
|
137
|
+
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
138
|
+
self.console.setFormatter(self.formatter)
|
|
139
|
+
|
|
131
140
|
def updateGlobalHomePath(self ) :
|
|
132
141
|
if not self.isLogWriteDisabled :
|
|
133
142
|
getFromEnv = self.env.get('debugger_homepath' , None )
|
easy_utils_dev/temp_memory.py
CHANGED
|
@@ -17,21 +17,28 @@ class TemporaryMemory :
|
|
|
17
17
|
sleep(5)
|
|
18
18
|
now = getTimestamp()
|
|
19
19
|
for key, value in list(self.store.items()) :
|
|
20
|
-
if
|
|
21
|
-
if value.get('
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
if value.get('removeTimestamp') :
|
|
21
|
+
if now >= value.get('removeTimestamp' , 0) :
|
|
22
|
+
if value.get('store_deleted_key' , False) :
|
|
23
|
+
self.deletions.append(key)
|
|
24
|
+
self.delete(key)
|
|
24
25
|
|
|
25
26
|
def delete(self , key ) :
|
|
26
|
-
|
|
27
|
+
try :
|
|
28
|
+
del self.store[key]
|
|
29
|
+
except :
|
|
30
|
+
pass
|
|
27
31
|
gc.collect()
|
|
28
32
|
|
|
29
|
-
def get(self , key ) :
|
|
30
|
-
return self.store.get(key , {}).get('item')
|
|
33
|
+
def get(self , key , default=None ) :
|
|
34
|
+
return self.store.get(key , {}).get('item' , default)
|
|
31
35
|
|
|
32
36
|
def save(self, item , custom_key=None ,auto_destroy_period=60 , store_deleted_key=True) :
|
|
33
37
|
now = getTimestamp()
|
|
34
|
-
|
|
38
|
+
if auto_destroy_period :
|
|
39
|
+
later = getTimestamp(after_seconds=auto_destroy_period)
|
|
40
|
+
else :
|
|
41
|
+
later = None
|
|
35
42
|
if not custom_key :
|
|
36
43
|
custom_key = f"{getTimestamp()}-{generateToken(iter=4)}".upper()
|
|
37
44
|
self.store[custom_key] = {
|
easy_utils_dev/wsnoclib.py
CHANGED
|
@@ -35,6 +35,7 @@ class KafkaConfig :
|
|
|
35
35
|
self.kafka_subscription_deleted = False
|
|
36
36
|
self.base_url = None
|
|
37
37
|
self.kafka_thread=None
|
|
38
|
+
self.enable_auto_refresh = False
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
|
|
@@ -69,7 +70,8 @@ class WSNOCLIB :
|
|
|
69
70
|
self.onGoingRequests=0
|
|
70
71
|
self.fastQueue = FastQueue(request_max_count)
|
|
71
72
|
self.queue = []
|
|
72
|
-
self.
|
|
73
|
+
self.token = {}
|
|
74
|
+
self.tokenRefreshPeriod = None
|
|
73
75
|
self.final_results = []
|
|
74
76
|
self.killed=False
|
|
75
77
|
self.nes=[]
|
|
@@ -78,6 +80,7 @@ class WSNOCLIB :
|
|
|
78
80
|
self.refresh_inprogress = False
|
|
79
81
|
self.kafka = kafka
|
|
80
82
|
self.refresh_thread = None
|
|
83
|
+
self.token_refresh_count = 0
|
|
81
84
|
self.session = WSNOCSession(self)
|
|
82
85
|
if register_atexit :
|
|
83
86
|
atexit.register(self.goodbye)
|
|
@@ -124,33 +127,23 @@ class WSNOCLIB :
|
|
|
124
127
|
return
|
|
125
128
|
if not pingAddress(self.address) :
|
|
126
129
|
raise Exception(f'Address {self.address} is not pingable.')
|
|
127
|
-
self.logger.info(f'Connecting to {self.address} using username: {self.username}
|
|
130
|
+
# self.logger.info(f'Connecting to {self.address} using username: {self.username}')
|
|
128
131
|
self.logger.debug(f'Connecting to {self.address} using username: {self.username}')
|
|
129
132
|
URL = f"https://{self.address}/rest-gateway/rest/api/v1/auth/token"
|
|
130
|
-
self.logger.debug(f'Login URL is {URL}')
|
|
131
133
|
headers = {
|
|
132
134
|
"Content-Type": "application/json"
|
|
133
135
|
}
|
|
134
136
|
data = {
|
|
135
137
|
"grant_type": "client_credentials"
|
|
136
138
|
}
|
|
137
|
-
r =
|
|
138
|
-
|
|
139
|
-
response_header={r.headers}
|
|
140
|
-
response_encoding={r.encoding}
|
|
141
|
-
response_reason={r.reason}
|
|
142
|
-
body={r.request.body}
|
|
143
|
-
headers={r.request.headers}
|
|
144
|
-
URL={URL}
|
|
145
|
-
content={r.text}
|
|
146
|
-
""")
|
|
147
|
-
self.logger.info(f'Request return status code : {r.status_code}')
|
|
148
|
-
self.logger.debug(f"Login Request response body is {r.text}")
|
|
149
|
-
if r.status_code != 200 :
|
|
139
|
+
r = self.session.post(url = URL , headers=headers , auth=BAuth(self.username, self.password), json=data , retries=5)
|
|
140
|
+
if not r.ok :
|
|
150
141
|
self.logger.debug(f'fail message {r.text}')
|
|
151
142
|
raise Exception(f'Failed to authenticate WSNOC. Return status code : {r.status_code}')
|
|
152
143
|
self.access_token = r.json()["access_token"]
|
|
153
144
|
self.refresh_token = r.json()["refresh_token"]
|
|
145
|
+
if not self.tokenRefreshPeriod :
|
|
146
|
+
self.tokenRefreshPeriod = int(r.json()["expires_in"]) - 100
|
|
154
147
|
self.bearer_token = f'Bearer {self.access_token}'
|
|
155
148
|
self.token = r.json()
|
|
156
149
|
self.token.update({'bearer_token' : self.bearer_token })
|
|
@@ -202,12 +195,14 @@ class WSNOCLIB :
|
|
|
202
195
|
sleep(self.tokenRefreshPeriod)
|
|
203
196
|
self.logger.info(f"Waiting period completed. Starting Revoking/Login process ...")
|
|
204
197
|
self.refresh_inprogress = True
|
|
205
|
-
self.
|
|
206
|
-
sleep(30)
|
|
207
|
-
self.logger.info(f"Logout process completed. Starting Reconnecting ...")
|
|
208
|
-
self.connect(self.auto_refresh_token)
|
|
198
|
+
self.renew_by_refresh_token()
|
|
209
199
|
self.refresh_inprogress = False
|
|
210
|
-
self.
|
|
200
|
+
self.kafka.refresh_inprogress = True
|
|
201
|
+
if self.kafka.enable_auto_refresh :
|
|
202
|
+
self.renewSubscription()
|
|
203
|
+
self.kafka.refresh_inprogress = False
|
|
204
|
+
self.token_refresh_count += 1
|
|
205
|
+
self.runAutoRefreshThread()
|
|
211
206
|
|
|
212
207
|
def kafka_connect( self ,
|
|
213
208
|
user ,
|
|
@@ -253,7 +248,6 @@ class WSNOCLIB :
|
|
|
253
248
|
self.logger.debug(f"nsp_address: {nsp_address}")
|
|
254
249
|
self.logger.debug(f"NewRelease: {new_release}")
|
|
255
250
|
self.kafka.kafka_subscription_deleted= False
|
|
256
|
-
|
|
257
251
|
if not self.external_nsp :
|
|
258
252
|
if new_release :
|
|
259
253
|
self.kafka.kafka_nsp_os_name = 'nspos-kafka'
|
|
@@ -265,8 +259,6 @@ class WSNOCLIB :
|
|
|
265
259
|
self.kafka.kafka_address = nsp_address
|
|
266
260
|
self.kafka.kafka_port = 9192
|
|
267
261
|
self.kafka.kafka_nsp_os_name = 'nspos-tomcat'
|
|
268
|
-
|
|
269
|
-
self.logger.info('requesting kafka subscription ...')
|
|
270
262
|
if self.loggedOut or self.killed:
|
|
271
263
|
self.logger.error(f"WSNOC API Authentication process loggedout or killed. exit")
|
|
272
264
|
raise Exception('WSNOC API Authentication process loggedout or killed. exit')
|
|
@@ -283,21 +275,38 @@ class WSNOCLIB :
|
|
|
283
275
|
self.nsp_key = f'{self.temp_dir}/nsp.key'
|
|
284
276
|
self.nsp_cert = f'{self.temp_dir}/nsp.pem'
|
|
285
277
|
if not self.external_nsp :
|
|
278
|
+
####################
|
|
279
|
+
####################
|
|
280
|
+
#
|
|
281
|
+
# IN CASE OF INTERNAL NSP
|
|
282
|
+
#
|
|
283
|
+
####################
|
|
284
|
+
####################
|
|
285
|
+
checkContainer = self.ssh.ssh_execute(f"docker ps | grep -i 'nspos-kafka' | wc -l")
|
|
286
|
+
if checkContainer != '0' :
|
|
287
|
+
self.kafka.kafka_nsp_os_name = 'nspos-kafka'
|
|
288
|
+
self.kafka.kafka_port = None
|
|
286
289
|
self.logger.debug(f"Working on internal NSP to copy the files ...")
|
|
287
290
|
self.ssh.ssh_execute(f"docker cp {self.kafka.kafka_nsp_os_name}:/opt/nsp/os/ssl/certs/nsp/nsp.pem /tmp/nsp.pem")
|
|
288
291
|
self.ssh.ssh_execute(f"docker cp {self.kafka.kafka_nsp_os_name}:/opt/nsp/os/ssl/nsp.key /tmp/nsp.key")
|
|
289
292
|
sftp.get('/tmp/nsp.pem' , f'{self.temp_dir}/nsp.pem')
|
|
290
293
|
sftp.get('/tmp/nsp.key' , f'{self.temp_dir}/nsp.key')
|
|
291
294
|
self.kafka.ca_cert = f'{self.temp_dir}/nsp.pem'
|
|
292
|
-
|
|
293
|
-
port = self.kafka.kafka_api_port
|
|
295
|
+
self.kafka.base_url = f'https://{self.address}'
|
|
294
296
|
else :
|
|
297
|
+
####################
|
|
298
|
+
####################
|
|
299
|
+
#
|
|
300
|
+
# IN CASE OF EXTERNAL NSP
|
|
301
|
+
#
|
|
302
|
+
####################
|
|
303
|
+
####################
|
|
295
304
|
self.logger.debug(f"Working on external NSP to copy the files ...")
|
|
296
305
|
CertLoc = f"""find /var/lib/kubelet/pods/ -type d -path "*/volumes/kubernetes.io~empty-dir/shared-tls-volume" | head -n1"""
|
|
297
306
|
CertLoc = self.ssh.ssh_execute(CertLoc).replace('\n','')
|
|
298
307
|
self.logger.debug(f"CertLoc Host: {CertLoc}")
|
|
299
|
-
|
|
300
|
-
|
|
308
|
+
self.kafka.base_url = f'https://{nsp_address}'
|
|
309
|
+
self.kafka.kafka_port = None
|
|
301
310
|
if len(CertLoc) > 15 :
|
|
302
311
|
self.logger.debug(f"Copying cert files from nsp host machine ....")
|
|
303
312
|
copies = [
|
|
@@ -334,7 +343,6 @@ class WSNOCLIB :
|
|
|
334
343
|
self.logger.debug(f'affectedObjectType Filter : filter updated with "{filter}"')
|
|
335
344
|
if custom_filter_expression :
|
|
336
345
|
filter += f" {custom_filter_expression}"
|
|
337
|
-
URL = '/nbi-notification/api/v1/notifications/subscriptions'
|
|
338
346
|
kafkaForm = {
|
|
339
347
|
"categories": [
|
|
340
348
|
{
|
|
@@ -344,19 +352,18 @@ class WSNOCLIB :
|
|
|
344
352
|
]
|
|
345
353
|
}
|
|
346
354
|
self.logger.debug(f"Kafka Filter Form : {kafkaForm}")
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
if response :
|
|
355
|
+
if self.kafka.kafka_port is not None :
|
|
356
|
+
URL = f"{self.kafka.base_url}:{self.kafka.kafka_port}/nbi-notification/api/v1/notifications/subscriptions"
|
|
357
|
+
else :
|
|
358
|
+
URL = f"{self.kafka.base_url}/nbi-notification/api/v1/notifications/subscriptions"
|
|
359
|
+
response = self.session.post(URL , json=kafkaForm , retries=3)
|
|
360
|
+
if response.ok :
|
|
361
|
+
response = response.json()
|
|
355
362
|
self.kafka.subscriptionId = response['response']['data']['subscriptionId']
|
|
356
363
|
self.kafka.response = response
|
|
357
364
|
self.kafka.topicId = response['response']['data']['topicId']
|
|
358
365
|
if auto_refresh :
|
|
359
|
-
self.kafka.
|
|
366
|
+
self.kafka.enable_auto_refresh = True
|
|
360
367
|
self.killed=False
|
|
361
368
|
else :
|
|
362
369
|
self.logger.error(f"Failed to create kafka subscription.")
|
|
@@ -365,81 +372,84 @@ class WSNOCLIB :
|
|
|
365
372
|
return self.kafka
|
|
366
373
|
|
|
367
374
|
def change_kafka_refresh_period(self , period : int =3000) :
|
|
368
|
-
|
|
375
|
+
print('Deprecated function change_kafka_refresh_period. Kafka refresh period is now managed by WSNOC API SLEEP PERIOD')
|
|
369
376
|
|
|
370
377
|
def renewSubscription(self) :
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
378
|
+
self.logger.info('Renewing subscription ...')
|
|
379
|
+
if self.kafka.kafka_port is not None :
|
|
380
|
+
URL = f"{self.kafka.base_url}:{self.kafka.kafka_port}/nbi-notification/api/v1/notifications/subscriptions/{self.kafka.subscriptionId}/renewals"
|
|
381
|
+
else :
|
|
382
|
+
URL = f"{self.kafka.base_url}/nbi-notification/api/v1/notifications/subscriptions/{self.kafka.subscriptionId}/renewals"
|
|
383
|
+
response = self.session.post(URL , retries=3)
|
|
384
|
+
if not response.ok :
|
|
385
|
+
self.logger.error(f'failed to renew subscription. {response.text}')
|
|
386
|
+
|
|
387
|
+
# def renewSubscription(self) :
|
|
388
|
+
# while True :
|
|
389
|
+
# try :
|
|
390
|
+
# sleep(self.kafka.kafka_refresh_period)
|
|
391
|
+
# if self.loggedOut or self.killed:
|
|
392
|
+
# break
|
|
393
|
+
# self.logger.info('Renewing subscription ...')
|
|
394
|
+
# self.kafka.refresh_inprogress = True
|
|
395
|
+
# URL = f"{self.kafka.base_url}:{self.kafka.kafka_port}/nbi-notification/api/v1/notifications/subscriptions/{self.kafka.subscriptionId}/renewals"
|
|
396
|
+
# response = self.session.post(URL , retries=3)
|
|
397
|
+
# self.logger.debug(f'Renewing subscription Response: [{response.text}]')
|
|
398
|
+
# except Exception as error :
|
|
399
|
+
# self.logger.error(f'failed to renew subscription. {error}')
|
|
400
|
+
# self.logger.debug(traceback.format_exc())
|
|
401
|
+
# self.kafka.refresh_inprogress = False
|
|
402
|
+
|
|
403
|
+
# def deleteKafkaSubscription(self , subscriptionId=None) :
|
|
404
|
+
# self.logger.info(f'Deleting subscription subscriptionId:{subscriptionId}')
|
|
405
|
+
# if not subscriptionId :
|
|
406
|
+
# self.logger.info(f'Deleting subscription subscriptionId:{self.kafka.subscriptionId}')
|
|
407
|
+
# subscriptionId=self.kafka.subscriptionId
|
|
408
|
+
# self.kafka.kafka_subscription_deleted= True
|
|
409
|
+
# URL = f"{self.kafka.base_url}:{self.kafka.kafka_port}/nbi-notification/api/v1/notifications/subscriptions/{subscriptionId}"
|
|
410
|
+
# response = self.session.delete(URL , retries=3)
|
|
411
|
+
# return response
|
|
405
412
|
|
|
406
|
-
def handle_beautify_alarm(self , alarm ) :
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
def kafka_listen(self) :
|
|
413
|
+
# def handle_beautify_alarm(self , alarm ) :
|
|
414
|
+
# oalarm = alarm
|
|
415
|
+
# alarm = alarm['data']['ietf-restconf:notification']
|
|
416
|
+
# if 'create' in str(list(alarm.keys())) :
|
|
417
|
+
# alarmData = alarm['nsp-fault:alarm-create']
|
|
418
|
+
# oalarm['dataEnh'] = {
|
|
419
|
+
# 'newAlarm' : True,
|
|
420
|
+
# 'alarmChange' : False,
|
|
421
|
+
# 'alarmId' : int(alarmData['objectId'].split(':')[-1]),
|
|
422
|
+
# 'neId' : alarmData['neId'],
|
|
423
|
+
# 'neName ' : alarmData['neName'],
|
|
424
|
+
# 'alarmName' : alarmData['alarmName'],
|
|
425
|
+
# 'cleared' : False,
|
|
426
|
+
# 'aknowledged' : False,
|
|
427
|
+
# **alarmData ,
|
|
428
|
+
# }
|
|
429
|
+
# elif 'change' in str(list(alarm.keys())) :
|
|
430
|
+
# alarmData = alarm['nsp-fault:alarm-change']
|
|
431
|
+
# cleared = False
|
|
432
|
+
# aknowledged = False
|
|
433
|
+
# if 'severity' in list(alarmData.keys()) :
|
|
434
|
+
# if alarmData['severity']['new-value'] == 'cleared' :
|
|
435
|
+
# cleared = True
|
|
436
|
+
# if 'acknowledged' in list(alarmData.keys()) :
|
|
437
|
+
# aknowledged = alarmData['acknowledged']['new-value']
|
|
438
|
+
# oalarm['dataEnh'] = {
|
|
439
|
+
# 'newAlarm' : False,
|
|
440
|
+
# 'alarmChange' : True,
|
|
441
|
+
# 'alarmId' : int(alarmData['objectId'].split(':')[-1]),
|
|
442
|
+
# 'cleared' : cleared,
|
|
443
|
+
# 'aknowledged' : aknowledged,
|
|
444
|
+
# **alarmData ,
|
|
445
|
+
# }
|
|
446
|
+
# return oalarm
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
def kafka_listen(self) :
|
|
450
|
+
def hold_if_kafka_refresh_inprogress() :
|
|
451
|
+
while self.kafka.refresh_inprogress :
|
|
452
|
+
sleep(.1)
|
|
443
453
|
self.logger.info('Listening to Kafka Notifications ...')
|
|
444
454
|
if not self.kafka.topicId :
|
|
445
455
|
self.logger.error(f'kafka is not established. exit.')
|
|
@@ -464,9 +474,7 @@ class WSNOCLIB :
|
|
|
464
474
|
)
|
|
465
475
|
try:
|
|
466
476
|
while True:
|
|
467
|
-
|
|
468
|
-
self.logger.info(f"Waiting for kafka subscription to be ready. In refresh process...")
|
|
469
|
-
sleep(1)
|
|
477
|
+
hold_if_kafka_refresh_inprogress()
|
|
470
478
|
if self.kafka.kafka_subscription_deleted :
|
|
471
479
|
self.logger.info(f"Kafka subscription is deleted. exit.")
|
|
472
480
|
break
|
|
@@ -583,6 +591,27 @@ class WSNOCLIB :
|
|
|
583
591
|
return r.json()
|
|
584
592
|
return r
|
|
585
593
|
|
|
594
|
+
def renew_by_refresh_token(self) :
|
|
595
|
+
URL = f"https://{self.address}/rest-gateway/rest/api/v1/auth/token"
|
|
596
|
+
headers = {
|
|
597
|
+
"Content-Type": "application/json"
|
|
598
|
+
}
|
|
599
|
+
data = {
|
|
600
|
+
"grant_type": "refresh_token",
|
|
601
|
+
"refresh_token": f"{self.refresh_token}"
|
|
602
|
+
|
|
603
|
+
}
|
|
604
|
+
r = self.session.post(URL , headers=headers , json=data , auth=BAuth(self.username, self.password) , skip_hold_for_token_refresh=True)
|
|
605
|
+
if r.ok :
|
|
606
|
+
if not self.tokenRefreshPeriod :
|
|
607
|
+
self.tokenRefreshPeriod = int(r.json()["expires_in"]) - 100
|
|
608
|
+
self.access_token = r.json()["access_token"]
|
|
609
|
+
self.refresh_token = r.json()["refresh_token"]
|
|
610
|
+
self.bearer_token = f'Bearer {self.access_token}'
|
|
611
|
+
self.token = r.json()
|
|
612
|
+
self.token.update({'bearer_token' : self.bearer_token })
|
|
613
|
+
return r
|
|
614
|
+
|
|
586
615
|
def session_info(self) :
|
|
587
616
|
self.logger.debug('Getting Version ...')
|
|
588
617
|
response = self.get( url='/oms1350/data/common/sessionInfo')
|
|
@@ -676,33 +705,48 @@ class WSNOCSession(requests.Session):
|
|
|
676
705
|
self.headers.update({"Content-Type": "application/json"}) # base defaults
|
|
677
706
|
self._wsnoc = wsnoc
|
|
678
707
|
self.verify = False
|
|
708
|
+
self.retries = 0
|
|
709
|
+
self.debug_this_request = False
|
|
710
|
+
self.skip_hold_for_token_refresh = False
|
|
679
711
|
|
|
680
712
|
def rebuild_auth(self, prepared_request, response):
|
|
681
713
|
return
|
|
682
714
|
|
|
683
|
-
def hold_for_token_refresh(self) :
|
|
715
|
+
def hold_for_token_refresh(self, url=None) :
|
|
684
716
|
while self._wsnoc.refresh_inprogress :
|
|
685
|
-
|
|
717
|
+
self._wsnoc.logger.info(f'Waiting for token refresh. {url if url else "No URL"}')
|
|
718
|
+
sleep(.5)
|
|
686
719
|
|
|
687
|
-
def request(self, method, url , retries=0 , **kwargs):
|
|
720
|
+
def request(self, method, url , retries=0 , skip_hold_for_token_refresh=False , debug_this_request=False , **kwargs):
|
|
688
721
|
self._wsnoc.logger.debug(f'[{method}] : {url}')
|
|
689
|
-
|
|
722
|
+
if not skip_hold_for_token_refresh :
|
|
723
|
+
self.hold_for_token_refresh(url)
|
|
690
724
|
self._wsnoc.api_count += 1
|
|
691
725
|
token = self._wsnoc.getLatestToken().get('bearer_token')
|
|
692
726
|
request_headers = kwargs.get('headers' , {})
|
|
693
|
-
if
|
|
694
|
-
request_headers
|
|
727
|
+
if token :
|
|
728
|
+
if not request_headers.get('Authorization') :
|
|
729
|
+
request_headers['Authorization'] = token
|
|
695
730
|
kwargs['headers'] = request_headers
|
|
696
731
|
request = super().request(method, url, **kwargs )
|
|
732
|
+
if debug_this_request :
|
|
733
|
+
self._wsnoc.logger.info(f'''
|
|
734
|
+
[DEBUG] [{method}] : {url}
|
|
735
|
+
[DEBUG] Headers: {request_headers}
|
|
736
|
+
[DEBUG] Body: {kwargs.get('data' , {})}
|
|
737
|
+
[DEBUG] Response: {request.text}
|
|
738
|
+
[DEBUG] OK: {request.ok}
|
|
739
|
+
[DEBUG] Method: {request.request.method}
|
|
740
|
+
''')
|
|
697
741
|
for i in range(retries) :
|
|
698
742
|
if request.ok :
|
|
699
743
|
break
|
|
700
744
|
if not request.ok :
|
|
701
745
|
sleep(1)
|
|
702
|
-
self.hold_for_token_refresh()
|
|
746
|
+
self.hold_for_token_refresh(url)
|
|
703
747
|
request = super().request(method, url, **kwargs )
|
|
704
748
|
self._wsnoc.logger.debug(f'[Try-{i}] [{method}] : {url}- {request.status_code}')
|
|
705
|
-
self._wsnoc.logger.info(f'[{method}] : {url}- {request.status_code}')
|
|
749
|
+
self._wsnoc.logger.info(f'[{method}] : {url} - [{request.status_code}]')
|
|
706
750
|
return request
|
|
707
751
|
|
|
708
752
|
|
|
@@ -1,21 +1,23 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
2
|
-
Name:
|
|
3
|
-
Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: easy_utils_dev
|
|
3
|
+
Version: 2.140
|
|
4
4
|
Keywords: python3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Requires-Dist: psutil
|
|
7
7
|
Requires-Dist: ping3
|
|
8
8
|
Requires-Dist: flask
|
|
9
|
-
Requires-Dist:
|
|
9
|
+
Requires-Dist: flask_cors
|
|
10
10
|
Requires-Dist: xmltodict
|
|
11
11
|
Requires-Dist: paramiko
|
|
12
12
|
Requires-Dist: oracledb
|
|
13
13
|
Requires-Dist: requests
|
|
14
|
-
Requires-Dist:
|
|
14
|
+
Requires-Dist: flask_socketio
|
|
15
15
|
Requires-Dist: python-dotenv
|
|
16
16
|
Requires-Dist: gevent
|
|
17
17
|
Requires-Dist: pyzipper
|
|
18
18
|
Requires-Dist: pyjwt
|
|
19
19
|
Requires-Dist: authlib
|
|
20
20
|
Requires-Dist: kafka-python
|
|
21
|
-
|
|
21
|
+
Dynamic: classifier
|
|
22
|
+
Dynamic: keywords
|
|
23
|
+
Dynamic: requires-dist
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
easy_utils_dev/EasySsh.py,sha256=
|
|
1
|
+
easy_utils_dev/EasySsh.py,sha256=9pQaHHQGng8X3fsy4Vvto5RIEObm-iOt52VLiO6m1g0,3591
|
|
2
2
|
easy_utils_dev/Events.py,sha256=MdI53gAyXX_2jmChpayayQM0ZitgjtkyUNrQYGEEZnw,2978
|
|
3
3
|
easy_utils_dev/FastQueue.py,sha256=Drt8B_hEdmg9eAt7OWSgTyoJ3rUHkeJHk9xdaehtEsY,5622
|
|
4
4
|
easy_utils_dev/NameObject.py,sha256=Z4Qp3qfMcQeMPw35PV_xOu8kigRtfSRZ4h7woR0t3Gg,270
|
|
@@ -8,7 +8,8 @@ easy_utils_dev/brevosmtp.py,sha256=A5n13MnVQnDuSjYQ91-MLftmqfg3VQ-36Zqw9OtoTB4,3
|
|
|
8
8
|
easy_utils_dev/check_license.py,sha256=C8vKXwaduoF3FSuDJ-J_j5jStNNyUdS-mOdLNfsCjmc,4825
|
|
9
9
|
easy_utils_dev/cplib.py,sha256=TPCFNQh4jYSGsm_CrMdivmD3G5B1rprco2O4B0BSnzo,19570
|
|
10
10
|
easy_utils_dev/custom_env.py,sha256=vxrjikpSNJlKfoBE-ef88UExlpXucUe-HcwHMn3gfB0,1510
|
|
11
|
-
easy_utils_dev/debugger.py,sha256=
|
|
11
|
+
easy_utils_dev/debugger-C-PF4PAMMP.py,sha256=5GmZU1l9R3CSZVIGff-l-gYaf-imJGSGTsh-cxNz6og,18637
|
|
12
|
+
easy_utils_dev/debugger.py,sha256=5GmZU1l9R3CSZVIGff-l-gYaf-imJGSGTsh-cxNz6og,18637
|
|
12
13
|
easy_utils_dev/easy_oracle.py,sha256=Jyc3HSl6eyLayjS8NoE4GOaf8otQlonR5_qOg2h1DjE,2157
|
|
13
14
|
easy_utils_dev/encryptor.py,sha256=f5Zjn0DGtXCyhldpVnBtfcTb4h4Wp0eQPHusEYwIags,1512
|
|
14
15
|
easy_utils_dev/ept.py,sha256=X-Z0_XCNfKK1TxQZquPMBqo3ZuxnK4TvWAYPnBUMlPI,25363
|
|
@@ -23,15 +24,15 @@ easy_utils_dev/openid_server.py,sha256=_odeg6omuizSUEJLtbAVn2PnG9vkcUAQ7rU3K5yXk
|
|
|
23
24
|
easy_utils_dev/optics_utils.py,sha256=G-hFX2iiUCSJjk7BICBRGvVoDq0IBONLZSjagoB5FMg,964
|
|
24
25
|
easy_utils_dev/require_auth.py,sha256=UsYAxfLX5wda6hd0nfLR_tl0bGQ4DYIpaTowsYSku-E,881
|
|
25
26
|
easy_utils_dev/simple_sqlite.py,sha256=J-mcTUnHmAn0eCPD8j-WEoA19uzHRXJ4YRJsyx9B-do,13113
|
|
26
|
-
easy_utils_dev/temp_memory.py,sha256=
|
|
27
|
+
easy_utils_dev/temp_memory.py,sha256=0Dx_vNUSFQRMtJZNT8tUZXubcG7T6jxevw2WYuGmVe8,1658
|
|
27
28
|
easy_utils_dev/uiserver.py,sha256=d9jImwgSURMH4MIU4Zkro2b20cAbuV8rO_If42FVyZ4,6826
|
|
28
29
|
easy_utils_dev/utils.py,sha256=BmVnbxc336c6WTeDFcEHN6Mavt7fJrIEyK4GXODV3gI,13345
|
|
29
30
|
easy_utils_dev/winserviceapi.py,sha256=2ZP6jaSt1-5vEJYXqwBhwX-1-eQ3V3YzntsoOoko2cw,18804
|
|
30
|
-
easy_utils_dev/wsnoclib.py,sha256=
|
|
31
|
+
easy_utils_dev/wsnoclib.py,sha256=kqkOkiafXnrIgdlV__3uyrAoqxG5dmIHnwqm0EkwS2U,33457
|
|
31
32
|
easy_utils_dev/wsselib.py,sha256=YweScnoAAH_t29EeIjBpkQ6HtX0Rp9mQudRsRce2SE8,7920
|
|
32
33
|
easy_utils_dev/ept_sql/create_dirs.sql,sha256=KWfX-Nc6lvr_BC-P6O97NE0idoPW4GNKUKUCgonJhto,3508
|
|
33
34
|
easy_utils_dev/ept_sql/create_ept_tables.sql,sha256=WDHyIyeReV8_QaYBPIpSy-lto3OKvZtex1tWs-FPURQ,67737
|
|
34
|
-
easy_utils_dev-2.
|
|
35
|
-
easy_utils_dev-2.
|
|
36
|
-
easy_utils_dev-2.
|
|
37
|
-
easy_utils_dev-2.
|
|
35
|
+
easy_utils_dev-2.140.dist-info/METADATA,sha256=11wRCPmmDl1s7jptVfwy-_ru_jnkTn2nJMcJ-dM07uM,572
|
|
36
|
+
easy_utils_dev-2.140.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
37
|
+
easy_utils_dev-2.140.dist-info/top_level.txt,sha256=7vBsrpq7NmilkdU3YUvfd5iVDNBaT07u_-ut4F7zc7A,15
|
|
38
|
+
easy_utils_dev-2.140.dist-info/RECORD,,
|
|
File without changes
|