easy-utils-dev 2.154__tar.gz → 2.156__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/PKG-INFO +1 -1
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/debugger.py +19 -14
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/ne1830PSS.py +16 -2
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/uiserver.py +118 -11
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/wsnoclib.py +7 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev.egg-info/PKG-INFO +1 -1
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/setup.py +1 -1
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/MANIFEST.in +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/EasySsh.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/Events.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/FastQueue.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/NameObject.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/__init__.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/abortable.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/brevosmtp.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/check_license.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/cplib.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/custom_env.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/debugger-C-PF4PAMMP.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/easy_oracle.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/encryptor.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/ept.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/ept_sql/create_dirs.sql +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/ept_sql/create_ept_tables.sql +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/exceptions.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/filescompressor.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/generate_license.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/keycloakapi.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/lralib.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/nsp_kafka.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/openid_server.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/optics_utils.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/require_auth.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/simple_sqlite.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/temp_memory.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/utils.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/winserviceapi.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev/wsselib.py +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev.egg-info/SOURCES.txt +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev.egg-info/dependency_links.txt +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev.egg-info/requires.txt +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/easy_utils_dev.egg-info/top_level.txt +0 -0
- {easy_utils_dev-2.154 → easy_utils_dev-2.156}/setup.cfg +0 -0
|
@@ -45,7 +45,8 @@ class DEBUGGER:
|
|
|
45
45
|
global_debugger=None,
|
|
46
46
|
disable_log_write=False,
|
|
47
47
|
file_name=None,
|
|
48
|
-
seperate_files=True
|
|
48
|
+
seperate_files=True,
|
|
49
|
+
trust_env_log_path=True
|
|
49
50
|
):
|
|
50
51
|
env = custom_env()
|
|
51
52
|
setupEnvironment( 'debugger' )
|
|
@@ -63,6 +64,7 @@ class DEBUGGER:
|
|
|
63
64
|
self.create_log_path(homePath, file_name)
|
|
64
65
|
self.fullSyntax=fullSyntax
|
|
65
66
|
self.onScreen= onscreen
|
|
67
|
+
self.trust_env_log_path = trust_env_log_path
|
|
66
68
|
self.id = id
|
|
67
69
|
self.stream_service = None
|
|
68
70
|
if not env['debugger'].get(name) :
|
|
@@ -118,19 +120,18 @@ class DEBUGGER:
|
|
|
118
120
|
start_thread(target=self.checks_in_bg)
|
|
119
121
|
|
|
120
122
|
def create_log_path(self , base_path , logname ) :
|
|
123
|
+
# print(f"Creating log path : {base_path} {logname}")
|
|
121
124
|
if not base_path :
|
|
122
|
-
base_path = os.
|
|
125
|
+
base_path = os.getcwd()
|
|
123
126
|
if not logname :
|
|
124
127
|
logname = self.name
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
# print(f"Log path With Filename : {self.log_path_with_filename}")
|
|
133
|
-
# print(f"Last Absolute Home Path : {self.lastAbsoluteHomePath}")
|
|
128
|
+
if base_path :
|
|
129
|
+
mkdirs(base_path)
|
|
130
|
+
self.baseHomePath = base_path
|
|
131
|
+
self.filename = logname
|
|
132
|
+
self.lastAbsoluteHomePath = base_path
|
|
133
|
+
self.log_path_with_filename = os.path.join(base_path, f'{logname}.log')
|
|
134
|
+
|
|
134
135
|
|
|
135
136
|
def fix_file_not_found_file_rotation(self) :
|
|
136
137
|
for i in range(self.BACKUP_COUNT) :
|
|
@@ -164,11 +165,13 @@ class DEBUGGER:
|
|
|
164
165
|
self.console.setFormatter(self.formatter)
|
|
165
166
|
|
|
166
167
|
def updateGlobalHomePath(self ) :
|
|
168
|
+
if not self.trust_env_log_path :
|
|
169
|
+
return
|
|
167
170
|
if not self.isLogWriteDisabled :
|
|
168
171
|
getFromEnv = self.env.get('debugger_homepath' , None )
|
|
169
172
|
# print(f"getFromEnv : {getFromEnv}")
|
|
170
|
-
self.create_log_path(getFromEnv, self.filename)
|
|
171
173
|
if getFromEnv :
|
|
174
|
+
self.create_log_path(getFromEnv, self.filename)
|
|
172
175
|
self.file_handler_class = self.createRotateFileHandler(self.log_path_with_filename)
|
|
173
176
|
|
|
174
177
|
def updateGlobalSetLevel( self ) :
|
|
@@ -272,7 +275,8 @@ class DEBUGGER:
|
|
|
272
275
|
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 ')
|
|
273
276
|
else :
|
|
274
277
|
self.set_level(EASY_UTILS_DEBUG_LEVEL)
|
|
275
|
-
self.
|
|
278
|
+
if self.trust_env_log_path :
|
|
279
|
+
self.updateGlobalHomePath()
|
|
276
280
|
if os.environ.get("EASY_UTILS_ENABLE_PRINT" , '' ).lower() == 'true' :
|
|
277
281
|
self.enable_print()
|
|
278
282
|
sleep(10)
|
|
@@ -313,12 +317,13 @@ class DEBUGGER:
|
|
|
313
317
|
def changeHomePath( self , path ) :
|
|
314
318
|
def delet_later(lastAbsoluteHomePath) :
|
|
315
319
|
if lastAbsoluteHomePath :
|
|
316
|
-
sleep(
|
|
320
|
+
sleep(1)
|
|
317
321
|
try :
|
|
318
322
|
shutil.rmtree(lastAbsoluteHomePath)
|
|
319
323
|
except :
|
|
320
324
|
pass
|
|
321
325
|
start_thread(target=delet_later, args=[self.lastAbsoluteHomePath])
|
|
326
|
+
sleep(.5)
|
|
322
327
|
self.create_log_path( path , self.filename)
|
|
323
328
|
self.file_handler_class = self.createRotateFileHandler(self.log_path_with_filename)
|
|
324
329
|
|
|
@@ -12,9 +12,23 @@ from easy_utils_dev import exceptions
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class PSS1830 :
|
|
15
|
-
def __init__(self ,
|
|
15
|
+
def __init__(self ,
|
|
16
|
+
sim=False ,
|
|
17
|
+
debug_name='Auto1830PSS' ,
|
|
18
|
+
auto_enable_tcp_forward=False,
|
|
19
|
+
file_name=None,
|
|
20
|
+
debug_home_path=None,
|
|
21
|
+
trust_env_log_path=True,
|
|
22
|
+
debugger_kwargs={}
|
|
23
|
+
) -> None:
|
|
16
24
|
self.port = None
|
|
17
|
-
self.
|
|
25
|
+
self.trust_env_log_path = trust_env_log_path
|
|
26
|
+
self.logger = DEBUGGER(
|
|
27
|
+
debug_name,file_name=file_name,
|
|
28
|
+
homePath=debug_home_path,
|
|
29
|
+
trust_env_log_path=trust_env_log_path,
|
|
30
|
+
**debugger_kwargs
|
|
31
|
+
)
|
|
18
32
|
self.connected = False
|
|
19
33
|
self.channel = None
|
|
20
34
|
self.nodeName = None
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import gc
|
|
2
|
+
import json
|
|
2
3
|
import time
|
|
4
|
+
from flask.ctx import F
|
|
3
5
|
from werkzeug.serving import ThreadedWSGIServer
|
|
4
|
-
from easy_utils_dev.utils import getRandomKey , generateToken , getTimestamp
|
|
6
|
+
from easy_utils_dev.utils import convertTimestampToDate, getRandomKey , generateToken , getTimestamp
|
|
5
7
|
from flask_socketio import SocketIO
|
|
6
8
|
from engineio.async_drivers import gevent
|
|
9
|
+
from engineio.async_drivers import threading as threading_engineio
|
|
7
10
|
from flask_cors import CORS
|
|
8
11
|
import logging , os
|
|
9
12
|
from flask import jsonify, request , current_app , copy_current_request_context
|
|
@@ -18,6 +21,9 @@ from werkzeug.serving import make_ssl_devcert
|
|
|
18
21
|
from time import sleep
|
|
19
22
|
from easy_utils_dev.utils import start_thread , getRandomKeysAndStr , mkdirs
|
|
20
23
|
from easy_utils_dev.temp_memory import TemporaryMemory
|
|
24
|
+
from easy_utils_dev.debugger import DEBUGGER
|
|
25
|
+
import signal
|
|
26
|
+
import sys
|
|
21
27
|
|
|
22
28
|
def getClassById( id ) :
|
|
23
29
|
return cenv[id]
|
|
@@ -92,6 +98,7 @@ class SocketClientObject :
|
|
|
92
98
|
|
|
93
99
|
class UISERVER :
|
|
94
100
|
def __init__(self ,
|
|
101
|
+
logger : DEBUGGER = None,
|
|
95
102
|
id=getRandomKey(n=15),
|
|
96
103
|
secretkey=generateToken(),
|
|
97
104
|
serve_with_secret_key=False,
|
|
@@ -121,6 +128,7 @@ class UISERVER :
|
|
|
121
128
|
self.bg_requests = {}
|
|
122
129
|
self.socketio_clients = []
|
|
123
130
|
self.abort_base_url = '/request/abort'
|
|
131
|
+
self.return_exception_as_code_400 = True
|
|
124
132
|
self.request_reply_base_url= '/request/result'
|
|
125
133
|
if https :
|
|
126
134
|
self.httpProtocol = 'https'
|
|
@@ -133,6 +141,10 @@ class UISERVER :
|
|
|
133
141
|
start_thread(target=self.delete_very_old_requests)
|
|
134
142
|
self.secret_key_execlude_urls = []
|
|
135
143
|
self.socketio_rooms = {}
|
|
144
|
+
self.log_url_requests = True
|
|
145
|
+
self.logger = logger
|
|
146
|
+
self.simulate_network_delay = False
|
|
147
|
+
|
|
136
148
|
|
|
137
149
|
def update_cert(self , crt, ssl ) :
|
|
138
150
|
self.ssl_crt=crt
|
|
@@ -158,6 +170,7 @@ class UISERVER :
|
|
|
158
170
|
|
|
159
171
|
def delete_very_old_requests(self) :
|
|
160
172
|
while True :
|
|
173
|
+
sleep(320)
|
|
161
174
|
now = getTimestamp()
|
|
162
175
|
for key, value in list(self.bg_requests.items()) :
|
|
163
176
|
value : AbortRequest = value
|
|
@@ -165,7 +178,6 @@ class UISERVER :
|
|
|
165
178
|
if value.delete_async_request_ts > now :
|
|
166
179
|
del self.bg_requests[key]
|
|
167
180
|
gc.collect()
|
|
168
|
-
sleep(320)
|
|
169
181
|
|
|
170
182
|
def create_room(self , room_id : str , members : list[str] ) :
|
|
171
183
|
self.socketio_rooms[room_id] = members
|
|
@@ -197,6 +209,14 @@ class UISERVER :
|
|
|
197
209
|
else :
|
|
198
210
|
return { 'status' : 404 , 'message' : 'Request not found or request is not abortable. Check request headers for abortable flag.'}
|
|
199
211
|
|
|
212
|
+
@self.app.route(f"/request/traceback/<key>" , methods=['GET'])
|
|
213
|
+
def get_traceback(key : str ) :
|
|
214
|
+
traceback = self.cache.get(key)
|
|
215
|
+
if traceback :
|
|
216
|
+
return { 'status' : 200 , 'traceback' : traceback.get('traceback') }
|
|
217
|
+
else :
|
|
218
|
+
return { 'status' : 404 , 'message' : 'Traceback not found or expired' }
|
|
219
|
+
|
|
200
220
|
@self.app.route(f'{self.request_reply_base_url}/<id>' , methods=['GET'])
|
|
201
221
|
def get_result_of_async_request(id : str ) :
|
|
202
222
|
request : AbortRequest = self.bg_requests.get(id)
|
|
@@ -217,6 +237,10 @@ class UISERVER :
|
|
|
217
237
|
|
|
218
238
|
@self.app.before_request
|
|
219
239
|
def before_request() :
|
|
240
|
+
if self.log_url_requests and self.logger :
|
|
241
|
+
self.logger.info(f'[{request.method}]: {request.url}' , source='WebServer')
|
|
242
|
+
|
|
243
|
+
|
|
220
244
|
if (self.serve_with_secret_key) and (request.path not in self.secret_key_execlude_urls) and (request.headers.get('secretkey') != self.secretkey):
|
|
221
245
|
return jsonify({"error": "Secret key is invalid"}), 401
|
|
222
246
|
|
|
@@ -257,26 +281,72 @@ class UISERVER :
|
|
|
257
281
|
if request.headers.get('async') == 'false' :
|
|
258
282
|
target_func = current_app.view_functions.get(request.endpoint)
|
|
259
283
|
if not target_func:
|
|
260
|
-
return
|
|
284
|
+
return {"error": "Route not found"}, 404
|
|
261
285
|
th = start_thread(target=run_async_job_results, args=[target_func , abort ])
|
|
262
286
|
abort.thread = th
|
|
263
287
|
self.bg_requests[requestId] = abort
|
|
264
288
|
return {"status": 200, "message": "Request now in running bg", "abort_id": abort.abort_id} , 200
|
|
265
289
|
|
|
290
|
+
if self.return_exception_as_code_400 :
|
|
291
|
+
@self.app.errorhandler(Exception)
|
|
292
|
+
def handle_exception(e):
|
|
293
|
+
|
|
294
|
+
exc_type, exc_value, exc_traceback = sys.exc_info()
|
|
295
|
+
key = getRandomKeysAndStr(n=10)
|
|
296
|
+
tb_last = traceback.extract_tb(exc_traceback)[-1] # Get last traceback frame
|
|
297
|
+
# Example: file, line, function, text
|
|
298
|
+
error_file = tb_last.filename
|
|
299
|
+
error_line = tb_last.lineno
|
|
300
|
+
error_func = tb_last.name
|
|
301
|
+
error_code = tb_last.line
|
|
302
|
+
|
|
303
|
+
# Log the full traceback (optional)
|
|
304
|
+
traceback.print_exc()
|
|
305
|
+
# Customize the error response
|
|
306
|
+
t = getTimestamp()
|
|
307
|
+
response = {
|
|
308
|
+
"status" : 400 ,
|
|
309
|
+
"key" : key,
|
|
310
|
+
"error": str(e),
|
|
311
|
+
"message": str(e),
|
|
312
|
+
"type": type(e).__name__ ,
|
|
313
|
+
"request_full_url" : request.url ,
|
|
314
|
+
"request_method" : request.method ,
|
|
315
|
+
"endpoint" : request.endpoint ,
|
|
316
|
+
"request_path" : request.path ,
|
|
317
|
+
"error_file" : os.path.basename(error_file).replace('.py' , ''),
|
|
318
|
+
"error_line" : error_line,
|
|
319
|
+
"error_func" : error_func,
|
|
320
|
+
"error_code" : error_code,
|
|
321
|
+
'timestamp' : t ,
|
|
322
|
+
"date" : convertTimestampToDate(t) ,
|
|
323
|
+
'traceback_url' : f"/request/traceback/{key}"
|
|
324
|
+
}
|
|
325
|
+
self.logger.error(f'error: {json.dumps(response , indent=4)}')
|
|
326
|
+
self.cache.set( custom_key=key , item={**response , 'traceback' : str(traceback.format_exc())} , auto_destroy_period=1800 , store_deleted_key=False )
|
|
327
|
+
# del response['traceback']
|
|
328
|
+
return response , 200
|
|
266
329
|
|
|
267
330
|
@self.app.after_request
|
|
268
331
|
def after_request(response) :
|
|
332
|
+
|
|
333
|
+
if self.simulate_network_delay :
|
|
334
|
+
time.sleep(self.simulate_network_delay)
|
|
335
|
+
|
|
269
336
|
try :
|
|
270
337
|
now = getTimestamp()
|
|
271
338
|
response.headers['internalid'] = request.internalid
|
|
272
339
|
response.headers['start_ts'] = request.start_ts
|
|
273
340
|
response.headers['end_ts'] = now
|
|
274
|
-
|
|
341
|
+
x = round(now - request.start_ts, 2)
|
|
342
|
+
response.headers['execution'] = x
|
|
275
343
|
if request.abortable :
|
|
276
344
|
response.headers['abortid'] = request.abort_id
|
|
277
345
|
response.headers['abortable'] = True
|
|
278
346
|
except :
|
|
279
347
|
response.headers['abortable'] = False
|
|
348
|
+
if self.log_url_requests and self.logger :
|
|
349
|
+
self.logger.info(f'[{request.method}]: {request.url} - [{response.status_code}] [secs:{x}]' , source='WebServer')
|
|
280
350
|
return response
|
|
281
351
|
|
|
282
352
|
# socketio client connected.
|
|
@@ -322,12 +392,18 @@ class UISERVER :
|
|
|
322
392
|
return self.wsgi_server
|
|
323
393
|
|
|
324
394
|
def shutdownUi(self) :
|
|
395
|
+
if hasattr(self, 'wsgi_server') and self.wsgi_server:
|
|
396
|
+
try:
|
|
397
|
+
self.wsgi_server.shutdown()
|
|
398
|
+
self.wsgi_server.server_close()
|
|
399
|
+
except:
|
|
400
|
+
pass
|
|
325
401
|
kill_thread(self.thread)
|
|
326
|
-
self.wsgi_server.server_close()
|
|
327
|
-
self.wsgi_server.shutdown()
|
|
328
402
|
|
|
329
403
|
def _wait_th(self , t ) :
|
|
330
|
-
t.join()
|
|
404
|
+
# t.join()
|
|
405
|
+
while True :
|
|
406
|
+
time.sleep(10)
|
|
331
407
|
|
|
332
408
|
|
|
333
409
|
def thrStartUi(self , suppress_prints=True) :
|
|
@@ -356,15 +432,46 @@ class UISERVER :
|
|
|
356
432
|
log.setLevel(logging.ERROR)
|
|
357
433
|
wsgi_server.serve_forever()
|
|
358
434
|
|
|
359
|
-
def
|
|
435
|
+
def on_ctrl_c(self , sig=None, frame=None):
|
|
436
|
+
self.stopUi()
|
|
437
|
+
pid = os.getpid()
|
|
438
|
+
os.kill(pid, signal.SIGTERM)
|
|
439
|
+
sys.exit(0)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def startUi(self , daemon=False , suppress_prints=True , block=False) :
|
|
360
443
|
self.start_before_request()
|
|
361
444
|
self.thread = self.flaskprocess = Thread(target=self.thrStartUi , args=[suppress_prints])
|
|
362
|
-
self.flaskprocess.daemon =
|
|
445
|
+
self.flaskprocess.daemon = daemon
|
|
363
446
|
self.flaskprocess.start()
|
|
364
447
|
start_thread(target=self._wait_th , args=[self.thread] , daemon=daemon)
|
|
448
|
+
signal.signal(signal.SIGINT, self.on_ctrl_c )
|
|
449
|
+
if block:
|
|
450
|
+
self.wait()
|
|
365
451
|
return self.thread
|
|
366
452
|
|
|
453
|
+
def wait(self):
|
|
454
|
+
"""
|
|
455
|
+
Block the main thread to keep it alive for signal handling (Ctrl+C).
|
|
456
|
+
This allows Ctrl+C to be properly detected. Call this after startUi()
|
|
457
|
+
if you want signal handling to work.
|
|
458
|
+
"""
|
|
459
|
+
try:
|
|
460
|
+
while self.flaskprocess.is_alive():
|
|
461
|
+
self.flaskprocess.join(timeout=0.1)
|
|
462
|
+
except KeyboardInterrupt:
|
|
463
|
+
if not hasattr(self, '_shutting_down'):
|
|
464
|
+
self._shutting_down = True
|
|
465
|
+
self.on_ctrl_c()
|
|
466
|
+
except SystemExit:
|
|
467
|
+
# Re-raise SystemExit to allow proper program termination
|
|
468
|
+
raise
|
|
469
|
+
|
|
367
470
|
def stopUi(self) :
|
|
471
|
+
if hasattr(self, 'wsgi_server') and self.wsgi_server:
|
|
472
|
+
try:
|
|
473
|
+
self.wsgi_server.shutdown()
|
|
474
|
+
except:
|
|
475
|
+
pass
|
|
368
476
|
kill_thread(self.thread)
|
|
369
|
-
return True
|
|
370
|
-
|
|
477
|
+
return True
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from ast import Import
|
|
2
|
+
import sys
|
|
1
3
|
from easy_utils_dev.debugger import DEBUGGER
|
|
2
4
|
import requests , json , subprocess
|
|
3
5
|
from requests.auth import HTTPBasicAuth as BAuth
|
|
@@ -16,9 +18,11 @@ from easy_utils_dev.utils import kill_thread
|
|
|
16
18
|
import atexit
|
|
17
19
|
try :
|
|
18
20
|
from snakebite.client import Client as HdfsClient
|
|
21
|
+
SNAKEBITEIMPORTED = True
|
|
19
22
|
except Exception as e:
|
|
20
23
|
print(f'Warning: snakebite is not installed. PM Hadoop client will not be available. {e}')
|
|
21
24
|
HdfsClient = None
|
|
25
|
+
SNAKEBITEIMPORTED = False
|
|
22
26
|
|
|
23
27
|
from datetime import datetime
|
|
24
28
|
|
|
@@ -751,6 +755,9 @@ class PmHadoopClient :
|
|
|
751
755
|
|
|
752
756
|
|
|
753
757
|
def connect(self) :
|
|
758
|
+
if not SNAKEBITEIMPORTED :
|
|
759
|
+
self.logger.error(f"HDFS Client importing had error. Maybe not supporting on this OS {sys.platform}. Exit")
|
|
760
|
+
raise ImportError(f"HDFS Client importing had error. Maybe not supporting on this OS {sys.platform}. Exit")
|
|
754
761
|
if not self.wsnoc.connected :
|
|
755
762
|
raise Exception('WSNOC is not connected')
|
|
756
763
|
try :
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|