ka-uts-com 1.0.0.240823__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.
Files changed (41) hide show
  1. build/lib/dist/ka_uts_com-1.0.0.240823-py3-none-any.whl +0 -0
  2. build/lib/dist/ka_uts_com-1.0.0.240823.tar.gz +0 -0
  3. build/lib/ka_uts_com/__init__.py +0 -0
  4. build/lib/ka_uts_com/__version__.py +10 -0
  5. build/lib/ka_uts_com/aeq.py +87 -0
  6. build/lib/ka_uts_com/argv.py +49 -0
  7. build/lib/ka_uts_com/com.py +222 -0
  8. build/lib/ka_uts_com/data/__init__.py +0 -0
  9. build/lib/ka_uts_com/data/log.personal.yml +93 -0
  10. build/lib/ka_uts_com/data/log.standard.yml +86 -0
  11. build/lib/ka_uts_com/date.py +15 -0
  12. build/lib/ka_uts_com/fnc.py +37 -0
  13. build/lib/ka_uts_com/ioc.py +57 -0
  14. build/lib/ka_uts_com/log.py +63 -0
  15. build/lib/ka_uts_com/pacmod.py +111 -0
  16. build/lib/ka_uts_com/py.typed +0 -0
  17. build/lib/ka_uts_com/str.py +268 -0
  18. build/lib/ka_uts_com/timer.py +72 -0
  19. dist/ka_uts_com-1.0.0.240823-py3-none-any.whl +0 -0
  20. dist/ka_uts_com-1.0.0.240823.tar.gz +0 -0
  21. ka_uts_com/__init__.py +0 -0
  22. ka_uts_com/__version__.py +10 -0
  23. ka_uts_com/aeq.py +87 -0
  24. ka_uts_com/argv.py +49 -0
  25. ka_uts_com/com.py +222 -0
  26. ka_uts_com/data/__init__.py +0 -0
  27. ka_uts_com/data/log.personal.yml +93 -0
  28. ka_uts_com/data/log.standard.yml +86 -0
  29. ka_uts_com/date.py +15 -0
  30. ka_uts_com/fnc.py +37 -0
  31. ka_uts_com/ioc.py +57 -0
  32. ka_uts_com/log.py +63 -0
  33. ka_uts_com/pacmod.py +111 -0
  34. ka_uts_com/py.typed +0 -0
  35. ka_uts_com/str.py +268 -0
  36. ka_uts_com/timer.py +72 -0
  37. ka_uts_com-1.0.0.240823.dist-info/LICENSE.txt +19 -0
  38. ka_uts_com-1.0.0.240823.dist-info/METADATA +943 -0
  39. ka_uts_com-1.0.0.240823.dist-info/RECORD +41 -0
  40. ka_uts_com-1.0.0.240823.dist-info/WHEEL +5 -0
  41. ka_uts_com-1.0.0.240823.dist-info/top_level.txt +4 -0
