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.
Files changed (43) hide show
  1. ruth_tools-2020.1.1/LICENSE.txt +15 -0
  2. ruth_tools-2020.1.1/PKG-INFO +364 -0
  3. ruth_tools-2020.1.1/README.md +336 -0
  4. ruth_tools-2020.1.1/pyproject.toml +58 -0
  5. ruth_tools-2020.1.1/setup.cfg +4 -0
  6. ruth_tools-2020.1.1/src/ruth_tools.egg-info/PKG-INFO +364 -0
  7. ruth_tools-2020.1.1/src/ruth_tools.egg-info/SOURCES.txt +41 -0
  8. ruth_tools-2020.1.1/src/ruth_tools.egg-info/dependency_links.txt +1 -0
  9. ruth_tools-2020.1.1/src/ruth_tools.egg-info/requires.txt +26 -0
  10. ruth_tools-2020.1.1/src/ruth_tools.egg-info/top_level.txt +1 -0
  11. ruth_tools-2020.1.1/src/tools/__import__.py +4 -0
  12. ruth_tools-2020.1.1/src/tools/__init__.py +1 -0
  13. ruth_tools-2020.1.1/src/tools/common/__init__.py +1 -0
  14. ruth_tools-2020.1.1/src/tools/common/v1/__init__.py +4 -0
  15. ruth_tools-2020.1.1/src/tools/common/v1/attribute_manager.py +105 -0
  16. ruth_tools-2020.1.1/src/tools/common/v1/get_location.py +30 -0
  17. ruth_tools-2020.1.1/src/tools/common/v1/hide_big_content.py +64 -0
  18. ruth_tools-2020.1.1/src/tools/common/v1/mask_password.py +42 -0
  19. ruth_tools-2020.1.1/src/tools/configurator/__init__.py +1 -0
  20. ruth_tools-2020.1.1/src/tools/configurator/v1/__init__.py +8 -0
  21. ruth_tools-2020.1.1/src/tools/configurator/v1/config.py +117 -0
  22. ruth_tools-2020.1.1/src/tools/configurator/v1/extensions.py +13 -0
  23. ruth_tools-2020.1.1/src/tools/configurator/v1/loader.py +363 -0
  24. ruth_tools-2020.1.1/src/tools/configurator/v1/loader_ignore.py +173 -0
  25. ruth_tools-2020.1.1/src/tools/configurator/v1/node.py +104 -0
  26. ruth_tools-2020.1.1/src/tools/databases/__init__.py +0 -0
  27. ruth_tools-2020.1.1/src/tools/databases/oracle/__init__.py +1 -0
  28. ruth_tools-2020.1.1/src/tools/databases/oracle/v1/__init__.py +1 -0
  29. ruth_tools-2020.1.1/src/tools/databases/oracle/v1/oracle.py +255 -0
  30. ruth_tools-2020.1.1/src/tools/logging/__init__.py +1 -0
  31. ruth_tools-2020.1.1/src/tools/logging/v1/__init__.py +5 -0
  32. ruth_tools-2020.1.1/src/tools/logging/v1/context.py +69 -0
  33. ruth_tools-2020.1.1/src/tools/logging/v1/defaults.py +62 -0
  34. ruth_tools-2020.1.1/src/tools/logging/v1/handlers.py +156 -0
  35. ruth_tools-2020.1.1/src/tools/logging/v1/logger.py +328 -0
  36. ruth_tools-2020.1.1/src/tools/logging/v1/logging.py +268 -0
  37. ruth_tools-2020.1.1/src/tools/logging/v1/types.py +74 -0
  38. ruth_tools-2020.1.1/src/tools/startup_info/__init__.py +1 -0
  39. ruth_tools-2020.1.1/src/tools/startup_info/v1/__init__.py +1 -0
  40. ruth_tools-2020.1.1/src/tools/startup_info/v1/startup_info.py +52 -0
  41. ruth_tools-2020.1.1/src/tools/tables/__init__.py +1 -0
  42. ruth_tools-2020.1.1/src/tools/tables/v1/__init__.py +1 -0
  43. 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
+