steely 0.1.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.
steely/__init__.py ADDED
File without changes
@@ -0,0 +1,40 @@
1
+ import asyncio
2
+ import inspect
3
+ from datetime import datetime
4
+ from functools import wraps
5
+
6
+ from steely.logger import Logger
7
+
8
+
9
+ def cronos(func):
10
+ log = Logger('*-cronos-*', func.__name__).log
11
+
12
+ if asyncio.iscoroutinefunction(func):
13
+ @wraps(func)
14
+ async def async_wrapper(*args, **kwargs):
15
+ start = datetime.now()
16
+ try:
17
+ res = await func(*args, **kwargs)
18
+ finally:
19
+ time_elapsed = datetime.now() - start
20
+ log('TEST-RESULT', f'Total Time Elapsed: {time_elapsed}')
21
+ return res
22
+
23
+ # Preserve the original signature for FastAPI
24
+ async_wrapper.__signature__ = inspect.signature(func)
25
+ return async_wrapper
26
+ else:
27
+ @wraps(func)
28
+ def sync_wrapper(*args, **kwargs):
29
+
30
+ start = datetime.now()
31
+ try:
32
+ res = func(*args, **kwargs)
33
+ finally:
34
+ time_elapsed = datetime.now() - start
35
+ log('TEST-RESULT', f'Total Time Elapsed: {time_elapsed}')
36
+ return res
37
+
38
+ # Preserve the original signature for FastAPI
39
+ sync_wrapper.__signature__ = inspect.signature(func)
40
+ return sync_wrapper
@@ -0,0 +1,40 @@
1
+ class UnicodeColors:
2
+ header = '\033[95m'
3
+ success_blue = '\033[94m'
4
+ success_cyan = '\033[96m'
5
+ success = '\033[92m'
6
+ alert = '\033[93m'
7
+ fail = '\033[91m'
8
+ endc = '\033[0m'
9
+ bold = '\033[1m'
10
+ underline = '\033[4m'
11
+ reset = '\033[0m'
12
+
13
+ # Basic Rainbow Colors
14
+ black = '\033[30m'
15
+ red = '\033[31m'
16
+ green = '\033[32m'
17
+ yellow = '\033[33m'
18
+ blue = '\033[34m'
19
+ purple = '\033[35m'
20
+ cyan = '\033[36m'
21
+ white = '\033[37m'
22
+ orange = '\033[38;5;208m'
23
+ pink = '\033[38;5;206m'
24
+ teal = '\033[38;5;39m'
25
+ brown = '\033[38;5;130m'
26
+ lavender = '\033[38;5;183m'
27
+ indigo = '\033[38;5;62m'
28
+ maroon = '\033[38;5;52m'
29
+ olive = '\033[38;5;100m'
30
+ steel_blue = '\033[38;5;67m'
31
+
32
+ # Bright Rainbow Colors
33
+ bright_black = '\033[90m'
34
+ bright_red = '\033[91m'
35
+ bright_green = '\033[92m'
36
+ bright_yellow = '\033[93m'
37
+ bright_blue = '\033[94m'
38
+ bright_purple = '\033[95m'
39
+ bright_cyan = '\033[96m'
40
+ bright_white = '\033[97m'
@@ -0,0 +1,142 @@
1
+ import multiprocessing
2
+ import os
3
+ import threading
4
+ from time import sleep
5
+ from datetime import datetime
6
+ from steely.design import UnicodeColors
7
+
8
+
9
+ def relative(path):
10
+ return os.path.join(os.path.dirname(__file__), path)
11
+
12
+
13
+ class Logger:
14
+ clean = False
15
+ master_clean = False
16
+ environment = None
17
+ log_path = None
18
+
19
+ def __init__(self, app_name: str, owner: str, destination: str = None, debug: bool = True, clean: bool = False, **kwargs):
20
+
21
+ self.kwargs = kwargs
22
+
23
+ if clean:
24
+ self.master_clean = True
25
+
26
+ if app_name is None:
27
+ self.app_name_upper = 'YOUR-APP-NAME-GOES-HERE'
28
+ else:
29
+ self.app_name_upper = str(app_name).upper()
30
+
31
+ self.path = destination
32
+ self.debug = debug
33
+ self.owner = owner
34
+
35
+ if debug:
36
+ self.environment = "debug"
37
+
38
+ @staticmethod
39
+ def _subprocess_log(logger, level: str, message, app_name: str = None, clean: bool = False, supress: bool = False, debug: bool = True, self_debug: bool = True, **kwargs):
40
+ """
41
+
42
+ Args:
43
+ level:
44
+ message:
45
+ app_name:
46
+ clean:
47
+ supress:
48
+ **kwargs:
49
+
50
+ Returns:
51
+ """
52
+
53
+ def generate_log_path():
54
+ # Initialize base directory path
55
+ if logger.environment is not None and logger.path is not None:
56
+ try:
57
+ base_dir = f"{logger.path}_{logger.environment}"
58
+ except TypeError:
59
+ base_dir = os.path.join('.', f"log_{logger.environment}")
60
+ else:
61
+ base_dir = str(logger.path) if logger.path is not None else '.'
62
+
63
+ # Ensure base_dir is treated as a directory
64
+ try:
65
+ os.makedirs(base_dir, exist_ok=True)
66
+ except Exception:
67
+ pass
68
+
69
+ # Construct filename and full path
70
+ filename = datetime.now().strftime('%d-%m-%Y') + ".log"
71
+ full_path = os.path.join(base_dir, filename)
72
+
73
+ return full_path
74
+
75
+ if logger.clean:
76
+ os.system('cls' if os.name == 'nt' else 'clear')
77
+ if not logger.master_clean:
78
+ logger.clean = False
79
+
80
+ timestamp = datetime.now().strftime("%d-%m-%Y %H:%M:%S")
81
+ level = level.upper()
82
+ owner = logger.owner.upper()
83
+ correspondent_clr = UnicodeColors.reset
84
+ _current_app = logger.app_name_upper
85
+
86
+ if app_name is not None:
87
+ _current_app = str(app_name).upper()
88
+
89
+ try:
90
+ del kwargs["suppress"]
91
+ except: pass
92
+
93
+ message_enclouser = timestamp + f" - [{_current_app}]" + f" [{owner}]" + ' ' + ' '.join(
94
+ [f'[{str(item).upper()}]' for item in [*logger.kwargs.values()]]) + ' '.join(
95
+ [f'[{str(item).upper()}]' for item in [*kwargs.values()]]) + f" [{level}]"
96
+
97
+ content = f"\n{message_enclouser.replace(' ', ' ')}: {str(message)}"
98
+
99
+ if logger.path is not None:
100
+ with open(generate_log_path(), 'a+') as f:
101
+ f.write(str(content))
102
+
103
+ if level == 'INFO' or level == 'START':
104
+ correspondent_clr = UnicodeColors.success_cyan
105
+ elif level == 'WARNING' or level == 'ALERT':
106
+ correspondent_clr = UnicodeColors.alert
107
+ elif level == 'SUCCESS' or level == 'OK':
108
+ correspondent_clr = UnicodeColors.success
109
+ elif level in ['CRITICAL', 'ERROR', 'FAULT', 'FAIL', 'FATAL']:
110
+ correspondent_clr = UnicodeColors.fail
111
+
112
+ if not supress or debug or self_debug:
113
+ print(correspondent_clr, content[1:], UnicodeColors.reset)
114
+ if clean:
115
+ logger.clean = True
116
+
117
+ return content
118
+
119
+ def log(self, level: str, message, app_name: str = None, clean: bool = False, supress: bool = False, debug: bool = True, **kwargs) -> bool:
120
+ """
121
+
122
+ Args:
123
+ level:
124
+ message:
125
+ app_name:
126
+ clean:
127
+ supress:
128
+ **kwargs:
129
+
130
+ Returns:
131
+
132
+ """
133
+ thread = threading.Thread(target=self._subprocess_log, kwargs={
134
+ "logger": self, "level": level, "message": message, "app_name": app_name, "clean": clean, "suppress": supress, "debug": debug, "self_debug": self.debug, **kwargs
135
+ })
136
+ thread.start()
137
+
138
+ #self._subprocess_log(self, level, message, app_name=app_name, clean=clean, supress=supress, debug=debug, self_debug=self.debug, **kwargs)
139
+ return True
140
+
141
+ def __call__(self, *args, **kwargs):
142
+ self.log(*args, **kwargs)
@@ -0,0 +1,16 @@
1
+ Metadata-Version: 2.4
2
+ Name: steely
3
+ Version: 0.1.0
4
+ Home-page: https://github.com/tomneto
5
+ Author: Steely Tools - Tom Neto
6
+ Author-email: info@tomneto.com
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: setuptools>=80.9.0
11
+ Dynamic: author
12
+ Dynamic: author-email
13
+ Dynamic: home-page
14
+ Dynamic: license-file
15
+
16
+ # steely
@@ -0,0 +1,9 @@
1
+ steely/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ steely/cronos/__init__.py,sha256=1TLh-Au8lnGa03Z67Hc_WSvRpS_KAGowgHqVVUEP7pM,1213
3
+ steely/design/__init__.py,sha256=ZGDofNmDBjzrb1IjIyIc1Rx7Dtuh9ygCp07RqPnGShY,1008
4
+ steely/logger/__init__.py,sha256=duhyC3tNdAHnNS8RILMOLzRi_D8jbi59wbG0o1UirTo,3808
5
+ steely-0.1.0.dist-info/licenses/LICENSE,sha256=1sjyhGAJNbAi7H5zVecDmOz5H2-IQ5MmuG2AntrRYJo,1079
6
+ steely-0.1.0.dist-info/METADATA,sha256=S2TkkdraSoD046uI0pnGt5awCG7aDtc6ybTVQ3jVP2Q,359
7
+ steely-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ steely-0.1.0.dist-info/top_level.txt,sha256=TvRET2hX3rZpdhqmNHmYFcxz-cR4QmnfqeH5lQayb9Q,7
9
+ steely-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Antonio Andrietti Neto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ steely