File without changes
@@ -0,0 +1,10 @@
1
+ __title__ = 'ka_uts_com'
2
+ __description__ = 'Communication Utilities.'
3
+ __url__ = 'https://ka-ut-com.readthedocs.io/en/latest'
4
+ __version__ = '1.0.0.240823'
5
+ __build__ = 0x022200
6
+ __author__ = 'Bernd Stroehle'
7
+ __author_email__ = 'bernd.stroehle@gmail.com'
8
+ __license__ = 'Apache-2.0'
9
+ __copyright__ = 'Copyright 2024 Bernd Stroehle'
10
+ __cake__ = u'\u2728 \U0001f370 \u2728'
@@ -0,0 +1,87 @@
1
+ # coding=utf-8
2
+
3
+ # import orjson
4
+ # import traceback
5
+
6
+ from ka_uts_com.date import Date
7
+ from ka_uts_com.str import Str
8
+
9
+ from typing import Any, Dict, List
10
+
11
+ TN_Date = None | Any
12
+
13
+ T_Arr = List[Any]
14
+ T_Dic = Dict[Any, Any]
15
+
16
+ TN_Arr = None | T_Arr
17
+ TN_Dic = None | T_Dic
18
+ TN_Str = None | str
19
+
20
+
21
+ class Aeq:
22
+ """ Dictionary of Equates
23
+ """
24
+ @classmethod
25
+ def sh_value(cls, key: str, value: Any, d_valid_parms: TN_Dic) -> Any:
26
+
27
+ # print(f"key = {key}, type(key) = {type(key)}")
28
+ # print(f"value = {value}, type(value) = {type(value)}")
29
+ if not d_valid_parms:
30
+ return value
31
+ _type: TN_Str = d_valid_parms.get(key)
32
+ # print(f"_type = {_type}")
33
+ if not _type:
34
+ return value
35
+ if isinstance(_type, str):
36
+ match _type:
37
+ case 'int':
38
+ value = int(value)
39
+ case 'bool':
40
+ value = Str.sh_boolean(value)
41
+ case 'dict':
42
+ value = Str.sh_dic(value)
43
+ case 'list':
44
+ value = Str.sh_arr(value)
45
+ case '%Y-%m-%d':
46
+ value = Date.sh(value, _type)
47
+ case '_':
48
+ match _type[0]:
49
+ case '[', '{':
50
+ _obj = Str.sh_dic(_type)
51
+ if value not in _obj:
52
+ msg = (f"parameter={key} value={value} is invalid; "
53
+ f"valid values are={_obj}")
54
+ raise Exception(msg)
55
+
56
+ # print(f"value = {value}, type(value) = {type(value)}")
57
+ return value
58
+
59
+ @classmethod
60
+ def sh_d_eq(cls, a_s_eq: T_Arr, d_valid_parms: TN_Dic) -> T_Dic:
61
+
62
+ d_eq = {}
63
+ _d_valid_parms = d_valid_parms
64
+ for s_eq in a_s_eq[1:]:
65
+ a_eq = s_eq.split('=')
66
+ if len(a_eq) == 1:
67
+ key = 'cmd'
68
+ value = a_eq[0]
69
+ if _d_valid_parms is not None:
70
+ if value in _d_valid_parms:
71
+ _d_valid_parms = _d_valid_parms[value]
72
+ else:
73
+ _valid_commands = list(_d_valid_parms.keys())
74
+ msg = (f"Wrong command: {value}; "
75
+ f"valid commands are: {_valid_commands}")
76
+ else:
77
+ key = a_eq[0]
78
+ value = a_eq[1]
79
+
80
+ if _d_valid_parms is not None:
81
+ if key not in _d_valid_parms:
82
+ msg = (f"Wrong parameter: {key}; "
83
+ f"valid parameters are: {_d_valid_parms}")
84
+ raise Exception(msg)
85
+ value = cls.sh_value(key, value, _d_valid_parms)
86
+ d_eq[key] = value
87
+ return d_eq
@@ -0,0 +1,49 @@
1
+ # coding=utf-8
2
+
3
+ from ka_uts_com.pacmod import Pacmod
4
+ from ka_uts_com.aeq import Aeq
5
+
6
+ from typing import Any, Callable, Dict, List
7
+
8
+ T_Arr = List[Any]
9
+ T_Dic = Dict[Any, Any]
10
+
11
+ TN_Arr = None | T_Arr
12
+ TN_Dic = None | T_Dic
13
+
14
+
15
+ class Argv:
16
+ """ Manage Commandline Arguments
17
+ """
18
+ @staticmethod
19
+ def set_by_pacmod(d_eq: T_Dic, root_cls) -> None:
20
+ """ set current pacmod dictionary
21
+ """
22
+ tenant = d_eq.get('tenant')
23
+ d_eq['pacmod_curr'] = Pacmod.sh_d_pacmod(root_cls, tenant)
24
+
25
+ @staticmethod
26
+ def set_by_prof(d_eq: T_Dic, sh_prof: Callable | Any) -> None:
27
+ """ set current pacmod dictionary
28
+ """
29
+ if callable(sh_prof):
30
+ d_eq['sh_prof'] = sh_prof()
31
+ else:
32
+ d_eq['sh_prof'] = sh_prof
33
+
34
+ @classmethod
35
+ def sh(cls, a_s_eq: T_Arr, **kwargs) -> T_Dic:
36
+ """ show equates dictionary
37
+ """
38
+ # print(f"DoEq sh kwargs = {kwargs}")
39
+ root_cls = kwargs.get('root_cls')
40
+ d_valid_parms: TN_Dic = kwargs.get('d_parms')
41
+ # print(f"DoEq sh d_valid_parms = {d_valid_parms}")
42
+
43
+ d_eq = Aeq.sh_d_eq(a_s_eq, d_valid_parms)
44
+
45
+ cls.set_by_pacmod(d_eq, root_cls)
46
+ _sh_prof = kwargs.get('sh_prof')
47
+ cls.set_by_prof(d_eq, _sh_prof)
48
+
49
+ return d_eq
@@ -0,0 +1,222 @@
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_Any = Any
19
+ T_Arr = List[Any]
20
+ T_Bool = bool
21
+ T_Dic = Dict[Any, Any]
22
+
23
+ TN_Arr = None | T_Arr
24
+ TN_Bool = None | bool
25
+ TN_Dic = None | T_Dic
26
+ TN_DT = None | datetime
27
+
28
+
29
+ class LogStandard:
30
+ """Standard Logging
31
+ """
32
+ sw_init: bool = False
33
+ cfg: T_Dic = {}
34
+ log: Logger = logging.getLogger('dummy_logger')
35
+ logfile: str = 'log.standard.yml'
36
+
37
+ @staticmethod
38
+ def read(pacmod: T_Dic, filename: str) -> Any:
39
+ """Read log file path with jinja2
40
+ """
41
+ # path: str = Pacmod.Path.Log.sh_cfg(filename=filename)
42
+ path: str = Pacmod.sh_path_cfg_log(filename=filename)
43
+ tenant: str = pacmod['tenant']
44
+ package: str = pacmod['package']
45
+ module: str = pacmod['module']
46
+ pid = Com.pid
47
+ ts: TN_DT = Com.ts_start
48
+ cfg = Jinja2.read(
49
+ path, tenant=tenant,
50
+ package=package, module=module,
51
+ pid=pid, ts=ts)
52
+ return cfg
53
+
54
+ @classmethod
55
+ def set_level(cls, sw_debug: bool) -> None:
56
+ """Set static variable log level in log configuration handlers
57
+ """
58
+ if sw_debug:
59
+ level = logging.DEBUG
60
+ else:
61
+ level = logging.INFO
62
+ cls.cfg['handlers']['main_debug_console']['level'] = level
63
+ cls.cfg['handlers']['main_debug_file']['level'] = level
64
+
65
+ @classmethod
66
+ def init(
67
+ cls, **kwargs) -> None:
68
+ cls.sw_init = True
69
+ cls.cfg = cls.read(Com.pacmod_curr, cls.logfile)
70
+ sw_debug: Any = kwargs.get('sw_debug')
71
+ cls.set_level(sw_debug)
72
+ logging.config.dictConfig(cls.cfg)
73
+ cls.log = logging.getLogger('main')
74
+
75
+ @classmethod
76
+ def sh(cls, **kwargs) -> Any:
77
+ if cls.sw_init:
78
+ return cls.log
79
+ cls.init(**kwargs)
80
+ return cls.log
81
+
82
+
83
+ class LogPersonal:
84
+ """Personal Logging
85
+ """
86
+ sw_init: bool = False
87
+ cfg: T_Dic = {}
88
+ logfile = 'log.person.yml'
89
+ log: Logger = logging.getLogger('dummy_logger')
90
+
91
+ @classmethod
92
+ def read(cls, pacmod: T_Dic, person: Any, filename: str) -> Any:
93
+ path: str = Pacmod.sh_path_cfg_log(filename=filename)
94
+ package: str = pacmod['package']
95
+ module: str = pacmod['module']
96
+ return Jinja2.read(
97
+ path, package=package, module=module, person=person,
98
+ pid=Com.pid, ts=Com.ts_start)
99
+
100
+ @classmethod
101
+ def set_level(cls, person: str, sw_debug: bool) -> None:
102
+ if sw_debug:
103
+ level = logging.DEBUG
104
+ else:
105
+ level = logging.INFO
106
+ cls.cfg['handlers'][f'{person}_debug_console']['level'] = level
107
+ cls.cfg['handlers'][f'{person}_debug_file']['level'] = level
108
+
109
+ @classmethod
110
+ def init(cls, pacmod: T_Dic, person: str, sw_debug: bool) -> None:
111
+ cls.cfg = cls.read(pacmod, person, cls.logfile)
112
+ cls.set_level(person, sw_debug)
113
+ logging.config.dictConfig(cls.cfg)
114
+ cls.log = logging.getLogger(person)
115
+
116
+ @classmethod
117
+ def sh(cls, **kwargs) -> Any:
118
+ if cls.sw_init:
119
+ return cls.log
120
+ cls.init(**kwargs)
121
+ return cls.log
122
+
123
+
124
+ class Cfg:
125
+ """Configuration Class
126
+ """
127
+ @classmethod
128
+ def init(cls, pacmod: T_Dic) -> TN_Dic:
129
+ """ the package data directory has to contain a __init__.py
130
+ file otherwise the objects notation {package}.data to
131
+ locate the package data directory is invalid
132
+ """
133
+ _dic: TN_Dic = Yaml.read(Pacmod.sh_path_cfg_yaml(pacmod))
134
+ return _dic
135
+
136
+
137
+ class Mgo:
138
+ """Mongo DB Class
139
+ """
140
+ client = None
141
+
142
+
143
+ class App:
144
+ """Aplication Class
145
+ """
146
+ sw_init: T_Bool = False
147
+ httpmod: T_Any = None
148
+ sw_replace_keys: TN_Bool = None
149
+ keys: TN_Arr = None
150
+ reqs: T_Dic = {}
151
+ app: T_Dic = {}
152
+
153
+ @classmethod
154
+ def init(cls, **kwargs) -> Any:
155
+ cls.sw_init = True
156
+ cls.httpmod = kwargs.get('httpmod')
157
+ cls.sw_replace_keys = kwargs.get('sw_replace_keys', False)
158
+ try:
159
+ if cls.sw_replace_keys:
160
+ pacmod = kwargs.get('pacmod_curr')
161
+ # cls.keys = Yaml.read(Pacmod.Pmd.sh_path_keys(pacmod))
162
+ cls.keys = Yaml.read(Pacmod.sh_path_keys_yaml(pacmod))
163
+ except Exception as e:
164
+ if Com.Log is not None:
165
+ fnc_error: Callable = Com.Log.error
166
+ fnc_error(e, exc_info=True)
167
+ raise
168
+ return cls
169
+
170
+ @classmethod
171
+ def sh(cls, **kwargs) -> Any:
172
+ if cls.sw_init:
173
+ return cls
174
+ cls.init(**kwargs)
175
+ return cls
176
+
177
+
178
+ class Exit:
179
+ """Exit Class
180
+ """
181
+ sw_critical: bool = False
182
+ sw_stop: bool = False
183
+ sw_interactive: bool = False
184
+
185
+
186
+ class Com:
187
+ """Communication Class
188
+ """
189
+ sw_init: bool = False
190
+ cfg: TN_Dic = None
191
+ pid = None
192
+ pacmod_curr: T_Dic = {}
193
+
194
+ ts_start: None | datetime = None
195
+ ts_end: None | datetime = None
196
+ ts_etime: None | datetime = None
197
+ d_timer: Dict = {}
198
+
199
+ # Log = None
200
+ Log: Logger = logging.getLogger('dummy_logger')
201
+ App = None
202
+ Exit = Exit
203
+
204
+ @classmethod
205
+ def init(cls, **kwargs):
206
+ """ set log and application (module) configuration
207
+ """
208
+ if cls.sw_init:
209
+ return
210
+ cls.sw_init = True
211
+
212
+ cls.pacmod_curr = kwargs.get('pacmod_curr')
213
+ cls.ts_start = calendar.timegm(time.gmtime())
214
+ cls.pid = os.getpid()
215
+
216
+ cls.cfg = Cfg.init(cls.pacmod_curr)
217
+ log_type = kwargs.get('log_type', 'standard')
218
+ if log_type == 'standard':
219
+ cls.Log = LogStandard.sh(**kwargs)
220
+ else:
221
+ cls.Log = LogPersonal.sh(**kwargs)
222
+ cls.App = App.sh(**kwargs)
File without changes
@@ -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'
@@ -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,15 @@
1
+ from datetime import datetime
2
+ from datetime import date
3
+
4
+ T_Date = date
5
+ TN_Date = None | T_Date
6
+ TN_Str = None | str
7
+
8
+
9
+ class Date:
10
+
11
+ @staticmethod
12
+ def sh(datestring: TN_Str, fmt: str) -> TN_Date:
13
+ if not datestring:
14
+ return None
15
+ return datetime.strptime(datestring, fmt).date()
@@ -0,0 +1,37 @@
1
+ # coding=utf-8
2
+
3
+ from typing import Any, Callable, Dict
4
+
5
+ T_Dic = Dict[Any, Any]
6
+ T_DicStr2Callable = Dict[str, Callable]
7
+
8
+ TN_Str = None | str
9
+ TN_Callable = None | Callable
10
+
11
+
12
+ class Fnc:
13
+ """ Manage Functions
14
+ """
15
+ @staticmethod
16
+ def sh(d_key2fnc: T_DicStr2Callable, key: TN_Str) -> Callable:
17
+ if not key:
18
+ msg = f"key {key} is None or empty string"
19
+ raise Exception(msg)
20
+ _fnc: TN_Callable = d_key2fnc.get(key)
21
+ if not _fnc:
22
+ msg = f"key {key} is not defined in function table {d_key2fnc}"
23
+ raise Exception(msg)
24
+ else:
25
+ return _fnc
26
+
27
+ @staticmethod
28
+ def ex(d_key2fnc: T_DicStr2Callable, key: TN_Str, kwargs: T_Dic) -> None:
29
+ if not key:
30
+ msg = f"key {key} is None or empty string"
31
+ raise Exception(msg)
32
+ _fnc: TN_Callable = d_key2fnc.get(key)
33
+ if not _fnc:
34
+ msg = f"key {key} is not defined in function table {d_key2fnc}"
35
+ raise Exception(msg)
36
+ else:
37
+ _fnc(kwargs)
@@ -0,0 +1,57 @@
1
+ # coding=utf-8
2
+
3
+ import jinja2
4
+ import os
5
+ import yaml
6
+
7
+ from typing import Any, Dict
8
+
9
+ T_Dic = Dict[Any, Any]
10
+
11
+ TN_Any = None | Any
12
+
13
+
14
+ class Yaml:
15
+
16
+ """ Manage Object to Yaml file affilitation
17
+ """
18
+ @staticmethod
19
+ def load_with_safeloader(string: str) -> None | Any:
20
+ _obj = yaml.load(string, Loader=yaml.SafeLoader)
21
+ return _obj
22
+
23
+ @staticmethod
24
+ def read(path: str) -> TN_Any:
25
+ with open(path) as fd:
26
+ # The Loader parameter handles the conversion from YAML
27
+ # scalar values to Python object format
28
+ _obj = yaml.load(fd, Loader=yaml.SafeLoader)
29
+ return _obj
30
+ return None
31
+
32
+
33
+ class Jinja2:
34
+ """ Manage Object to Json file affilitation
35
+ """
36
+ @staticmethod
37
+ def read_template(
38
+ path: str) -> Any:
39
+ dir, file = os.path.split(path)
40
+ env = jinja2.Environment(loader=jinja2.FileSystemLoader(dir))
41
+ return env.get_template(file)
42
+
43
+ @classmethod
44
+ def read(
45
+ cls, path: str, **kwargs):
46
+ try:
47
+ # read jinja template from file
48
+ template = cls.read_template(path)
49
+
50
+ # render template as yaml string
51
+ template_rendered = template.render(**kwargs)
52
+
53
+ # parse yaml string as dictionary
54
+ dic = Yaml.load_with_safeloader(template_rendered)
55
+ return dic
56
+ except Exception:
57
+ raise