loggerric 1.0.0__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.
- loggerric-1.0.0/LICENSE +13 -0
- loggerric-1.0.0/PKG-INFO +22 -0
- loggerric-1.0.0/README.md +0 -0
- loggerric-1.0.0/loggerric/__init__.py +14 -0
- loggerric-1.0.0/loggerric/_log.py +108 -0
- loggerric-1.0.0/loggerric/_log_levels.py +10 -0
- loggerric-1.0.0/loggerric/_progress_bar.py +75 -0
- loggerric-1.0.0/loggerric/_prompt.py +42 -0
- loggerric-1.0.0/loggerric/_timer.py +44 -0
- loggerric-1.0.0/loggerric/_utils.py +5 -0
- loggerric-1.0.0/loggerric.egg-info/PKG-INFO +22 -0
- loggerric-1.0.0/loggerric.egg-info/SOURCES.txt +14 -0
- loggerric-1.0.0/loggerric.egg-info/dependency_links.txt +1 -0
- loggerric-1.0.0/loggerric.egg-info/top_level.txt +1 -0
- loggerric-1.0.0/pyproject.toml +12 -0
- loggerric-1.0.0/setup.cfg +4 -0
loggerric-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Luka Jacobsen
|
|
4
|
+
|
|
5
|
+
You are free to:
|
|
6
|
+
- Share — copy and redistribute the material in any medium or format
|
|
7
|
+
- Adapt — remix, transform, and build upon the material
|
|
8
|
+
|
|
9
|
+
Under the following terms:
|
|
10
|
+
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made.
|
|
11
|
+
- NonCommercial — You may not use the material for commercial purposes.
|
|
12
|
+
|
|
13
|
+
No additional warranties are provided.
|
loggerric-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: loggerric
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A fancy logging, progress bar, prompt, and timer utility for Python. Developed for personal use.
|
|
5
|
+
Author: Luka Jacobsen
|
|
6
|
+
License: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Luka Jacobsen
|
|
9
|
+
|
|
10
|
+
You are free to:
|
|
11
|
+
- Share — copy and redistribute the material in any medium or format
|
|
12
|
+
- Adapt — remix, transform, and build upon the material
|
|
13
|
+
|
|
14
|
+
Under the following terms:
|
|
15
|
+
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made.
|
|
16
|
+
- NonCommercial — You may not use the material for commercial purposes.
|
|
17
|
+
|
|
18
|
+
No additional warranties are provided.
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from loggerric._progress_bar import ProgressBar
|
|
2
|
+
from loggerric._log_levels import LogLevel
|
|
3
|
+
from loggerric._prompt import prompt
|
|
4
|
+
from loggerric._timer import Timer
|
|
5
|
+
from loggerric._log import Log
|
|
6
|
+
from colorama import init
|
|
7
|
+
|
|
8
|
+
# Add option to turn on feedback loop in prompt with options
|
|
9
|
+
|
|
10
|
+
# Expose these functions/classes
|
|
11
|
+
__all__ = ['LogLevel', 'prompt', 'ProgressBar', 'Log', 'Timer']
|
|
12
|
+
|
|
13
|
+
# Initialize Colorama
|
|
14
|
+
init(autoreset=True)
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from colorama import Fore
|
|
2
|
+
from loggerric._log_levels import *
|
|
3
|
+
from loggerric._utils import *
|
|
4
|
+
|
|
5
|
+
class Log:
|
|
6
|
+
"""
|
|
7
|
+
**Contains various logging methods.**
|
|
8
|
+
"""
|
|
9
|
+
# Keep track of what should be logged
|
|
10
|
+
_active_levels = { LogLevel.INFO, LogLevel.WARN, LogLevel.ERROR, LogLevel.DEBUG }
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def info(cls, content:str) -> None:
|
|
14
|
+
"""
|
|
15
|
+
**Format a message as information.**
|
|
16
|
+
|
|
17
|
+
*Parameters*:
|
|
18
|
+
- `content` (str): The content you want printed.
|
|
19
|
+
|
|
20
|
+
*Example*:
|
|
21
|
+
```python
|
|
22
|
+
Log.info(content='Hello World!')
|
|
23
|
+
```
|
|
24
|
+
"""
|
|
25
|
+
# Log the content
|
|
26
|
+
if LogLevel.INFO in cls._active_levels:
|
|
27
|
+
print(f'{Fore.MAGENTA}[{timestamp()}] {Fore.GREEN}[i] {content}{Fore.WHITE}')
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def warn(cls, content:str) -> None:
|
|
31
|
+
"""
|
|
32
|
+
**Format a message as a warning.**
|
|
33
|
+
|
|
34
|
+
*Parameters*:
|
|
35
|
+
- `content` (str): The content you want printed.
|
|
36
|
+
|
|
37
|
+
*Example*:
|
|
38
|
+
```python
|
|
39
|
+
Log.warn(content='Hello World!')
|
|
40
|
+
```
|
|
41
|
+
"""
|
|
42
|
+
# Log the content
|
|
43
|
+
if LogLevel.WARN in cls._active_levels:
|
|
44
|
+
print(f'{Fore.MAGENTA}[{timestamp()}] {Fore.YELLOW}[w] {content}{Fore.WHITE}')
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def error(cls, content:str) -> None:
|
|
48
|
+
"""
|
|
49
|
+
**Format a message as an error.**
|
|
50
|
+
|
|
51
|
+
*Parameters*:
|
|
52
|
+
- `content` (str): The content you want printed.
|
|
53
|
+
|
|
54
|
+
*Example*:
|
|
55
|
+
```python
|
|
56
|
+
Log.error(content='Hello World!')
|
|
57
|
+
```
|
|
58
|
+
"""
|
|
59
|
+
# Log the content
|
|
60
|
+
if LogLevel.ERROR in cls._active_levels:
|
|
61
|
+
print(f'{Fore.MAGENTA}[{timestamp()}] {Fore.RED}[!] {content}{Fore.WHITE}')
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def debug(cls, content:str) -> None:
|
|
65
|
+
"""
|
|
66
|
+
**Format a message as a debug message.**
|
|
67
|
+
|
|
68
|
+
*Parameters*:
|
|
69
|
+
- `content` (str): The content you want printed.
|
|
70
|
+
|
|
71
|
+
*Example*:
|
|
72
|
+
```python
|
|
73
|
+
Log.debug(content='Hello World!')
|
|
74
|
+
```
|
|
75
|
+
"""
|
|
76
|
+
# Log the content
|
|
77
|
+
if LogLevel.DEBUG in cls._active_levels:
|
|
78
|
+
print(f'{Fore.MAGENTA}[{timestamp()}] {Fore.LIGHTBLACK_EX}[?] {content}{Fore.WHITE}')
|
|
79
|
+
|
|
80
|
+
@classmethod
|
|
81
|
+
def enable(cls, *levels:LogLevel) -> None:
|
|
82
|
+
"""
|
|
83
|
+
**Enable logging methods.**
|
|
84
|
+
|
|
85
|
+
*Parameters*:
|
|
86
|
+
- `*levels` (LogLevel): Levels that should be enabled.
|
|
87
|
+
|
|
88
|
+
*Example*:
|
|
89
|
+
```python
|
|
90
|
+
Log.enable(LogLevel.INFO, LogLevel.WARN, ...)
|
|
91
|
+
```
|
|
92
|
+
"""
|
|
93
|
+
cls._active_levels.update(levels)
|
|
94
|
+
|
|
95
|
+
@classmethod
|
|
96
|
+
def disable(cls, *levels:LogLevel) -> None:
|
|
97
|
+
"""
|
|
98
|
+
**Disable logging methods.**
|
|
99
|
+
|
|
100
|
+
*Parameters*:
|
|
101
|
+
- `*levels` (LogLevel): Levels that should be disabled.
|
|
102
|
+
|
|
103
|
+
*Example*:
|
|
104
|
+
```python
|
|
105
|
+
Log.disable(LogLevel.INFO, LogLevel.WARN, ...)
|
|
106
|
+
```
|
|
107
|
+
"""
|
|
108
|
+
cls._active_levels.difference_update(levels)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from time import perf_counter
|
|
2
|
+
from colorama import Fore
|
|
3
|
+
from loggerric._utils import *
|
|
4
|
+
import math
|
|
5
|
+
|
|
6
|
+
class ProgressBar:
|
|
7
|
+
"""
|
|
8
|
+
**Push a formatted progressbar to the standard output.**
|
|
9
|
+
|
|
10
|
+
*Parameters*:
|
|
11
|
+
- `end_value` (int): The end iteration number.
|
|
12
|
+
- `name` (str): The name of the progressbar.
|
|
13
|
+
- `bar_length` (int): The length of the progressbar.
|
|
14
|
+
|
|
15
|
+
*Example*:
|
|
16
|
+
```python
|
|
17
|
+
end_val = 50
|
|
18
|
+
bar = ProgressBar(end_value=end_val, name='Progress Bar Name', bar_length=50)
|
|
19
|
+
for i in range(1, end_val + 1):
|
|
20
|
+
...
|
|
21
|
+
bar.update(i)
|
|
22
|
+
```
|
|
23
|
+
"""
|
|
24
|
+
# Dunder: Initialization
|
|
25
|
+
def __init__(self, end_value:int, name:str='Progress', bar_length:int=50):
|
|
26
|
+
# Define class scoped variables
|
|
27
|
+
self.end_value = end_value
|
|
28
|
+
self.name = name
|
|
29
|
+
self.bar_length = bar_length
|
|
30
|
+
self._end_value_digets = len(str(end_value))
|
|
31
|
+
self.start_time = 0
|
|
32
|
+
self.elapsed = 0
|
|
33
|
+
|
|
34
|
+
# Internal: Method
|
|
35
|
+
def _format_time(self, seconds:float) -> str:
|
|
36
|
+
# Convert seconds to hours, minutes and seconds
|
|
37
|
+
seconds = int(seconds)
|
|
38
|
+
h, m, s = seconds // 3600, (seconds % 3600) // 60, seconds % 60
|
|
39
|
+
|
|
40
|
+
# Format to HH:MM:SS
|
|
41
|
+
return f'{h:02d}:{m:02d}:{s:02d}'
|
|
42
|
+
|
|
43
|
+
# Method
|
|
44
|
+
def update(self, current_value:int) -> None:
|
|
45
|
+
"""
|
|
46
|
+
**Called when the progress bar needs to update.**
|
|
47
|
+
|
|
48
|
+
*Parameters*:
|
|
49
|
+
- `current_value` (int): The current value for the progress bar.
|
|
50
|
+
"""
|
|
51
|
+
# If its the first time called, log the start time
|
|
52
|
+
if not self.start_time:
|
|
53
|
+
self.start_time = perf_counter()
|
|
54
|
+
|
|
55
|
+
# String formatted division 'current/end'
|
|
56
|
+
division = f'{str(current_value).zfill(self._end_value_digets)}/{self.end_value}'
|
|
57
|
+
|
|
58
|
+
# Calculate the current progress (scaled to bar length)
|
|
59
|
+
progress = current_value * self.bar_length / self.end_value
|
|
60
|
+
|
|
61
|
+
# String formatted progress bar
|
|
62
|
+
bar = f'[{Fore.CYAN}{"#" * (math.floor(progress))}{"_" * (self.bar_length - math.floor(progress))}]'
|
|
63
|
+
|
|
64
|
+
# String formatted percentage complete
|
|
65
|
+
pct = f'{current_value * 100 / self.end_value:.2f}%'
|
|
66
|
+
|
|
67
|
+
# Calculate the ETA
|
|
68
|
+
timer = 'ETA --:--:--'
|
|
69
|
+
self.elapsed = perf_counter() - self.start_time
|
|
70
|
+
if current_value > 0:
|
|
71
|
+
remaining = (self.elapsed / current_value) * (self.end_value - current_value)
|
|
72
|
+
timer = f'ETA {self._format_time(remaining)}'
|
|
73
|
+
|
|
74
|
+
# Log the progress bar
|
|
75
|
+
print(f'{Fore.MAGENTA}[{timestamp()}] {Fore.BLUE}{self.name}: {Fore.CYAN}{division} {bar} {pct} {timer}{Fore.WHITE}', end='\n' if current_value == self.end_value else '\r')
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from colorama import Fore
|
|
2
|
+
from loggerric._utils import *
|
|
3
|
+
|
|
4
|
+
def prompt(question:str, options:list[str]=[], default:str=None) -> str | None:
|
|
5
|
+
"""
|
|
6
|
+
**Prompts standard I/O and returns the answer.**
|
|
7
|
+
|
|
8
|
+
If options are given but not chosen by the user during prompting, return value will be `None`
|
|
9
|
+
|
|
10
|
+
*Parameters*:
|
|
11
|
+
- `question` (str): The question appearing in the prompt.
|
|
12
|
+
- `options` (list[str]): Options that the user can pick from during prompting.
|
|
13
|
+
- `default` (str): If options are not `None`, optionally specify a default value.
|
|
14
|
+
|
|
15
|
+
*Example (No Options)*:
|
|
16
|
+
```python
|
|
17
|
+
answer = prompt(question='Insert your name')
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
*Example (Options)*:
|
|
21
|
+
```python
|
|
22
|
+
answer = prompt(question="What's the best?", options=['a', 'b', 'c'], default='b')
|
|
23
|
+
```
|
|
24
|
+
"""
|
|
25
|
+
# If no options ommitted prompt immediately
|
|
26
|
+
if len(options) == 0:
|
|
27
|
+
return input(f'{Fore.BLUE}{question}: {Fore.CYAN}') or None
|
|
28
|
+
|
|
29
|
+
# Format options
|
|
30
|
+
options_formatted = f'{Fore.BLUE} | '.join(Fore.YELLOW + o for o in options)
|
|
31
|
+
|
|
32
|
+
# Prompt user
|
|
33
|
+
answer = input(f'{Fore.MAGENTA}[{timestamp()}] {Fore.BLUE}{question} [ {options_formatted}{Fore.BLUE} ]{f" ({Fore.YELLOW}{default}{Fore.BLUE})" if default else ""}:{Fore.CYAN} ')
|
|
34
|
+
|
|
35
|
+
# Validate answer
|
|
36
|
+
if len(answer) == 0 and default != None:
|
|
37
|
+
return default
|
|
38
|
+
if answer in options:
|
|
39
|
+
return answer
|
|
40
|
+
|
|
41
|
+
# Implementor decides what to happen if user answers "wrong"
|
|
42
|
+
return None
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from time import perf_counter
|
|
2
|
+
from colorama import Fore
|
|
3
|
+
from loggerric._utils import *
|
|
4
|
+
|
|
5
|
+
class Timer:
|
|
6
|
+
"""
|
|
7
|
+
**Time how long a code snippet takes to execute.**
|
|
8
|
+
|
|
9
|
+
*Arguments*:
|
|
10
|
+
- `name` (str): Name of the timer.
|
|
11
|
+
|
|
12
|
+
*Example*:
|
|
13
|
+
```python
|
|
14
|
+
with Timer(name='Timer Name'):
|
|
15
|
+
...
|
|
16
|
+
```
|
|
17
|
+
"""
|
|
18
|
+
# Dunder: Initialization
|
|
19
|
+
def __init__(self, name:str='Timer'):
|
|
20
|
+
# Define class scoped variables
|
|
21
|
+
self.name = name
|
|
22
|
+
self.end_time = 0
|
|
23
|
+
self.elapsed = 0
|
|
24
|
+
|
|
25
|
+
# Dunder: Entering 'with' operator
|
|
26
|
+
def __enter__(self):
|
|
27
|
+
# Log the start time in variable, and log to STDIO
|
|
28
|
+
self.start_time = perf_counter()
|
|
29
|
+
print(f'{Fore.MAGENTA}[{timestamp()}] {Fore.BLUE}{self.name}: {Fore.CYAN}Started...{Fore.WHITE}')
|
|
30
|
+
|
|
31
|
+
# Dunder: Exiting 'with' operator
|
|
32
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
33
|
+
# Log the end time, and calculate the time elapsed
|
|
34
|
+
self.end_time = perf_counter()
|
|
35
|
+
self.elapsed = self.end_time - self.start_time
|
|
36
|
+
|
|
37
|
+
# Check if duration should be converted to milliseconds
|
|
38
|
+
is_ms = False
|
|
39
|
+
if self.elapsed < 1:
|
|
40
|
+
is_ms = True
|
|
41
|
+
self.elapsed *= 1_000
|
|
42
|
+
|
|
43
|
+
# Log the duration
|
|
44
|
+
print(f'{Fore.MAGENTA}[{timestamp()}] {Fore.BLUE}{self.name}: {Fore.CYAN}Finished... {Fore.YELLOW}{self.elapsed:,.5f} {"ms" if is_ms else "s"}{Fore.CYAN} Elapsed.{Fore.WHITE}')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: loggerric
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A fancy logging, progress bar, prompt, and timer utility for Python. Developed for personal use.
|
|
5
|
+
Author: Luka Jacobsen
|
|
6
|
+
License: Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Luka Jacobsen
|
|
9
|
+
|
|
10
|
+
You are free to:
|
|
11
|
+
- Share — copy and redistribute the material in any medium or format
|
|
12
|
+
- Adapt — remix, transform, and build upon the material
|
|
13
|
+
|
|
14
|
+
Under the following terms:
|
|
15
|
+
- Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made.
|
|
16
|
+
- NonCommercial — You may not use the material for commercial purposes.
|
|
17
|
+
|
|
18
|
+
No additional warranties are provided.
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
loggerric/__init__.py
|
|
5
|
+
loggerric/_log.py
|
|
6
|
+
loggerric/_log_levels.py
|
|
7
|
+
loggerric/_progress_bar.py
|
|
8
|
+
loggerric/_prompt.py
|
|
9
|
+
loggerric/_timer.py
|
|
10
|
+
loggerric/_utils.py
|
|
11
|
+
loggerric.egg-info/PKG-INFO
|
|
12
|
+
loggerric.egg-info/SOURCES.txt
|
|
13
|
+
loggerric.egg-info/dependency_links.txt
|
|
14
|
+
loggerric.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
loggerric
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "loggerric"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "A fancy logging, progress bar, prompt, and timer utility for Python. Developed for personal use."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
authors = [{ name="Luka Jacobsen" }]
|
|
8
|
+
license = { file="LICENSE" }
|
|
9
|
+
|
|
10
|
+
[build-system]
|
|
11
|
+
requires = ["setuptools", "wheel"]
|
|
12
|
+
build-backend = "setuptools.build_meta"
|