easy-utils-dev 2.141__tar.gz → 2.143__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.141 → easy_utils_dev-2.143}/PKG-INFO +2 -1
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/wsnoclib.py +116 -4
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/PKG-INFO +2 -1
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/requires.txt +1 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/setup.py +2 -1
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/MANIFEST.in +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/EasySsh.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/Events.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/FastQueue.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/NameObject.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/__init__.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/abortable.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/brevosmtp.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/check_license.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/cplib.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/custom_env.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/debugger-C-PF4PAMMP.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/debugger.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/easy_oracle.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/encryptor.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ept.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ept_sql/create_dirs.sql +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ept_sql/create_ept_tables.sql +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/exceptions.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/filescompressor.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/generate_license.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/keycloakapi.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/lralib.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ne1830PSS.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/nsp_kafka.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/openid_server.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/optics_utils.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/require_auth.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/simple_sqlite.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/temp_memory.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/uiserver.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/utils.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/winserviceapi.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/wsselib.py +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/SOURCES.txt +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/dependency_links.txt +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/top_level.txt +0 -0
- {easy_utils_dev-2.141 → easy_utils_dev-2.143}/setup.cfg +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: easy_utils_dev
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.143
|
|
4
4
|
Keywords: python3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Requires-Dist: psutil
|
|
7
7
|
Requires-Dist: ping3
|
|
8
|
+
Requires-Dist: snakebite-py3
|
|
8
9
|
Requires-Dist: flask
|
|
9
10
|
Requires-Dist: flask_cors
|
|
10
11
|
Requires-Dist: xmltodict
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from easy_utils_dev.debugger import DEBUGGER
|
|
2
2
|
import requests , json , subprocess
|
|
3
3
|
from requests.auth import HTTPBasicAuth as BAuth
|
|
4
|
-
from .utils import pingAddress , fixTupleForSql , start_thread , mkdirs
|
|
4
|
+
from .utils import pingAddress , fixTupleForSql , start_thread , mkdirs , getTimestamp
|
|
5
5
|
from time import sleep
|
|
6
6
|
from urllib3.exceptions import InsecureRequestWarning
|
|
7
7
|
from urllib3 import disable_warnings
|
|
@@ -15,7 +15,8 @@ import tempfile , os
|
|
|
15
15
|
from kafka import KafkaConsumer
|
|
16
16
|
from easy_utils_dev.utils import kill_thread
|
|
17
17
|
import atexit
|
|
18
|
-
|
|
18
|
+
from snakebite.client import Client as HdfsClient
|
|
19
|
+
from datetime import datetime
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class KafkaConfig :
|
|
@@ -38,7 +39,6 @@ class KafkaConfig :
|
|
|
38
39
|
self.enable_auto_refresh = False
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
|
|
42
42
|
class WSNOCLIB :
|
|
43
43
|
def __init__(
|
|
44
44
|
self,
|
|
@@ -51,7 +51,8 @@ class WSNOCLIB :
|
|
|
51
51
|
request_max_count=30,
|
|
52
52
|
tmp_dir = tempfile.gettempdir() ,
|
|
53
53
|
kafka = KafkaConfig(),
|
|
54
|
-
register_atexit=True
|
|
54
|
+
register_atexit=True,
|
|
55
|
+
trust_env=True
|
|
55
56
|
):
|
|
56
57
|
self.logger = DEBUGGER(f'{debug_name}-{ip}',level=debug_level,homePath=debug_homepath)
|
|
57
58
|
self.disabledWarnings = self.disableUrlWarnings()
|
|
@@ -59,6 +60,7 @@ class WSNOCLIB :
|
|
|
59
60
|
self.address = ip
|
|
60
61
|
self.username = username
|
|
61
62
|
self.password = password
|
|
63
|
+
self.trust_env = trust_env
|
|
62
64
|
self.external_nsp = False
|
|
63
65
|
self.api_count = 0
|
|
64
66
|
self.api_count_limit = 999999999999
|
|
@@ -82,6 +84,8 @@ class WSNOCLIB :
|
|
|
82
84
|
self.refresh_thread = None
|
|
83
85
|
self.token_refresh_count = 0
|
|
84
86
|
self.session = WSNOCSession(self)
|
|
87
|
+
self.connected = False
|
|
88
|
+
self.pm_hadoop = PmHadoopClient(self)
|
|
85
89
|
if register_atexit :
|
|
86
90
|
atexit.register(self.goodbye)
|
|
87
91
|
|
|
@@ -150,6 +154,7 @@ class WSNOCLIB :
|
|
|
150
154
|
if auto_refresh_token :
|
|
151
155
|
self.autoRefreshThread = self.refresh_thread = start_thread(target=self.runAutoRefreshThread)
|
|
152
156
|
self.logger.debug(f'token => {r.text}')
|
|
157
|
+
self.connected = True
|
|
153
158
|
return self.token
|
|
154
159
|
|
|
155
160
|
|
|
@@ -182,6 +187,7 @@ class WSNOCLIB :
|
|
|
182
187
|
r.close()
|
|
183
188
|
except :
|
|
184
189
|
pass
|
|
190
|
+
self.connected = False
|
|
185
191
|
return True
|
|
186
192
|
|
|
187
193
|
def goodbye(self):
|
|
@@ -610,6 +616,7 @@ class WSNOCLIB :
|
|
|
610
616
|
self.bearer_token = f'Bearer {self.access_token}'
|
|
611
617
|
self.token = r.json()
|
|
612
618
|
self.token.update({'bearer_token' : self.bearer_token })
|
|
619
|
+
self.connected = True
|
|
613
620
|
return r
|
|
614
621
|
|
|
615
622
|
def session_info(self) :
|
|
@@ -706,6 +713,9 @@ class WSNOCSession(requests.Session):
|
|
|
706
713
|
self._wsnoc = wsnoc
|
|
707
714
|
self.verify = False
|
|
708
715
|
self.retries = 0
|
|
716
|
+
if not wsnoc.trust_env :
|
|
717
|
+
os.environ['https_proxy'] = ""
|
|
718
|
+
os.environ['http_proxy'] = ""
|
|
709
719
|
self.debug_this_request = False
|
|
710
720
|
self.skip_hold_for_token_refresh = False
|
|
711
721
|
|
|
@@ -749,6 +759,108 @@ class WSNOCSession(requests.Session):
|
|
|
749
759
|
self._wsnoc.logger.info(f'[{method}] : {url} - [{request.status_code}]')
|
|
750
760
|
return request
|
|
751
761
|
|
|
762
|
+
class PmHadoopClient :
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
def __init__(self , _wsnoc : WSNOCLIB):
|
|
766
|
+
self.ip = _wsnoc.address
|
|
767
|
+
self.wsnoc = _wsnoc
|
|
768
|
+
self.client : HdfsClient = None
|
|
769
|
+
self.hdfs_port = 8020
|
|
770
|
+
self.hdfs_user = 'otn'
|
|
771
|
+
self.hdfs_root = '/'
|
|
772
|
+
self.hdfs_use_trash = False
|
|
773
|
+
self.PM24H = 1
|
|
774
|
+
self.PM15M = 2
|
|
775
|
+
self.KPIAGGR = 3
|
|
776
|
+
self.CURRENT = 1
|
|
777
|
+
self.ARCHIVE = 2
|
|
778
|
+
self.logger : DEBUGGER = self.wsnoc.logger
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
def connect(self) :
|
|
782
|
+
if not self.wsnoc.connected :
|
|
783
|
+
raise Exception('WSNOC is not connected')
|
|
784
|
+
try :
|
|
785
|
+
self.client = HdfsClient(self.ip, self.hdfs_port, use_trash=self.hdfs_use_trash)
|
|
786
|
+
except Exception as e:
|
|
787
|
+
self.logger.warning('PM Hadoop client is using WSNOC port 8020/custom port. Please check if it is not blocked by firewall.' , source='PmHadoopClient')
|
|
788
|
+
self.logger.error(f'Failed to connect to PM Hadoop: {e}' , source='PmHadoopClient')
|
|
789
|
+
raise
|
|
790
|
+
|
|
791
|
+
def change_date_to_timestamp(self , date_str) :
|
|
792
|
+
'''
|
|
793
|
+
this is a helper function to convert date string to timestamp
|
|
794
|
+
date_str : must be in the format of %Y%m%d example: 20250101
|
|
795
|
+
return : timestamp
|
|
796
|
+
'''
|
|
797
|
+
dt = datetime.strptime(date_str, "%Y%m%d")
|
|
798
|
+
return int(dt.timestamp())
|
|
799
|
+
|
|
800
|
+
def pm_list(self , mode , target_pm , date_range=[]) :
|
|
801
|
+
'''
|
|
802
|
+
mode : must be one of the following:
|
|
803
|
+
- self.PM24H
|
|
804
|
+
- self.PM15M
|
|
805
|
+
- self.KPIAGGR
|
|
806
|
+
target_pm : must be on the following :
|
|
807
|
+
- self.CURRENT
|
|
808
|
+
- self.ARCHIVE
|
|
809
|
+
date_range : must be a list of two integers in the format of [start_timestamp, end_timestamp]
|
|
810
|
+
- for example: [1718217600, 1718221200]
|
|
811
|
+
- if date_range is not provided, all available PM dates will be returned
|
|
812
|
+
'''
|
|
813
|
+
if mode == self.PM24H :
|
|
814
|
+
_mode = 'ONE_DAY'
|
|
815
|
+
elif mode == self.PM15M :
|
|
816
|
+
_mode = 'FIFTEEN_MINS'
|
|
817
|
+
elif mode == self.KPIAGGR :
|
|
818
|
+
_mode = 'KPIAGGR'
|
|
819
|
+
else :
|
|
820
|
+
raise Exception(f'Invalid mode: {mode}')
|
|
821
|
+
if target_pm == self.CURRENT :
|
|
822
|
+
_target = 'PMDATA'
|
|
823
|
+
elif target_pm == self.ARCHIVE :
|
|
824
|
+
_target = "ARC_PMDATA"
|
|
825
|
+
else :
|
|
826
|
+
self.logger.error(f"target_pm arg must be self.CURRENT or self.ARCHIVE.")
|
|
827
|
+
raise Exception("Invalid TARGET_PM")
|
|
828
|
+
self.logger.info(f"Getting available PM dates for {_target}/{_mode}" , source='PmHadoopClient')
|
|
829
|
+
dirs = list(self.client.ls([f'/{_target}/{_mode}']))
|
|
830
|
+
ts_now = getTimestamp()
|
|
831
|
+
for index , dir in enumerate(dirs) :
|
|
832
|
+
self.logger.info(f"Processing {dir.get('path')}" , source='PmHadoopClient')
|
|
833
|
+
date_str = dir.get('path').split('=')[-1]
|
|
834
|
+
dir['pm_date'] = int(date_str)
|
|
835
|
+
dir['mode'] = _mode
|
|
836
|
+
dt = datetime.strptime(date_str, "%Y%m%d")
|
|
837
|
+
dir['pm_date_timestamp'] = int(dt.timestamp())
|
|
838
|
+
if len(date_range) > 0 :
|
|
839
|
+
if dir['pm_date_timestamp'] < date_range[0] :
|
|
840
|
+
del dirs[index]
|
|
841
|
+
if dir['pm_date_timestamp'] > date_range[1] :
|
|
842
|
+
del dirs[index]
|
|
843
|
+
return dirs
|
|
844
|
+
|
|
845
|
+
def _download_dir(self , hdfs_path, local_path):
|
|
846
|
+
for entry in self.client.ls([hdfs_path]):
|
|
847
|
+
# print(entry)
|
|
848
|
+
entry_path = entry['path']
|
|
849
|
+
entry_type = entry['file_type']
|
|
850
|
+
if entry_type == 'd':
|
|
851
|
+
subdir = os.path.join(local_path, os.path.basename(entry_path))
|
|
852
|
+
mkdirs(subdir)
|
|
853
|
+
self._download_dir(entry_path, subdir)
|
|
854
|
+
else: # FILE
|
|
855
|
+
self.logger.debug(f"Downloading {entry_path} → {local_path}" , source='PmHadoopClient')
|
|
856
|
+
self.client.copyToLocal([entry_path], local_path)
|
|
857
|
+
|
|
858
|
+
def download(self , obj , destination_path) :
|
|
859
|
+
self.wsnoc.logger.info(f'Downloading {obj.get("pm_date")} to {destination_path}')
|
|
860
|
+
destination_path = f"{destination_path}/{obj.get('mode')}/{obj.get('pm_date')}"
|
|
861
|
+
mkdirs(destination_path)
|
|
862
|
+
self._download_dir(obj.get('path'), destination_path)
|
|
863
|
+
|
|
752
864
|
|
|
753
865
|
if __name__ == '__main__' :
|
|
754
866
|
# noc = WSNOCLIB('10.20.30.55' , 'admin' , 'Nokia@2024')
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: easy_utils_dev
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.143
|
|
4
4
|
Keywords: python3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Requires-Dist: psutil
|
|
7
7
|
Requires-Dist: ping3
|
|
8
|
+
Requires-Dist: snakebite-py3
|
|
8
9
|
Requires-Dist: flask
|
|
9
10
|
Requires-Dist: flask_cors
|
|
10
11
|
Requires-Dist: xmltodict
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from setuptools import setup, find_packages
|
|
2
2
|
|
|
3
|
-
VERSION = '2.
|
|
3
|
+
VERSION = '2.143'
|
|
4
4
|
|
|
5
5
|
# Setting up
|
|
6
6
|
setup(
|
|
@@ -11,6 +11,7 @@ setup(
|
|
|
11
11
|
install_requires=[
|
|
12
12
|
'psutil' ,
|
|
13
13
|
'ping3' ,
|
|
14
|
+
'snakebite-py3',
|
|
14
15
|
'flask' ,
|
|
15
16
|
'flask_cors' ,
|
|
16
17
|
'xmltodict' ,
|
|
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
|
|
File without changes
|
|
File without changes
|