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.
Files changed (43) hide show
  1. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/PKG-INFO +2 -1
  2. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/wsnoclib.py +116 -4
  3. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/PKG-INFO +2 -1
  4. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/requires.txt +1 -0
  5. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/setup.py +2 -1
  6. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/MANIFEST.in +0 -0
  7. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/EasySsh.py +0 -0
  8. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/Events.py +0 -0
  9. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/FastQueue.py +0 -0
  10. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/NameObject.py +0 -0
  11. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/__init__.py +0 -0
  12. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/abortable.py +0 -0
  13. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/brevosmtp.py +0 -0
  14. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/check_license.py +0 -0
  15. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/cplib.py +0 -0
  16. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/custom_env.py +0 -0
  17. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/debugger-C-PF4PAMMP.py +0 -0
  18. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/debugger.py +0 -0
  19. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/easy_oracle.py +0 -0
  20. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/encryptor.py +0 -0
  21. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ept.py +0 -0
  22. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ept_sql/create_dirs.sql +0 -0
  23. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ept_sql/create_ept_tables.sql +0 -0
  24. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/exceptions.py +0 -0
  25. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/filescompressor.py +0 -0
  26. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/generate_license.py +0 -0
  27. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/keycloakapi.py +0 -0
  28. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/lralib.py +0 -0
  29. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/ne1830PSS.py +0 -0
  30. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/nsp_kafka.py +0 -0
  31. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/openid_server.py +0 -0
  32. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/optics_utils.py +0 -0
  33. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/require_auth.py +0 -0
  34. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/simple_sqlite.py +0 -0
  35. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/temp_memory.py +0 -0
  36. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/uiserver.py +0 -0
  37. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/utils.py +0 -0
  38. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/winserviceapi.py +0 -0
  39. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev/wsselib.py +0 -0
  40. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/SOURCES.txt +0 -0
  41. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/dependency_links.txt +0 -0
  42. {easy_utils_dev-2.141 → easy_utils_dev-2.143}/easy_utils_dev.egg-info/top_level.txt +0 -0
  43. {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.141
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.141
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,5 +1,6 @@
1
1
  psutil
2
2
  ping3
3
+ snakebite-py3
3
4
  flask
4
5
  flask_cors
5
6
  xmltodict
@@ -1,6 +1,6 @@
1
1
  from setuptools import setup, find_packages
2
2
 
3
- VERSION = '2.141'
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