faultforge-cli 0.2.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.
- faultforge_cli/__init__.py +0 -0
- faultforge_cli/encoded_memory/__init__.py +9 -0
- faultforge_cli/encoded_memory/commands.py +713 -0
- faultforge_cli/encoded_memory/plots.py +395 -0
- faultforge_cli/encoded_memory/results.py +212 -0
- faultforge_cli/logging.py +122 -0
- faultforge_cli/main.py +24 -0
- faultforge_cli-0.2.0.dist-info/METADATA +21 -0
- faultforge_cli-0.2.0.dist-info/RECORD +11 -0
- faultforge_cli-0.2.0.dist-info/WHEEL +4 -0
- faultforge_cli-0.2.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from typing import override
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
_console = Console()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_log_level() -> tuple[int, bool]:
|
|
12
|
+
"""Get the log level and verbosity from environment variables."""
|
|
13
|
+
try:
|
|
14
|
+
verbose_str = os.environ["VERBOSE_LOGS"]
|
|
15
|
+
except KeyError:
|
|
16
|
+
verbose_str = ""
|
|
17
|
+
|
|
18
|
+
if verbose_str == "":
|
|
19
|
+
verbose = None
|
|
20
|
+
elif verbose_str == "0":
|
|
21
|
+
verbose = False
|
|
22
|
+
else:
|
|
23
|
+
verbose = True
|
|
24
|
+
|
|
25
|
+
levels = {
|
|
26
|
+
"debug": logging.DEBUG,
|
|
27
|
+
"info": logging.INFO,
|
|
28
|
+
"warning": logging.WARNING,
|
|
29
|
+
"error": logging.ERROR,
|
|
30
|
+
}
|
|
31
|
+
default_verbosity = {
|
|
32
|
+
logging.DEBUG: True,
|
|
33
|
+
logging.INFO: False,
|
|
34
|
+
logging.WARN: False,
|
|
35
|
+
logging.ERROR: False,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
level_str = os.environ["LOG_LEVEL"]
|
|
40
|
+
except KeyError:
|
|
41
|
+
level_str = "info"
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
level = levels[level_str.lower()]
|
|
45
|
+
except KeyError:
|
|
46
|
+
level = logging.INFO
|
|
47
|
+
print(
|
|
48
|
+
f"Warning: invalid log level `{level_str}`, expected one of: {', '.join(levels.keys())}, defaulting to info"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if verbose is None:
|
|
52
|
+
return level, default_verbosity[level]
|
|
53
|
+
else:
|
|
54
|
+
return level, verbose
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class LogFormatter(logging.Formatter):
|
|
58
|
+
"""A custom formatter for `setup_logging`."""
|
|
59
|
+
|
|
60
|
+
def __init__(self, verbose: bool = False):
|
|
61
|
+
super().__init__()
|
|
62
|
+
|
|
63
|
+
self.verbose: bool = verbose
|
|
64
|
+
|
|
65
|
+
@override
|
|
66
|
+
def format(self, record: logging.LogRecord) -> str:
|
|
67
|
+
dim_color = "dim white"
|
|
68
|
+
default_color = "white"
|
|
69
|
+
|
|
70
|
+
match record.levelno:
|
|
71
|
+
case logging.DEBUG:
|
|
72
|
+
head_color = dim_color
|
|
73
|
+
message_color = dim_color
|
|
74
|
+
name = "Debug"
|
|
75
|
+
case logging.INFO:
|
|
76
|
+
head_color = "blue"
|
|
77
|
+
message_color = default_color
|
|
78
|
+
name = "Info"
|
|
79
|
+
case logging.WARNING:
|
|
80
|
+
head_color = "yellow"
|
|
81
|
+
message_color = default_color
|
|
82
|
+
name = "Warning"
|
|
83
|
+
case logging.ERROR | logging.CRITICAL:
|
|
84
|
+
head_color = "red"
|
|
85
|
+
message_color = "red"
|
|
86
|
+
name = "Error"
|
|
87
|
+
case _:
|
|
88
|
+
print(
|
|
89
|
+
f"Unexpected log record `levelno` `{record.levelno}`, using default format",
|
|
90
|
+
file=sys.stderr,
|
|
91
|
+
)
|
|
92
|
+
return logging.Formatter().format(record)
|
|
93
|
+
|
|
94
|
+
message = f"[{head_color}]{name}[/{head_color}][{message_color}]: {record.getMessage()}[/{message_color}]"
|
|
95
|
+
|
|
96
|
+
if self.verbose:
|
|
97
|
+
message = f"{message}\n\
|
|
98
|
+
-> [{dim_color}]{record.pathname}:{record.funcName}:{record.lineno}[/{dim_color}]"
|
|
99
|
+
|
|
100
|
+
with _console.capture() as capture:
|
|
101
|
+
_console.print(
|
|
102
|
+
message,
|
|
103
|
+
end="",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
cap = capture.get()
|
|
107
|
+
return cap
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def setup_logging(logger: logging.Logger | None = None):
|
|
111
|
+
"""Configure the given logger or the root logger if None."""
|
|
112
|
+
if logger is None:
|
|
113
|
+
logger = logging.getLogger()
|
|
114
|
+
|
|
115
|
+
handler = logging.StreamHandler()
|
|
116
|
+
handler.setLevel(logging.DEBUG)
|
|
117
|
+
level, verbose = get_log_level()
|
|
118
|
+
|
|
119
|
+
handler.setFormatter(LogFormatter(verbose))
|
|
120
|
+
logger.setLevel(level)
|
|
121
|
+
|
|
122
|
+
logger.addHandler(handler)
|
faultforge_cli/main.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
|
|
3
|
+
from faultforge_cli import encoded_memory
|
|
4
|
+
from faultforge_cli.logging import setup_logging
|
|
5
|
+
|
|
6
|
+
app = typer.Typer(
|
|
7
|
+
pretty_exceptions_enable=False,
|
|
8
|
+
context_settings={"help_option_names": ["-h", "--help"]},
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
app.add_typer(
|
|
12
|
+
encoded_memory.app,
|
|
13
|
+
name="encoded-memory",
|
|
14
|
+
help="Commands for encoded memory experiments.",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main() -> None:
|
|
19
|
+
setup_logging()
|
|
20
|
+
app()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if __name__ == "__main__":
|
|
24
|
+
main()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: faultforge-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: CLI for FaultForge
|
|
5
|
+
Author: Marten Roots
|
|
6
|
+
Author-email: Marten Roots <marten.roots@gmail.com>
|
|
7
|
+
Requires-Dist: faultforge
|
|
8
|
+
Requires-Dist: matplotlib>=3.10.5
|
|
9
|
+
Requires-Dist: numpy>=2.3.1
|
|
10
|
+
Requires-Dist: typer>=0.20.0
|
|
11
|
+
Requires-Python: >=3.14
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# faultforge-cli
|
|
15
|
+
|
|
16
|
+
A `typer`-based CLI for [FaultForge](https://github.com/rezzubs/faultforge),
|
|
17
|
+
installing a `faultforge` command on top of the `faultforge` library.
|
|
18
|
+
|
|
19
|
+
See the [main repository](https://github.com/rezzubs/faultforge) for full
|
|
20
|
+
documentation, including the CLI usage covered in
|
|
21
|
+
[docs/experiments/encoded_memory.md](https://github.com/rezzubs/faultforge/blob/main/docs/experiments/encoded_memory.md).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
faultforge_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
faultforge_cli/encoded_memory/__init__.py,sha256=AjGvdXFBRJN0ZFkSHAOHy_bZuZPR_SNCes1EhrTt9yI,304
|
|
3
|
+
faultforge_cli/encoded_memory/commands.py,sha256=MHBnEym3LWAGwh57zo0vDySVqwm3dkUkcvPJJC_jx8k,24121
|
|
4
|
+
faultforge_cli/encoded_memory/plots.py,sha256=okfEWRRC-ZoAQF6S6AnMq-OwWKoxeT7a-lK970nRsbs,13924
|
|
5
|
+
faultforge_cli/encoded_memory/results.py,sha256=wF9EjkEB0T2vifUV3Xttk1i0a6NZZgmiOK0teZWROG8,8152
|
|
6
|
+
faultforge_cli/logging.py,sha256=yO91DM_KbR_kh-EhZgxpWfFZV7eRX20IUAGWwt6cecY,3302
|
|
7
|
+
faultforge_cli/main.py,sha256=N1Kvppvo0B-spPzV1UO2i4B-xOocKNiCef0-PT5hyF0,439
|
|
8
|
+
faultforge_cli-0.2.0.dist-info/WHEEL,sha256=CoDSoyhtC_eO_tlxRYzsTraPv1fPJRXFx91k6ISeAvA,81
|
|
9
|
+
faultforge_cli-0.2.0.dist-info/entry_points.txt,sha256=m_nA2rHeIsZ0HP01Ls8dt8WXmeG2E9t_0jLmIv2iBhA,57
|
|
10
|
+
faultforge_cli-0.2.0.dist-info/METADATA,sha256=Oa1Q3A69srM_oImnmUUc8okngIuQ6SdYqpnGRoY3hzM,753
|
|
11
|
+
faultforge_cli-0.2.0.dist-info/RECORD,,
|