ka-uts-com 2023.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,129 @@
1
+ # coding=utf-8
2
+
3
+ from os import path as os_path
4
+ import pkg_resources
5
+
6
+ from typing import Any, Dict, List
7
+
8
+ T_Arr = List[Any]
9
+ T_Dic = Dict[Any, Any]
10
+
11
+ TN_Dic = None | T_Dic
12
+
13
+
14
+ class Pacmod:
15
+ """ Package Module Management
16
+ """
17
+ def sh(root_cls, tenant: Any) -> T_Dic:
18
+ """ Show Pacmod Dictionary
19
+ """
20
+ a_pacmod: T_Arr = root_cls.__module__.split(".")
21
+ package = a_pacmod[0]
22
+ module = a_pacmod[1]
23
+ d_pacmod: T_Dic = {}
24
+ d_pacmod['tenant'] = tenant
25
+ d_pacmod['package'] = package
26
+ d_pacmod['module'] = module
27
+ return d_pacmod
28
+
29
+ class Cfg:
30
+ """ Configuration Sub Class of Package Module Class
31
+ """
32
+ @staticmethod
33
+ def sh_path(pacmod: T_Dic) -> str:
34
+ """ show directory
35
+ """
36
+ package = pacmod['package']
37
+ module = pacmod['module']
38
+
39
+ dir: str = f"{package}.data"
40
+
41
+ # print(f"dir = {dir}")
42
+ # print(f"package = {package}")
43
+ # print(f"module = {module}")
44
+
45
+ path = pkg_resources.resource_filename(dir, f"{module}.yml")
46
+ return path
47
+
48
+ class Pmd:
49
+ """ Package Sub Class of Package Module Class
50
+ """
51
+ @staticmethod
52
+ def sh_path_keys(
53
+ pacmod: Any, filename: str = 'keys.yml') -> str:
54
+ """ show directory
55
+ """
56
+ package = pacmod['package']
57
+ dir = f"{package}.data"
58
+ path = pkg_resources.resource_filename(dir, filename)
59
+ return path
60
+
61
+ class Path:
62
+
63
+ # class Data:
64
+ # class Dir:
65
+ # """ Data Directory Sub Class
66
+ # """
67
+ # @staticmethod
68
+ # def sh(pacmod: Dict, type: str) -> str:
69
+ # """ show Data File Path
70
+ # """
71
+ # package = pacmod['package']
72
+ # module = pacmod['module']
73
+ # return f"/data/{package}/{module}/{type}"
74
+
75
+ @staticmethod
76
+ def sh_data_package_module_type(pacmod: Dict, type_: str) -> str:
77
+ """ show Data File Path
78
+ """
79
+ package = pacmod['package']
80
+ module = pacmod['module']
81
+ return f"/data/{package}/{module}/{type_}"
82
+
83
+ @classmethod
84
+ def sh(
85
+ cls, pacmod: T_Dic, type_: str, suffix: str,
86
+ pid: Any, ts: Any, **kwargs) -> str:
87
+ """ show type specific path
88
+ """
89
+ filename = kwargs.get('filename')
90
+ if filename is not None:
91
+ filename_ = filename
92
+ else:
93
+ filename_ = type_
94
+
95
+ sw_run_pid_ts = kwargs.get('sw_run_pid_ts', True)
96
+ if sw_run_pid_ts is None:
97
+ sw_run_pid_ts = True
98
+
99
+ # _dir: str = cls.Data.Dir.sh(pacmod, type)
100
+ _dir: str = cls.sh_data_package_module_type(pacmod, type_)
101
+ if sw_run_pid_ts:
102
+ # pid = str(Com.pid)
103
+ # ts = str(Com.ts_start)
104
+ file_path = os_path.join(
105
+ _dir, f"{filename_}_{pid}_{ts}.{suffix}")
106
+ else:
107
+ file_path = os_path.join(_dir, f"{filename_}.{suffix}")
108
+ return file_path
109
+
110
+ @classmethod
111
+ def sh_pattern(
112
+ cls, pacmod: Dict, type_: str, suffix: str, **kwargs) -> str:
113
+ """ show type specific path
114
+ """
115
+ filename = kwargs.get('filename')
116
+ _dir: str = cls.sh_data_package_module_type(pacmod, type_)
117
+ return os_path.join(_dir, f"{filename}*.{suffix}")
118
+
119
+ class Log:
120
+
121
+ @staticmethod
122
+ def sh_cfg(pacmod: TN_Dic = None, filename: str = 'log.yml'):
123
+ """ show directory
124
+ """
125
+ if pacmod is None:
126
+ pacmod = {'package': 'ka_uts_com', 'module': 'com'}
127
+ return pkg_resources.resource_filename(
128
+ f"{pacmod['package']}.data", filename
129
+ )
File without changes
@@ -0,0 +1,72 @@
1
+ # coding=utf-8
2
+
3
+ from datetime import datetime
4
+
5
+ from ka_uts_com.com import Com
6
+ from ka_uts_com.log import Log
7
+
8
+ from typing import Any, List
9
+
10
+ T_Any = Any
11
+ T_Arr = List[Any]
12
+ T_Str = str
13
+
14
+ TN_Any = None | T_Any
15
+ TN_Str = None | T_Str
16
+
17
+
18
+ class Timestamp:
19
+
20
+ @staticmethod
21
+ def sh_elapse_time_sec(
22
+ end: Any, start: TN_Any) -> TN_Any:
23
+ if start is None:
24
+ return None
25
+ return end.timestamp()-start.timestamp()
26
+
27
+
28
+ class Timer:
29
+ """ Timer Management
30
+ """
31
+ @staticmethod
32
+ def sh_task_id(
33
+ class_id: Any, parms: TN_Any, separator: T_Str) -> T_Str:
34
+ """ start Timer
35
+ """
36
+ package = Com.pacmod_curr['package']
37
+ module = Com.pacmod_curr['module']
38
+ if isinstance(class_id, str):
39
+ class_name = class_id
40
+ else:
41
+ class_name = class_id.__qualname__
42
+ if not parms:
43
+ parms = ""
44
+ else:
45
+ parms = f" {parms}"
46
+ arr: T_Arr = []
47
+ for item in [package, module, class_name, parms]:
48
+ if not item:
49
+ continue
50
+ arr.append(item)
51
+ return separator.join(arr)
52
+
53
+ @classmethod
54
+ def start(
55
+ cls, class_id: T_Any,
56
+ parms: TN_Any = None, separator: T_Str = ".") -> None:
57
+ """ start Timer
58
+ """
59
+ task_id = cls.sh_task_id(class_id, parms, separator)
60
+ Com.d_timer[task_id] = datetime.now()
61
+
62
+ @classmethod
63
+ def end(cls, class_id: T_Any,
64
+ parms: TN_Any = None, separator: T_Str = ".") -> None:
65
+ """ end Timer
66
+ """
67
+ task_id = cls.sh_task_id(class_id, parms, separator)
68
+ start = Com.d_timer.get(task_id)
69
+ end = datetime.now()
70
+ elapse_time_sec = Timestamp.sh_elapse_time_sec(end, start)
71
+ msg = f"{task_id} elapse time [sec] = {elapse_time_sec}"
72
+ Log.info(msg, stacklevel=2)
ka_uts_com/__init__.py ADDED
File without changes
@@ -0,0 +1,10 @@
1
+ __title__ = 'ka_uts_com'
2
+ __description__ = 'Communication Area Utilities.'
3
+ __url__ = 'https://ka-ut-com.readthedocs.io/en/latest'
4
+ __version__ = '2023.6.0'
5
+ __build__ = 0x022200
6
+ __author__ = 'Bernd Stroehle'
7
+ __author_email__ = 'bernd.stroehle@bs29.com'
8
+ __license__ = 'Apache-2.0'
9
+ __copyright__ = 'Copyright 2023 bs29'
10
+ __cake__ = u'\u2728 \U0001f370 \u2728'
ka_uts_com/com.py ADDED
@@ -0,0 +1,196 @@
1
+ # coding=utf-8
2
+
3
+ import calendar
4
+ import logging
5
+ import logging.config
6
+ from logging import Logger
7
+
8
+ import os
9
+ import time
10
+ from datetime import datetime
11
+
12
+ from ka_uts_com.ioc import Yaml
13
+ from ka_uts_com.ioc import Jinja2
14
+ from ka_uts_com.pacmod import Pacmod
15
+
16
+ from typing import Any, Callable, List, Dict
17
+
18
+ T_Arr = List[Any]
19
+ T_Dic = Dict[Any, Any]
20
+
21
+ TN_Arr = None | T_Arr
22
+ TN_Dic = None | T_Dic
23
+
24
+
25
+ class StandardLog:
26
+
27
+ sw_init: bool = False
28
+ cfg: T_Dic = {}
29
+ log: Logger = logging.getLogger('dummy_logger')
30
+
31
+ @staticmethod
32
+ def read(pacmod: T_Dic, filename: str) -> Any:
33
+ path: str = Pacmod.Path.Log.sh_cfg(filename=filename)
34
+ tenant: str = pacmod['tenant']
35
+ package: str = pacmod['package']
36
+ module: str = pacmod['module']
37
+ pid = Com.pid
38
+ ts: None | datetime = Com.ts_start
39
+ log_main = Jinja2.read(
40
+ path, tenant=tenant, package=package, module=module,
41
+ pid=pid, ts=ts)
42
+ return log_main
43
+
44
+ @classmethod
45
+ def set_level(cls, sw_debug: bool) -> None:
46
+ if sw_debug:
47
+ level = logging.DEBUG
48
+ else:
49
+ level = logging.INFO
50
+ cls.cfg['handlers']['main_debug_console']['level'] = level
51
+ cls.cfg['handlers']['main_debug_file']['level'] = level
52
+
53
+ @classmethod
54
+ def init(
55
+ cls, **kwargs) -> None:
56
+ sw_debug: Any = kwargs.get('sw_debug')
57
+ if cls.sw_init:
58
+ return
59
+ cls.sw_init = True
60
+ cls.cfg = cls.read(Com.pacmod_curr, 'log.main.tenant.yml')
61
+ cls.set_level(sw_debug)
62
+ logging.config.dictConfig(cls.cfg)
63
+ cls.log = logging.getLogger('main')
64
+ return cls.log
65
+
66
+
67
+ class PersonLog:
68
+
69
+ sw_init: bool = False
70
+ cfg: T_Dic = {}
71
+ log: Logger = logging.getLogger('dummy_logger')
72
+
73
+ @classmethod
74
+ def read(
75
+ cls, pacmod: T_Dic, person: Any, filename: str) -> Any:
76
+ path: str = Pacmod.Path.Log.sh_cfg(filename=filename)
77
+ package: str = pacmod['package']
78
+ module: str = pacmod['module']
79
+ return Jinja2.read(
80
+ path, package=package, module=module, person=person,
81
+ pid=Com.pid, ts=Com.ts_start)
82
+
83
+ @classmethod
84
+ def set_level(cls, person: str, sw_debug: bool) -> None:
85
+ if sw_debug:
86
+ level = logging.DEBUG
87
+ else:
88
+ level = logging.INFO
89
+ cls.cfg['handlers'][f'{person}_debug_console']['level'] = level
90
+ cls.cfg['handlers'][f'{person}_debug_file']['level'] = level
91
+
92
+ @classmethod
93
+ def init(cls, pacmod: T_Dic, person: str, sw_debug: bool) -> None:
94
+ cls.cfg = cls.read(pacmod, person, 'log.person.yml')
95
+ cls.set_level(person, sw_debug)
96
+ logging.config.dictConfig(cls.cfg)
97
+ cls.log = logging.getLogger(person)
98
+ return cls.log
99
+
100
+
101
+ class Cfg:
102
+
103
+ @classmethod
104
+ def init(cls, pacmod: T_Dic) -> TN_Dic:
105
+ """ the package data directory has to contain a __init__.py
106
+ file otherwise the objects notation {package}.data to
107
+ locate the package data directory is invalid
108
+ """
109
+ _dic: TN_Dic = Yaml.read(Pacmod.Cfg.sh_path(pacmod))
110
+ return _dic
111
+
112
+
113
+ class Mgo:
114
+
115
+ client = None
116
+
117
+
118
+ class App:
119
+
120
+ sw_init: bool = False
121
+ httpmod = None
122
+ sw_replace_keys: None | bool = None
123
+ keys: TN_Arr = None
124
+ reqs: T_Dic = {}
125
+ app: T_Dic = {}
126
+
127
+ @classmethod
128
+ def init(
129
+ cls, **kwargs) -> Any:
130
+ if cls.sw_init:
131
+ return cls
132
+ cls.sw_init = True
133
+
134
+ cls.httpmod = kwargs.get('httpmod')
135
+ cls.sw_replace_keys = kwargs.get('sw_replace_keys', False)
136
+
137
+ try:
138
+ if cls.sw_replace_keys:
139
+ pacmod = kwargs.get('pacmod_curr')
140
+ cls.keys = Yaml.read(Pacmod.Pmd.sh_path_keys(pacmod))
141
+ except Exception as e:
142
+ if Com.Log is not None:
143
+ fnc_error: Callable = Com.Log.error
144
+ fnc_error(e, exc_info=True)
145
+ raise
146
+ return cls
147
+
148
+
149
+ class Exit:
150
+
151
+ sw_critical: bool = False
152
+ sw_stop: bool = False
153
+ sw_interactive: bool = False
154
+
155
+
156
+ class Com:
157
+ """Communication Class
158
+ """
159
+
160
+ sw_init: bool = False
161
+ cfg: TN_Dic = None
162
+ pid = None
163
+ pacmod_curr: T_Dic = {}
164
+
165
+ ts_start: None | datetime = None
166
+ ts_end: None | datetime = None
167
+ ts_etime: None | datetime = None
168
+ d_timer: Dict = {}
169
+
170
+ Log: Logger = logging.getLogger('dummy_logger')
171
+ App = None
172
+ Exit = Exit
173
+
174
+ @classmethod
175
+ def init(cls, **kwargs):
176
+ """ set log and application (module) configuration
177
+ """
178
+ if cls.sw_init:
179
+ return
180
+ cls.sw_init = True
181
+
182
+ cls.pacmod_curr = kwargs.get('pacmod_curr')
183
+ cls.ts_start = calendar.timegm(time.gmtime())
184
+ cls.pid = os.getpid()
185
+
186
+ cls.cfg = Cfg.init(cls.pacmod_curr)
187
+ cls.Log = StandardLog.init(**kwargs)
188
+ cls.App = App.init(**kwargs)
189
+
190
+ # @classmethod
191
+ # def terminate(cls):
192
+ # """ set log and application (module) configuration
193
+ # """
194
+ # cls.Log = StandardLog.log
195
+ # cls.ts_end = calendar.timegm(time.gmtime())
196
+ # cls.ts_etime = cls.ts_end - cls.ts_start
File without changes
@@ -0,0 +1,86 @@
1
+ version: 1
2
+
3
+ disable_existing_loggers: False
4
+
5
+ # root:
6
+ # level: DEBUG
7
+ # handlers:
8
+ # - debug_console
9
+ # - debug_file
10
+
11
+ loggers:
12
+
13
+ # main logger
14
+ main:
15
+ # level: NOTSET
16
+ level: DEBUG
17
+ handlers:
18
+ - main_debug_console
19
+ - main_debug_file
20
+ - main_info_file
21
+ - main_error_file
22
+
23
+ handlers:
24
+
25
+ main_debug_console:
26
+ class: 'logging.StreamHandler'
27
+ level: DEBUG
28
+ formatter: main_debug
29
+ stream: 'ext://sys.stderr'
30
+
31
+ # main_info_rotating_file_handler:
32
+ # class: 'logging.handlers.RotatingFileHandler'
33
+ # level: INFO
34
+ # formatter: info
35
+ # filename: 'info.rotating.log'
36
+ # mode: 'a'
37
+ # maxBytes: 1048576 # 1MB
38
+ # backupCount: 10
39
+ # encoding: utf8
40
+
41
+ main_debug_file:
42
+ class: 'logging.FileHandler'
43
+ level: DEBUG
44
+ formatter: main_error
45
+ filename: '/data/{{tenant}}/RUN/{{package}}/{{module}}/debs/debs_{{pid}}_{{ts}}.log'
46
+ mode: 'a'
47
+
48
+ main_info_file:
49
+ class: 'logging.FileHandler'
50
+ level: INFO
51
+ formatter: main_info
52
+ filename: '/data/{{tenant}}/RUN/{{package}}/{{module}}/logs/logs_{{pid}}_{{ts}}.log'
53
+ mode: 'a'
54
+
55
+ main_error_file:
56
+ class: 'logging.FileHandler'
57
+ level: ERROR
58
+ formatter: main_error
59
+ filename: '/data/{{tenant}}/RUN/{{package}}/{{module}}/errs/errs_{{pid}}_{{ts}}.log'
60
+ mode: 'a'
61
+
62
+ main_critical_mail:
63
+ class: 'logging.handlers.SMTPHandler'
64
+ level: CRITICAL
65
+ formatter: main_critical
66
+ mailhost : localhost
67
+ fromaddr: 'monitoring@domain.com'
68
+ toaddrs:
69
+ - 'dev@domain.com'
70
+ - 'qa@domain.com'
71
+ subject: 'Critical error with application name'
72
+
73
+
74
+ formatters:
75
+
76
+ main_info:
77
+ format: '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
78
+ main_debug:
79
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
80
+ datefmt: '%Y-%m-%d %H:%M:%S'
81
+ main_error:
82
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
83
+ datefmt: '%Y-%m-%d %H:%M:%S'
84
+ main_critical:
85
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
86
+ datefmt: '%Y-%m-%d %H:%M:%S'
@@ -0,0 +1,86 @@
1
+ version: 1
2
+
3
+ disable_existing_loggers: False
4
+
5
+ # root:
6
+ # level: DEBUG
7
+ # handlers:
8
+ # - debug_console
9
+ # - debug_file
10
+
11
+ loggers:
12
+
13
+ # main logger
14
+ main:
15
+ # level: NOTSET
16
+ level: DEBUG
17
+ handlers:
18
+ - main_debug_console
19
+ - main_debug_file
20
+ - main_info_file
21
+ - main_error_file
22
+
23
+ handlers:
24
+
25
+ main_debug_console:
26
+ class: 'logging.StreamHandler'
27
+ level: DEBUG
28
+ formatter: main_debug
29
+ stream: 'ext://sys.stderr'
30
+
31
+ # main_info_rotating_file_handler:
32
+ # class: 'logging.handlers.RotatingFileHandler'
33
+ # level: INFO
34
+ # formatter: info
35
+ # filename: 'info.rotating.log'
36
+ # mode: 'a'
37
+ # maxBytes: 1048576 # 1MB
38
+ # backupCount: 10
39
+ # encoding: utf8
40
+
41
+ main_debug_file:
42
+ class: 'logging.FileHandler'
43
+ level: DEBUG
44
+ formatter: main_error
45
+ filename: '/data/{{tenant}}/RUN/{{package}}/{{module}}/debs/debs_{{pid}}_{{ts}}.log'
46
+ mode: 'a'
47
+
48
+ main_info_file:
49
+ class: 'logging.FileHandler'
50
+ level: INFO
51
+ formatter: main_info
52
+ filename: '/data/{{tenant}}/RUN/{{package}}/{{module}}/logs/logs_{{pid}}_{{ts}}.log'
53
+ mode: 'a'
54
+
55
+ main_error_file:
56
+ class: 'logging.FileHandler'
57
+ level: ERROR
58
+ formatter: main_error
59
+ filename: '/data/{{tenant}}/RUN/{{package}}/{{module}}/errs/errs_{{pid}}_{{ts}}.log'
60
+ mode: 'a'
61
+
62
+ main_critical_mail:
63
+ class: 'logging.handlers.SMTPHandler'
64
+ level: CRITICAL
65
+ formatter: main_critical
66
+ mailhost : localhost
67
+ fromaddr: 'monitoring@domain.com'
68
+ toaddrs:
69
+ - 'dev@domain.com'
70
+ - 'qa@domain.com'
71
+ subject: 'Critical error with application name'
72
+
73
+
74
+ formatters:
75
+
76
+ main_info:
77
+ format: '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
78
+ main_debug:
79
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
80
+ datefmt: '%Y-%m-%d %H:%M:%S'
81
+ main_error:
82
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
83
+ datefmt: '%Y-%m-%d %H:%M:%S'
84
+ main_critical:
85
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
86
+ datefmt: '%Y-%m-%d %H:%M:%S'
@@ -0,0 +1,93 @@
1
+ version: 1
2
+
3
+ disable_existing_loggers: False
4
+
5
+ root:
6
+ level: DEBUG
7
+ handlers:
8
+ - debug_console
9
+ - debug_file
10
+
11
+ loggers:
12
+
13
+ # main logger
14
+ main:
15
+ level: 'NOTSET'
16
+ handlers:
17
+ - debug_console
18
+ - debug_file
19
+ - info_file
20
+ - error_file
21
+
22
+ # person logger
23
+ person:
24
+ level: NOTSET
25
+ handlers:
26
+ - debug_console
27
+ - debug_file
28
+ - info_file
29
+ - error_file
30
+
31
+ handlers:
32
+
33
+ debug_console:
34
+ class: 'logging.StreamHandler'
35
+ level: DEBUG
36
+ formatter: debug
37
+ stream: 'ext://sys.stderr'
38
+
39
+ debug_file:
40
+ class: 'logging.FileHandler'
41
+ level: DEBUG
42
+ formatter: error
43
+ filename: 'debug.log'
44
+ mode: 'a'
45
+
46
+ # info_rotating_file_handler:
47
+ # class: 'logging.handlers.RotatingFileHandler'
48
+ # level: INFO
49
+ # formatter: info
50
+ # filename: 'info.rotating.log'
51
+ # mode: 'a'
52
+ # maxBytes: 1048576 # 1MB
53
+ # backupCount: 10
54
+ # encoding: utf8
55
+
56
+ info_file:
57
+ class: 'logging.FileHandler'
58
+ level: INFO
59
+ formatter: info
60
+ filename: 'info.log'
61
+ mode: 'a'
62
+
63
+ error_file:
64
+ class: 'logging.FileHandler'
65
+ level: ERROR
66
+ formatter: error
67
+ filename: 'error.log'
68
+ mode: 'a'
69
+
70
+ critical_mail:
71
+ class: 'logging.handlers.SMTPHandler'
72
+ level: CRITICAL
73
+ formatter: critical
74
+ mailhost : localhost
75
+ fromaddr: 'monitoring@domain.com'
76
+ toaddrs:
77
+ - 'dev@domain.com'
78
+ - 'qa@domain.com'
79
+ subject: 'Critical error with application name'
80
+
81
+ formatters:
82
+
83
+ info:
84
+ format: '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
85
+ debug:
86
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
87
+ datefmt: '%Y-%m-%d %H:%M:%S'
88
+ error:
89
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
90
+ datefmt: '%Y-%m-%d %H:%M:%S'
91
+ critical:
92
+ format: '%(asctime)-15s %(levelname)s-%(name)s-%(process)d::%(module)s.%(funcName)s|%(lineno)s:: %(message)s'
93
+ datefmt: '%Y-%m-%d %H:%M:%S'