ruth-tools 2020.1.1__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.
- ruth_tools-2020.1.1/LICENSE.txt +15 -0
- ruth_tools-2020.1.1/PKG-INFO +364 -0
- ruth_tools-2020.1.1/README.md +336 -0
- ruth_tools-2020.1.1/pyproject.toml +58 -0
- ruth_tools-2020.1.1/setup.cfg +4 -0
- ruth_tools-2020.1.1/src/ruth_tools.egg-info/PKG-INFO +364 -0
- ruth_tools-2020.1.1/src/ruth_tools.egg-info/SOURCES.txt +41 -0
- ruth_tools-2020.1.1/src/ruth_tools.egg-info/dependency_links.txt +1 -0
- ruth_tools-2020.1.1/src/ruth_tools.egg-info/requires.txt +26 -0
- ruth_tools-2020.1.1/src/ruth_tools.egg-info/top_level.txt +1 -0
- ruth_tools-2020.1.1/src/tools/__import__.py +4 -0
- ruth_tools-2020.1.1/src/tools/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/common/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/common/v1/__init__.py +4 -0
- ruth_tools-2020.1.1/src/tools/common/v1/attribute_manager.py +105 -0
- ruth_tools-2020.1.1/src/tools/common/v1/get_location.py +30 -0
- ruth_tools-2020.1.1/src/tools/common/v1/hide_big_content.py +64 -0
- ruth_tools-2020.1.1/src/tools/common/v1/mask_password.py +42 -0
- ruth_tools-2020.1.1/src/tools/configurator/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/configurator/v1/__init__.py +8 -0
- ruth_tools-2020.1.1/src/tools/configurator/v1/config.py +117 -0
- ruth_tools-2020.1.1/src/tools/configurator/v1/extensions.py +13 -0
- ruth_tools-2020.1.1/src/tools/configurator/v1/loader.py +363 -0
- ruth_tools-2020.1.1/src/tools/configurator/v1/loader_ignore.py +173 -0
- ruth_tools-2020.1.1/src/tools/configurator/v1/node.py +104 -0
- ruth_tools-2020.1.1/src/tools/databases/__init__.py +0 -0
- ruth_tools-2020.1.1/src/tools/databases/oracle/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/databases/oracle/v1/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/databases/oracle/v1/oracle.py +255 -0
- ruth_tools-2020.1.1/src/tools/logging/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/logging/v1/__init__.py +5 -0
- ruth_tools-2020.1.1/src/tools/logging/v1/context.py +69 -0
- ruth_tools-2020.1.1/src/tools/logging/v1/defaults.py +62 -0
- ruth_tools-2020.1.1/src/tools/logging/v1/handlers.py +156 -0
- ruth_tools-2020.1.1/src/tools/logging/v1/logger.py +328 -0
- ruth_tools-2020.1.1/src/tools/logging/v1/logging.py +268 -0
- ruth_tools-2020.1.1/src/tools/logging/v1/types.py +74 -0
- ruth_tools-2020.1.1/src/tools/startup_info/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/startup_info/v1/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/startup_info/v1/startup_info.py +52 -0
- ruth_tools-2020.1.1/src/tools/tables/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/tables/v1/__init__.py +1 -0
- ruth_tools-2020.1.1/src/tools/tables/v1/tables.py +130 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Copyright (c) 2025 Eyes Rutherford
|
|
2
|
+
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and distribute this software and its
|
|
6
|
+
documentation for any purpose and without fee is hereby denied, unless
|
|
7
|
+
prior written permission is obtained from the copyright holder.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
10
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
11
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
12
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
13
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
14
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
15
|
+
SOFTWARE.
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ruth-tools
|
|
3
|
+
Version: 2020.1.1
|
|
4
|
+
Summary: Python utility package
|
|
5
|
+
Author-email: Eyes Rutherford <ruth-tools@inbox.ru>
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE.txt
|
|
9
|
+
Provides-Extra: startup-info
|
|
10
|
+
Provides-Extra: common
|
|
11
|
+
Provides-Extra: configurator
|
|
12
|
+
Requires-Dist: ruth-tools[common]; extra == "configurator"
|
|
13
|
+
Requires-Dist: PyYAML>=6.0.3; extra == "configurator"
|
|
14
|
+
Provides-Extra: logging
|
|
15
|
+
Requires-Dist: ruth-tools[common]; extra == "logging"
|
|
16
|
+
Requires-Dist: ruth-tools[configurator]; extra == "logging"
|
|
17
|
+
Provides-Extra: tables
|
|
18
|
+
Requires-Dist: ruth-tools[logging]; extra == "tables"
|
|
19
|
+
Provides-Extra: databases-oracle
|
|
20
|
+
Requires-Dist: ruth-tools[configurator]; extra == "databases-oracle"
|
|
21
|
+
Requires-Dist: ruth-tools[logging]; extra == "databases-oracle"
|
|
22
|
+
Requires-Dist: ruth-tools[tables]; extra == "databases-oracle"
|
|
23
|
+
Requires-Dist: cx_Oracle>=8.3.0; extra == "databases-oracle"
|
|
24
|
+
Provides-Extra: databases
|
|
25
|
+
Requires-Dist: ruth-tools[databases-oracle]; extra == "databases"
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
from xml.etree.ElementTree import indentfrom sys import prefix
|
|
30
|
+
|
|
31
|
+
# Tools
|
|
32
|
+
Python Utility Tools Library
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Startup Info
|
|
37
|
+
This module print in stdout general info at startup.
|
|
38
|
+
Should be added at the beginning of the main program or where you need to display this information:
|
|
39
|
+
|
|
40
|
+
- [ ] examples:
|
|
41
|
+
```python
|
|
42
|
+
from tools.startup_info import startup_info
|
|
43
|
+
startup_info()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
result:
|
|
47
|
+
```cmd
|
|
48
|
+
--------------------------
|
|
49
|
+
2020-11-12 13:14:15.678901
|
|
50
|
+
User: DemoUser
|
|
51
|
+
Host: DemoUser-PC
|
|
52
|
+
OS Platform: Windows-10-10.0.19020-SP0
|
|
53
|
+
Python Version: 3.11.2 (tags/v3.11.2:bffe2c1, Jan 08 2020, 10:12:11) [MSC v.1936 64 bit (AMD64)]
|
|
54
|
+
Implementation: CPython
|
|
55
|
+
-----------------------
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Common
|
|
63
|
+
This module contains tools for general use.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
##### Attribute Manager
|
|
67
|
+
This class contains methods for managing class attributes taking in consideration real mangled name of each attribute.
|
|
68
|
+
|
|
69
|
+
- [ ] examples:
|
|
70
|
+
```python
|
|
71
|
+
from tools.common import AttributeManager
|
|
72
|
+
|
|
73
|
+
class SomeClass:
|
|
74
|
+
__slots__ = ('__private_attr', '_protected_attr', 'public_attr')
|
|
75
|
+
...
|
|
76
|
+
def as_static(self, attr_name: str):
|
|
77
|
+
mangled_name = AttributeManager.get_name(obj=self, attr=attr_name)
|
|
78
|
+
print(f'attribute_mangled_name: {mangled_name}')
|
|
79
|
+
#
|
|
80
|
+
found = AttributeManager.has_attribute(obj=self, attr=attr_name)
|
|
81
|
+
print(f'found: {found}')
|
|
82
|
+
#
|
|
83
|
+
if not found:
|
|
84
|
+
AttributeManager.set_attribute(obj=self, attr=attr_name, value=None)
|
|
85
|
+
#
|
|
86
|
+
value = AttributeManager.get_attribute(obj=self, attr=attr_name)
|
|
87
|
+
print(f'value: {value}')
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
def as_instance(self, attr_name: str):
|
|
91
|
+
attr = AttributeManager(obj=self, attr=attr_name)
|
|
92
|
+
#
|
|
93
|
+
mangled_name = attr.name
|
|
94
|
+
print(f'attribute_mangled_name: {mangled_name}')
|
|
95
|
+
#
|
|
96
|
+
found = attr.exists
|
|
97
|
+
print(f'found: {found}')
|
|
98
|
+
#
|
|
99
|
+
if not found:
|
|
100
|
+
attr.value = None
|
|
101
|
+
#
|
|
102
|
+
value = attr.value
|
|
103
|
+
print(f'value: {value}')
|
|
104
|
+
pass
|
|
105
|
+
...
|
|
106
|
+
pass
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
##### Hide Big Content
|
|
111
|
+
This method tries to hide big content over a limit of characters.
|
|
112
|
+
|
|
113
|
+
- [ ] examples:
|
|
114
|
+
```python
|
|
115
|
+
from tools.common import hide_big_content
|
|
116
|
+
|
|
117
|
+
content = {
|
|
118
|
+
'key': 'value',
|
|
119
|
+
'l': [1, 'a', 'b'],
|
|
120
|
+
's': 'aaa',
|
|
121
|
+
't': (1, 2, 'a' * 5000)
|
|
122
|
+
}
|
|
123
|
+
print(f'content: {content}')
|
|
124
|
+
processed = hide_big_content(value=content)
|
|
125
|
+
print(f'processed: {processed}')
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
##### Mask password
|
|
130
|
+
This method tries to mask passwords from provided object.
|
|
131
|
+
|
|
132
|
+
- [ ] examples:
|
|
133
|
+
```python
|
|
134
|
+
from tools.common import mask_password
|
|
135
|
+
|
|
136
|
+
content = [
|
|
137
|
+
1, 2, True,
|
|
138
|
+
{
|
|
139
|
+
'password': '12345',
|
|
140
|
+
'pwd': 'x56',
|
|
141
|
+
'pwd_lst': ['123', '345', '567']
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
print(f'content: {content}')
|
|
145
|
+
processed = mask_password(value=content)
|
|
146
|
+
print(f'processed: {processed}')
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
##### Get Location
|
|
151
|
+
Try to resolve file / method location. Can be used for template relative location
|
|
152
|
+
|
|
153
|
+
- [ ] examples:
|
|
154
|
+
```python
|
|
155
|
+
from tools.common import get_location
|
|
156
|
+
|
|
157
|
+
def func(): pass
|
|
158
|
+
|
|
159
|
+
func_location = get_location(func=func)
|
|
160
|
+
print(f'func_location: {func_location}')
|
|
161
|
+
|
|
162
|
+
file_location = get_location(file=__file__)
|
|
163
|
+
print(f'file_location: {file_location}')
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
### Configurator
|
|
171
|
+
This module try to get all application configurations from files and system environment and stores it as a global object to be used later.
|
|
172
|
+
Should be called at the beginning of main program.
|
|
173
|
+
|
|
174
|
+
- [ ] examples:
|
|
175
|
+
|
|
176
|
+
load config:
|
|
177
|
+
```python
|
|
178
|
+
from tools.configurator import Config, ConfigNode, ConfigLoader, ConfigLoaderIgnore
|
|
179
|
+
Config.load(
|
|
180
|
+
config=ConfigNode(
|
|
181
|
+
config=ConfigLoader(
|
|
182
|
+
path='../configs_folder', # config files path
|
|
183
|
+
paths=[ # or list of paths
|
|
184
|
+
'./configs_folder_1',
|
|
185
|
+
'./configs_folder_2'
|
|
186
|
+
],
|
|
187
|
+
env_prefix='env_prefix',
|
|
188
|
+
env_separator='::',
|
|
189
|
+
ignore=ConfigLoaderIgnore( # files / paths / env-vars to be ignored
|
|
190
|
+
file='test.py', # file name
|
|
191
|
+
files=['test_1.py', 'test_2.py'], # or list of file names
|
|
192
|
+
file_mask='test*', # file name mask
|
|
193
|
+
file_masks=['templ-*', 'template-*'] # or list of file name masks
|
|
194
|
+
),
|
|
195
|
+
extension='py', # file extension
|
|
196
|
+
extensions=['json', 'yaml'], # or list of file extensions
|
|
197
|
+
order=['env', 'json', 'yaml'] # loading config file order, Last Loaded value overrides Existing value for the same key
|
|
198
|
+
).config,
|
|
199
|
+
read_only=True # safe loading, forbid config changes after loading
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
```
|
|
203
|
+
config parameter use:
|
|
204
|
+
```python
|
|
205
|
+
from tools.configurator import Config
|
|
206
|
+
|
|
207
|
+
print(f'param: {Config.param_group.param_subgroup.param_name}')
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
### Logging
|
|
215
|
+
This module injects into method a logger object and try to inspect and log input parameters and method result and/or error in a pretty way as a hierarchical tree of calls.
|
|
216
|
+
Can be used both for sync and async methods.
|
|
217
|
+
|
|
218
|
+
- [ ] examples:
|
|
219
|
+
```python
|
|
220
|
+
from tools.logging import Logger, LogTypes, Console, File, LogContext, logging
|
|
221
|
+
|
|
222
|
+
logger = Logger(
|
|
223
|
+
type=[
|
|
224
|
+
LogTypes.debug,
|
|
225
|
+
LogTypes.info,
|
|
226
|
+
LogTypes.warning,
|
|
227
|
+
LogTypes.error
|
|
228
|
+
],
|
|
229
|
+
outputs=(
|
|
230
|
+
Console(
|
|
231
|
+
enabled=True
|
|
232
|
+
),
|
|
233
|
+
File(
|
|
234
|
+
enabled=True,
|
|
235
|
+
path='./logs',
|
|
236
|
+
name='log.ext'
|
|
237
|
+
)
|
|
238
|
+
)
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
# as global logger ----
|
|
242
|
+
from tools.configurator import Config, ConfigNode
|
|
243
|
+
# config load
|
|
244
|
+
Config.globals = ConfigNode()
|
|
245
|
+
Config.globals.logger = logger
|
|
246
|
+
|
|
247
|
+
# as logging context ----
|
|
248
|
+
from tools.logging import LogContext
|
|
249
|
+
log_ctx_token = LogContext.set(logger=logger)
|
|
250
|
+
# some code
|
|
251
|
+
# at the end
|
|
252
|
+
LogContext.reset(token=log_ctx_token)
|
|
253
|
+
```
|
|
254
|
+
use for logs:
|
|
255
|
+
```python
|
|
256
|
+
from tools.logging import logging
|
|
257
|
+
|
|
258
|
+
@logging(prefix=__name__)
|
|
259
|
+
def some_method():
|
|
260
|
+
some_method.logger.debug(
|
|
261
|
+
obj='some debug info',
|
|
262
|
+
prefix='!!! > ', # object prefix if needed
|
|
263
|
+
date_: True, # add date before log message
|
|
264
|
+
indent: True, # all logs from begin of start row or as hierarchy tree
|
|
265
|
+
end_line: 1 # 0 - no end of line
|
|
266
|
+
)
|
|
267
|
+
# method logic here
|
|
268
|
+
pass
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
### Tables
|
|
276
|
+
This module was created to store data as a table, with data / column validation and filtering.
|
|
277
|
+
Cells can be accessed by index or by key.
|
|
278
|
+
|
|
279
|
+
- [ ] examples:
|
|
280
|
+
```python
|
|
281
|
+
from tools.tables import Table
|
|
282
|
+
|
|
283
|
+
table = Table(
|
|
284
|
+
table={
|
|
285
|
+
'columns': ['col-1', 'col-2'],
|
|
286
|
+
'data': [
|
|
287
|
+
# row-1
|
|
288
|
+
{'col-1': 1, 'col-2': 2},
|
|
289
|
+
# row-2
|
|
290
|
+
{'col-1': True, 'col-2': 'str'}
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
)
|
|
294
|
+
print(f'table: {table}')
|
|
295
|
+
|
|
296
|
+
filtered_1 = table.filter(exclude=('col-1',))
|
|
297
|
+
print(f'filtered_1: {filtered_1}')
|
|
298
|
+
|
|
299
|
+
filtered_2 = table.filter(include=('col-2',))
|
|
300
|
+
print(f'filtered_2: {filtered_2}')
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
### Databases
|
|
308
|
+
This module was created to easily access different databases.
|
|
309
|
+
Now it supports only Oracle connection, other DBs will be added in future versions.
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
##### Oracle
|
|
313
|
+
|
|
314
|
+
- [ ] examples:
|
|
315
|
+
```python
|
|
316
|
+
from tools.databases.oracle import Oracle
|
|
317
|
+
|
|
318
|
+
conn = Oracle(db='tns', username='user', password='pwd')
|
|
319
|
+
|
|
320
|
+
# query
|
|
321
|
+
query = conn.sql(
|
|
322
|
+
stmt='''
|
|
323
|
+
select :test
|
|
324
|
+
from DUAL d
|
|
325
|
+
''',
|
|
326
|
+
params={
|
|
327
|
+
'test': 123
|
|
328
|
+
}
|
|
329
|
+
)
|
|
330
|
+
print(f'query: {query}')
|
|
331
|
+
|
|
332
|
+
dml = conn.sql(
|
|
333
|
+
stmt='''
|
|
334
|
+
delete
|
|
335
|
+
from TABLE_NAME tn
|
|
336
|
+
where tn.ID > :id
|
|
337
|
+
''',
|
|
338
|
+
params={
|
|
339
|
+
'id': 1234
|
|
340
|
+
}
|
|
341
|
+
)
|
|
342
|
+
print(f'dml: {dml}')
|
|
343
|
+
|
|
344
|
+
plsql = conn.plsql(
|
|
345
|
+
stmt='''
|
|
346
|
+
begin
|
|
347
|
+
:val2 := :val1 + 5;
|
|
348
|
+
:val4 := :val4 + :val2;
|
|
349
|
+
end;
|
|
350
|
+
''',
|
|
351
|
+
params={
|
|
352
|
+
'val1': 10,
|
|
353
|
+
'val4': 3
|
|
354
|
+
},
|
|
355
|
+
params_out={
|
|
356
|
+
'val2': int,
|
|
357
|
+
'val4': int
|
|
358
|
+
}
|
|
359
|
+
)
|
|
360
|
+
print(f'plsql: {plsql}')
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
from xml.etree.ElementTree import indentfrom sys import prefix
|
|
2
|
+
|
|
3
|
+
# Tools
|
|
4
|
+
Python Utility Tools Library
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## Startup Info
|
|
9
|
+
This module print in stdout general info at startup.
|
|
10
|
+
Should be added at the beginning of the main program or where you need to display this information:
|
|
11
|
+
|
|
12
|
+
- [ ] examples:
|
|
13
|
+
```python
|
|
14
|
+
from tools.startup_info import startup_info
|
|
15
|
+
startup_info()
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
result:
|
|
19
|
+
```cmd
|
|
20
|
+
--------------------------
|
|
21
|
+
2020-11-12 13:14:15.678901
|
|
22
|
+
User: DemoUser
|
|
23
|
+
Host: DemoUser-PC
|
|
24
|
+
OS Platform: Windows-10-10.0.19020-SP0
|
|
25
|
+
Python Version: 3.11.2 (tags/v3.11.2:bffe2c1, Jan 08 2020, 10:12:11) [MSC v.1936 64 bit (AMD64)]
|
|
26
|
+
Implementation: CPython
|
|
27
|
+
-----------------------
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### Common
|
|
35
|
+
This module contains tools for general use.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
##### Attribute Manager
|
|
39
|
+
This class contains methods for managing class attributes taking in consideration real mangled name of each attribute.
|
|
40
|
+
|
|
41
|
+
- [ ] examples:
|
|
42
|
+
```python
|
|
43
|
+
from tools.common import AttributeManager
|
|
44
|
+
|
|
45
|
+
class SomeClass:
|
|
46
|
+
__slots__ = ('__private_attr', '_protected_attr', 'public_attr')
|
|
47
|
+
...
|
|
48
|
+
def as_static(self, attr_name: str):
|
|
49
|
+
mangled_name = AttributeManager.get_name(obj=self, attr=attr_name)
|
|
50
|
+
print(f'attribute_mangled_name: {mangled_name}')
|
|
51
|
+
#
|
|
52
|
+
found = AttributeManager.has_attribute(obj=self, attr=attr_name)
|
|
53
|
+
print(f'found: {found}')
|
|
54
|
+
#
|
|
55
|
+
if not found:
|
|
56
|
+
AttributeManager.set_attribute(obj=self, attr=attr_name, value=None)
|
|
57
|
+
#
|
|
58
|
+
value = AttributeManager.get_attribute(obj=self, attr=attr_name)
|
|
59
|
+
print(f'value: {value}')
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
def as_instance(self, attr_name: str):
|
|
63
|
+
attr = AttributeManager(obj=self, attr=attr_name)
|
|
64
|
+
#
|
|
65
|
+
mangled_name = attr.name
|
|
66
|
+
print(f'attribute_mangled_name: {mangled_name}')
|
|
67
|
+
#
|
|
68
|
+
found = attr.exists
|
|
69
|
+
print(f'found: {found}')
|
|
70
|
+
#
|
|
71
|
+
if not found:
|
|
72
|
+
attr.value = None
|
|
73
|
+
#
|
|
74
|
+
value = attr.value
|
|
75
|
+
print(f'value: {value}')
|
|
76
|
+
pass
|
|
77
|
+
...
|
|
78
|
+
pass
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
##### Hide Big Content
|
|
83
|
+
This method tries to hide big content over a limit of characters.
|
|
84
|
+
|
|
85
|
+
- [ ] examples:
|
|
86
|
+
```python
|
|
87
|
+
from tools.common import hide_big_content
|
|
88
|
+
|
|
89
|
+
content = {
|
|
90
|
+
'key': 'value',
|
|
91
|
+
'l': [1, 'a', 'b'],
|
|
92
|
+
's': 'aaa',
|
|
93
|
+
't': (1, 2, 'a' * 5000)
|
|
94
|
+
}
|
|
95
|
+
print(f'content: {content}')
|
|
96
|
+
processed = hide_big_content(value=content)
|
|
97
|
+
print(f'processed: {processed}')
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
##### Mask password
|
|
102
|
+
This method tries to mask passwords from provided object.
|
|
103
|
+
|
|
104
|
+
- [ ] examples:
|
|
105
|
+
```python
|
|
106
|
+
from tools.common import mask_password
|
|
107
|
+
|
|
108
|
+
content = [
|
|
109
|
+
1, 2, True,
|
|
110
|
+
{
|
|
111
|
+
'password': '12345',
|
|
112
|
+
'pwd': 'x56',
|
|
113
|
+
'pwd_lst': ['123', '345', '567']
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
print(f'content: {content}')
|
|
117
|
+
processed = mask_password(value=content)
|
|
118
|
+
print(f'processed: {processed}')
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
##### Get Location
|
|
123
|
+
Try to resolve file / method location. Can be used for template relative location
|
|
124
|
+
|
|
125
|
+
- [ ] examples:
|
|
126
|
+
```python
|
|
127
|
+
from tools.common import get_location
|
|
128
|
+
|
|
129
|
+
def func(): pass
|
|
130
|
+
|
|
131
|
+
func_location = get_location(func=func)
|
|
132
|
+
print(f'func_location: {func_location}')
|
|
133
|
+
|
|
134
|
+
file_location = get_location(file=__file__)
|
|
135
|
+
print(f'file_location: {file_location}')
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
### Configurator
|
|
143
|
+
This module try to get all application configurations from files and system environment and stores it as a global object to be used later.
|
|
144
|
+
Should be called at the beginning of main program.
|
|
145
|
+
|
|
146
|
+
- [ ] examples:
|
|
147
|
+
|
|
148
|
+
load config:
|
|
149
|
+
```python
|
|
150
|
+
from tools.configurator import Config, ConfigNode, ConfigLoader, ConfigLoaderIgnore
|
|
151
|
+
Config.load(
|
|
152
|
+
config=ConfigNode(
|
|
153
|
+
config=ConfigLoader(
|
|
154
|
+
path='../configs_folder', # config files path
|
|
155
|
+
paths=[ # or list of paths
|
|
156
|
+
'./configs_folder_1',
|
|
157
|
+
'./configs_folder_2'
|
|
158
|
+
],
|
|
159
|
+
env_prefix='env_prefix',
|
|
160
|
+
env_separator='::',
|
|
161
|
+
ignore=ConfigLoaderIgnore( # files / paths / env-vars to be ignored
|
|
162
|
+
file='test.py', # file name
|
|
163
|
+
files=['test_1.py', 'test_2.py'], # or list of file names
|
|
164
|
+
file_mask='test*', # file name mask
|
|
165
|
+
file_masks=['templ-*', 'template-*'] # or list of file name masks
|
|
166
|
+
),
|
|
167
|
+
extension='py', # file extension
|
|
168
|
+
extensions=['json', 'yaml'], # or list of file extensions
|
|
169
|
+
order=['env', 'json', 'yaml'] # loading config file order, Last Loaded value overrides Existing value for the same key
|
|
170
|
+
).config,
|
|
171
|
+
read_only=True # safe loading, forbid config changes after loading
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
```
|
|
175
|
+
config parameter use:
|
|
176
|
+
```python
|
|
177
|
+
from tools.configurator import Config
|
|
178
|
+
|
|
179
|
+
print(f'param: {Config.param_group.param_subgroup.param_name}')
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
### Logging
|
|
187
|
+
This module injects into method a logger object and try to inspect and log input parameters and method result and/or error in a pretty way as a hierarchical tree of calls.
|
|
188
|
+
Can be used both for sync and async methods.
|
|
189
|
+
|
|
190
|
+
- [ ] examples:
|
|
191
|
+
```python
|
|
192
|
+
from tools.logging import Logger, LogTypes, Console, File, LogContext, logging
|
|
193
|
+
|
|
194
|
+
logger = Logger(
|
|
195
|
+
type=[
|
|
196
|
+
LogTypes.debug,
|
|
197
|
+
LogTypes.info,
|
|
198
|
+
LogTypes.warning,
|
|
199
|
+
LogTypes.error
|
|
200
|
+
],
|
|
201
|
+
outputs=(
|
|
202
|
+
Console(
|
|
203
|
+
enabled=True
|
|
204
|
+
),
|
|
205
|
+
File(
|
|
206
|
+
enabled=True,
|
|
207
|
+
path='./logs',
|
|
208
|
+
name='log.ext'
|
|
209
|
+
)
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# as global logger ----
|
|
214
|
+
from tools.configurator import Config, ConfigNode
|
|
215
|
+
# config load
|
|
216
|
+
Config.globals = ConfigNode()
|
|
217
|
+
Config.globals.logger = logger
|
|
218
|
+
|
|
219
|
+
# as logging context ----
|
|
220
|
+
from tools.logging import LogContext
|
|
221
|
+
log_ctx_token = LogContext.set(logger=logger)
|
|
222
|
+
# some code
|
|
223
|
+
# at the end
|
|
224
|
+
LogContext.reset(token=log_ctx_token)
|
|
225
|
+
```
|
|
226
|
+
use for logs:
|
|
227
|
+
```python
|
|
228
|
+
from tools.logging import logging
|
|
229
|
+
|
|
230
|
+
@logging(prefix=__name__)
|
|
231
|
+
def some_method():
|
|
232
|
+
some_method.logger.debug(
|
|
233
|
+
obj='some debug info',
|
|
234
|
+
prefix='!!! > ', # object prefix if needed
|
|
235
|
+
date_: True, # add date before log message
|
|
236
|
+
indent: True, # all logs from begin of start row or as hierarchy tree
|
|
237
|
+
end_line: 1 # 0 - no end of line
|
|
238
|
+
)
|
|
239
|
+
# method logic here
|
|
240
|
+
pass
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
### Tables
|
|
248
|
+
This module was created to store data as a table, with data / column validation and filtering.
|
|
249
|
+
Cells can be accessed by index or by key.
|
|
250
|
+
|
|
251
|
+
- [ ] examples:
|
|
252
|
+
```python
|
|
253
|
+
from tools.tables import Table
|
|
254
|
+
|
|
255
|
+
table = Table(
|
|
256
|
+
table={
|
|
257
|
+
'columns': ['col-1', 'col-2'],
|
|
258
|
+
'data': [
|
|
259
|
+
# row-1
|
|
260
|
+
{'col-1': 1, 'col-2': 2},
|
|
261
|
+
# row-2
|
|
262
|
+
{'col-1': True, 'col-2': 'str'}
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
)
|
|
266
|
+
print(f'table: {table}')
|
|
267
|
+
|
|
268
|
+
filtered_1 = table.filter(exclude=('col-1',))
|
|
269
|
+
print(f'filtered_1: {filtered_1}')
|
|
270
|
+
|
|
271
|
+
filtered_2 = table.filter(include=('col-2',))
|
|
272
|
+
print(f'filtered_2: {filtered_2}')
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
### Databases
|
|
280
|
+
This module was created to easily access different databases.
|
|
281
|
+
Now it supports only Oracle connection, other DBs will be added in future versions.
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
##### Oracle
|
|
285
|
+
|
|
286
|
+
- [ ] examples:
|
|
287
|
+
```python
|
|
288
|
+
from tools.databases.oracle import Oracle
|
|
289
|
+
|
|
290
|
+
conn = Oracle(db='tns', username='user', password='pwd')
|
|
291
|
+
|
|
292
|
+
# query
|
|
293
|
+
query = conn.sql(
|
|
294
|
+
stmt='''
|
|
295
|
+
select :test
|
|
296
|
+
from DUAL d
|
|
297
|
+
''',
|
|
298
|
+
params={
|
|
299
|
+
'test': 123
|
|
300
|
+
}
|
|
301
|
+
)
|
|
302
|
+
print(f'query: {query}')
|
|
303
|
+
|
|
304
|
+
dml = conn.sql(
|
|
305
|
+
stmt='''
|
|
306
|
+
delete
|
|
307
|
+
from TABLE_NAME tn
|
|
308
|
+
where tn.ID > :id
|
|
309
|
+
''',
|
|
310
|
+
params={
|
|
311
|
+
'id': 1234
|
|
312
|
+
}
|
|
313
|
+
)
|
|
314
|
+
print(f'dml: {dml}')
|
|
315
|
+
|
|
316
|
+
plsql = conn.plsql(
|
|
317
|
+
stmt='''
|
|
318
|
+
begin
|
|
319
|
+
:val2 := :val1 + 5;
|
|
320
|
+
:val4 := :val4 + :val2;
|
|
321
|
+
end;
|
|
322
|
+
''',
|
|
323
|
+
params={
|
|
324
|
+
'val1': 10,
|
|
325
|
+
'val4': 3
|
|
326
|
+
},
|
|
327
|
+
params_out={
|
|
328
|
+
'val2': int,
|
|
329
|
+
'val4': int
|
|
330
|
+
}
|
|
331
|
+
)
|
|
332
|
+
print(f'plsql: {plsql}')
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|