arin-log 0.2.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.
arin_log-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marcus Aurelius
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,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: arin-log
3
+ Version: 0.2.0
4
+ Summary: A lightweight logging package for long-running pipelines: a virtual assistant for the user, a clean archive for the developer.
5
+ Author-email: Marcus Aurelius <marcus.aurelius.hu@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/marcus-aurelius-hu/arin_log
8
+ Project-URL: Source, https://github.com/marcus-aurelius-hu/arin_log
9
+ Project-URL: Issues, https://github.com/marcus-aurelius-hu/arin_log/issues
10
+ Keywords: logging,pipeline,console,logger,arin
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: System :: Logging
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Dynamic: license-file
25
+
26
+ # arin-log
27
+
28
+ A lightweight, cross-platform logging package for long-running pipelines.
29
+ A virtual assistant for the user. A clean archive for the developer.
30
+
31
+ ---
32
+
33
+ ## What is `arin_log`?
34
+
35
+ `arin_log` combines two roles in one package:
36
+
37
+ 1. **A virtual assistant (Arin)** who talks to the user on the console
38
+ and keeps them informed about what the script is doing.
39
+ 2. **A clean, technical log file** that contains only the beacons:
40
+ start, exception, exit. Meant for the developer who has to
41
+ reconstruct later what happened.
42
+
43
+ The user sees a story. The developer sees a trail. That is the core.
44
+
45
+ **Arin is not an AI.** She is a voice — a smart logger with a
46
+ character. This is a deliberate choice not to abuse the AI hype.
47
+
48
+ ---
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install arin-log
54
+ ```
55
+
56
+ On first import, a folder dialog appears asking where you want to
57
+ store your log files. The choice, together with the default colors,
58
+ is saved in:
59
+
60
+ - **Windows:** `%APPDATA%\arin_log\config_log.json`
61
+ - **Linux/macOS:** `~/.arin_log/config_log.json`
62
+
63
+ The dialog appears only once. On every next run, `arin_log` reads
64
+ this file and skips the dialog.
65
+
66
+ If you want to change the log folder later:
67
+
68
+ ```python
69
+ from arin_log import change_folder
70
+ change_folder()
71
+ ```
72
+
73
+ ---
74
+
75
+ ## Quick example
76
+
77
+ ```python
78
+ from arin_log import log_start, log_notes, log_except, log_exit
79
+ from sys import _getframe
80
+
81
+ log_start("my_pipeline", logloc="pipeline")
82
+
83
+ try:
84
+ log_notes("startup ; loading data", logloc="pipeline")
85
+ # ... your work ...
86
+ log_notes("success ; data loaded", logloc="pipeline")
87
+ except Exception:
88
+ log_except(_getframe(), "data ; loading ; fail", logloc="pipeline")
89
+ log_exit("my_pipeline", imp=False, logloc="pipeline")
90
+
91
+ log_exit("my_pipeline", imp=True, logloc="pipeline")
92
+ ```
93
+
94
+ **What the user sees on the console:**
95
+
96
+ ```
97
+ Arin : startup ; loading data
98
+ Arin : success ; data loaded
99
+ Arin my_pipeline ; 14:32:11 ; completed
100
+ ```
101
+
102
+ **What ends up in the log file:**
103
+
104
+ ```
105
+ 26-10-04.pipeline.log
106
+
107
+ my_pipeline ; 14:32:11 ; running
108
+
109
+ startup ; loading data
110
+ success ; data loaded
111
+
112
+ my_pipeline ; 14:32:11 ; completed
113
+ ------------------------------------------------------------
114
+ ```
115
+
116
+ ---
117
+
118
+ ## What makes `arin_log` different?
119
+
120
+ | Aspect | `arin_log` | Loguru / stdlib / structlog |
121
+ |---|---|---|
122
+ | **Context propagation** | One parameter `logloc` travels through the whole call chain; every submodule becomes part of the same log file | `LoggerAdapter`, `contextvars`, or manual config |
123
+ | **Console vs. log file** | Deliberately separated: console = everything (with Arin as a voice), log file = only the beacons | Everything goes to the same handlers |
124
+ | **Archive** | One log file per main module per day, with automatic section separation per subtask | Scattered files or one big file |
125
+ | **Arin as virtual assistant** | A character who guides the user, not a log-level prefix | No equivalent |
126
+ | **Exception notation** | `module.function.linenumber ; time ; exception` — compact and directly usable | Full traceback or `exc_info=True` |
127
+
128
+ **Core USP:** `logloc` + daily grouping per main module + separation of
129
+ console and archive + Arin.
130
+
131
+ ---
132
+
133
+ ## How it works
134
+
135
+ The package consists of four modules, each with a clear task:
136
+
137
+ - **`logger.py`** — the heart: `log_start`, `log_notes`, `log_except`,
138
+ `log_exit`, and the helpers.
139
+ - **`folder.py`** — manages the config folder and the log folder.
140
+ - **`console.py`** — console interaction: clear screen, menus.
141
+ - **`utils.py`** — JSON helpers (`load_json`, `save_json`).
142
+
143
+ ### Configuration
144
+
145
+ - **`log_cnfg.json`** ships with the package as a template: the default
146
+ color words and color codes for the console.
147
+ - **`config_log.json`** lives in `%APPDATA%\arin_log\` (Windows) or
148
+ `~/.arin_log/` (Linux/macOS). On first run it is created by copying
149
+ the colors from `log_cnfg.json` and adding your chosen log folder.
150
+
151
+ To customize colors, edit `config_log.json` in the config folder
152
+ above. Your changes survive `pip install --upgrade arin-log`, because
153
+ the file is never touched by pip.
154
+
155
+ ---
156
+
157
+ ## The log folder
158
+
159
+ `arin_log` stores its files in a folder of your choice. On first use,
160
+ a folder dialog appears. The choice is saved in `config_log.json`
161
+ (see Configuration), so it survives across sessions and is never
162
+ overwritten by a `pip install --upgrade`.
163
+
164
+ If `config_log.json` is missing or corrupt, the dialog appears again —
165
+ the package has no fallback folder. The user is expected to choose.
166
+
167
+ ---
168
+
169
+ ## Requirements
170
+
171
+ - Python 3.9 or higher
172
+
173
+ No external dependencies.
174
+
175
+ ---
176
+
177
+ ## License
178
+
179
+ MIT — see [LICENSE](LICENSE).
180
+
181
+ ---
182
+
183
+ ## Status
184
+
185
+ **Alpha (0.2.0).** The core works. Tests are still in development.
@@ -0,0 +1,160 @@
1
+ # arin-log
2
+
3
+ A lightweight, cross-platform logging package for long-running pipelines.
4
+ A virtual assistant for the user. A clean archive for the developer.
5
+
6
+ ---
7
+
8
+ ## What is `arin_log`?
9
+
10
+ `arin_log` combines two roles in one package:
11
+
12
+ 1. **A virtual assistant (Arin)** who talks to the user on the console
13
+ and keeps them informed about what the script is doing.
14
+ 2. **A clean, technical log file** that contains only the beacons:
15
+ start, exception, exit. Meant for the developer who has to
16
+ reconstruct later what happened.
17
+
18
+ The user sees a story. The developer sees a trail. That is the core.
19
+
20
+ **Arin is not an AI.** She is a voice — a smart logger with a
21
+ character. This is a deliberate choice not to abuse the AI hype.
22
+
23
+ ---
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install arin-log
29
+ ```
30
+
31
+ On first import, a folder dialog appears asking where you want to
32
+ store your log files. The choice, together with the default colors,
33
+ is saved in:
34
+
35
+ - **Windows:** `%APPDATA%\arin_log\config_log.json`
36
+ - **Linux/macOS:** `~/.arin_log/config_log.json`
37
+
38
+ The dialog appears only once. On every next run, `arin_log` reads
39
+ this file and skips the dialog.
40
+
41
+ If you want to change the log folder later:
42
+
43
+ ```python
44
+ from arin_log import change_folder
45
+ change_folder()
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Quick example
51
+
52
+ ```python
53
+ from arin_log import log_start, log_notes, log_except, log_exit
54
+ from sys import _getframe
55
+
56
+ log_start("my_pipeline", logloc="pipeline")
57
+
58
+ try:
59
+ log_notes("startup ; loading data", logloc="pipeline")
60
+ # ... your work ...
61
+ log_notes("success ; data loaded", logloc="pipeline")
62
+ except Exception:
63
+ log_except(_getframe(), "data ; loading ; fail", logloc="pipeline")
64
+ log_exit("my_pipeline", imp=False, logloc="pipeline")
65
+
66
+ log_exit("my_pipeline", imp=True, logloc="pipeline")
67
+ ```
68
+
69
+ **What the user sees on the console:**
70
+
71
+ ```
72
+ Arin : startup ; loading data
73
+ Arin : success ; data loaded
74
+ Arin my_pipeline ; 14:32:11 ; completed
75
+ ```
76
+
77
+ **What ends up in the log file:**
78
+
79
+ ```
80
+ 26-10-04.pipeline.log
81
+
82
+ my_pipeline ; 14:32:11 ; running
83
+
84
+ startup ; loading data
85
+ success ; data loaded
86
+
87
+ my_pipeline ; 14:32:11 ; completed
88
+ ------------------------------------------------------------
89
+ ```
90
+
91
+ ---
92
+
93
+ ## What makes `arin_log` different?
94
+
95
+ | Aspect | `arin_log` | Loguru / stdlib / structlog |
96
+ |---|---|---|
97
+ | **Context propagation** | One parameter `logloc` travels through the whole call chain; every submodule becomes part of the same log file | `LoggerAdapter`, `contextvars`, or manual config |
98
+ | **Console vs. log file** | Deliberately separated: console = everything (with Arin as a voice), log file = only the beacons | Everything goes to the same handlers |
99
+ | **Archive** | One log file per main module per day, with automatic section separation per subtask | Scattered files or one big file |
100
+ | **Arin as virtual assistant** | A character who guides the user, not a log-level prefix | No equivalent |
101
+ | **Exception notation** | `module.function.linenumber ; time ; exception` — compact and directly usable | Full traceback or `exc_info=True` |
102
+
103
+ **Core USP:** `logloc` + daily grouping per main module + separation of
104
+ console and archive + Arin.
105
+
106
+ ---
107
+
108
+ ## How it works
109
+
110
+ The package consists of four modules, each with a clear task:
111
+
112
+ - **`logger.py`** — the heart: `log_start`, `log_notes`, `log_except`,
113
+ `log_exit`, and the helpers.
114
+ - **`folder.py`** — manages the config folder and the log folder.
115
+ - **`console.py`** — console interaction: clear screen, menus.
116
+ - **`utils.py`** — JSON helpers (`load_json`, `save_json`).
117
+
118
+ ### Configuration
119
+
120
+ - **`log_cnfg.json`** ships with the package as a template: the default
121
+ color words and color codes for the console.
122
+ - **`config_log.json`** lives in `%APPDATA%\arin_log\` (Windows) or
123
+ `~/.arin_log/` (Linux/macOS). On first run it is created by copying
124
+ the colors from `log_cnfg.json` and adding your chosen log folder.
125
+
126
+ To customize colors, edit `config_log.json` in the config folder
127
+ above. Your changes survive `pip install --upgrade arin-log`, because
128
+ the file is never touched by pip.
129
+
130
+ ---
131
+
132
+ ## The log folder
133
+
134
+ `arin_log` stores its files in a folder of your choice. On first use,
135
+ a folder dialog appears. The choice is saved in `config_log.json`
136
+ (see Configuration), so it survives across sessions and is never
137
+ overwritten by a `pip install --upgrade`.
138
+
139
+ If `config_log.json` is missing or corrupt, the dialog appears again —
140
+ the package has no fallback folder. The user is expected to choose.
141
+
142
+ ---
143
+
144
+ ## Requirements
145
+
146
+ - Python 3.9 or higher
147
+
148
+ No external dependencies.
149
+
150
+ ---
151
+
152
+ ## License
153
+
154
+ MIT — see [LICENSE](LICENSE).
155
+
156
+ ---
157
+
158
+ ## Status
159
+
160
+ **Alpha (0.2.0).** The core works. Tests are still in development.
@@ -0,0 +1,68 @@
1
+ """
2
+ arin_log
3
+ --------
4
+ Een lichtgewicht, platformonafhankelijke logging-package voor
5
+ langlopende pipelines.
6
+
7
+ Twee rollen in één package:
8
+
9
+ 1. Een virtuele assistent (Arin) die op de console tegen de gebruiker
10
+ praat en hem op de hoogte houdt van wat het script doet.
11
+ 2. Een schoon, technisch logbestand dat alleen de bakens bevat:
12
+ start, exception, exit. Bedoeld voor de ontwikkelaar die later
13
+ moet reconstrueren wat er is gebeurd.
14
+
15
+ De gebruiker ziet een verhaal. De ontwikkelaar ziet een spoor.
16
+
17
+ Publieke API
18
+ ------------
19
+ Vanuit de logger:
20
+ log_start, log_notes, log_except, log_exit,
21
+ config_logs, file_exist, tijd
22
+
23
+ Vanuit de folder:
24
+ change_folder, get_folder
25
+
26
+ Vanuit de console:
27
+ cons_menu
28
+
29
+ Interne functies blijven bereikbaar via hun eigen module, bijvoorbeeld:
30
+ from arin_log.logger import not_set
31
+ from arin_log.folder import get_config
32
+ from arin_log.utils import load_json, save_json
33
+ from arin_log.console import cls, menu_dict
34
+ """
35
+
36
+ __version__ = "0.2.0"
37
+
38
+ from arin_log.logger import (
39
+ log_start,
40
+ log_notes,
41
+ log_except,
42
+ log_exit,
43
+ config_logs,
44
+ file_exist,
45
+ tijd,
46
+ )
47
+
48
+ from arin_log.folder import (
49
+ change_folder,
50
+ get_folder,
51
+ )
52
+
53
+ from arin_log.console import (
54
+ cons_menu,
55
+ )
56
+
57
+ __all__ = [
58
+ "log_start",
59
+ "log_notes",
60
+ "log_except",
61
+ "log_exit",
62
+ "config_logs",
63
+ "file_exist",
64
+ "tijd",
65
+ "change_folder",
66
+ "get_folder",
67
+ "cons_menu",
68
+ ]
@@ -0,0 +1,91 @@
1
+ """
2
+ console.py
3
+ ----------
4
+ Console-interactie voor arin_log.
5
+
6
+ Bevat:
7
+ cls() - wist het scherm (Windows: cls, anders clear)
8
+ menu_dict(optlst) - bouwt een dict van genummerde menu-opties
9
+ cons_menu(optlst, ...) - toont een console-menu en retourneert
10
+ de gekozen functie als commando-string.
11
+
12
+ Dit is een aparte module omdat console-interactie (menu, scherm wissen)
13
+ niets met loggen te maken heeft. De logger logt; de console toont.
14
+ """
15
+
16
+ from os import system, name, path
17
+ from arin_log.logger import log_notes
18
+
19
+ br = chr(10)
20
+ prgnm = path.basename(__file__).split('.')[0]
21
+
22
+
23
+ def cls():
24
+ """Wist het scherm. Op Windows met 'cls', anders met 'clear'."""
25
+ system('cls' if name == 'nt' else 'clear')
26
+ return
27
+
28
+
29
+ def menu_dict(optlst):
30
+ """Bouwt een dict van genummerde menu-opties.
31
+
32
+ De opties krijgen de sleutels '1', '2', '3', ... in volgorde.
33
+ Daarnaast worden de aliassen 'e', 'exit', 'q' en 'quit' toegevoegd,
34
+ die allemaal naar 'exit' wijzen."""
35
+ opties = {}
36
+ idx = 1
37
+ for opt in optlst:
38
+ ids = str(idx)
39
+ opties[ids] = opt
40
+ idx += 1
41
+ opties['e'] = 'exit'
42
+ opties['exit'] = 'exit'
43
+ opties['q'] = 'exit'
44
+ opties['quit'] = 'exit'
45
+ return opties
46
+
47
+
48
+ def cons_menu(optlst, logloc=None):
49
+ """Toont een console-menu en retourneert de gekozen functie
50
+ als een commando-string (bijvoorbeeld 'mijn_functie()').
51
+
52
+ optlst - lijst met functienamen (strings, zonder haakjes).
53
+ 'exit' wordt automatisch toegevoegd als het ontbreekt.
54
+ logloc - context voor de logger; standaard None.
55
+
56
+ De functie blijft het menu tonen tot de gebruiker een geldige
57
+ keuze maakt. 'exit', 'e', 'q' en 'quit' geven 'exit(0)' terug."""
58
+
59
+ exts = ['e', 'exit', 'q', 'quit']
60
+ tlst = optlst
61
+ if 'exit' not in tlst:
62
+ tlst.append('exit')
63
+
64
+ opties = menu_dict(tlst)
65
+ keys = list(opties.keys())
66
+ lng = len(keys)
67
+ choice = '#'
68
+ com = ''
69
+ while choice not in keys:
70
+ cls()
71
+ log_notes([f'{logloc} ; console ; menu', br])
72
+ for key in keys:
73
+ tmp = opties[key].replace('_', ' ')
74
+ if key not in exts:
75
+ print(f'{key}. {tmp}')
76
+ print()
77
+ choice = input(f'Enter your choice ({keys[0]}-{keys[-5]}): ')
78
+ if choice.lower() in exts:
79
+ choice = choice.lower()
80
+ cls()
81
+ if choice in keys:
82
+ com = opties[choice]
83
+ tmp = opties[choice].replace('_', ' ')
84
+ x = keys.index(choice)
85
+ if x < lng - 5:
86
+ log_notes([br, f'Your ; choice ; {tmp}'], logloc=logloc)
87
+ if com.lower() == 'exit':
88
+ com = 'exit(0)'
89
+ else:
90
+ com = f'{com}()'
91
+ return com
@@ -0,0 +1,37 @@
1
+ """
2
+ demo_log.py
3
+ -----------
4
+ Eerste kennismaking met arin_log.
5
+
6
+ Laat zien:
7
+ - hoe je een hoofdmodule markeert met log_start / log_exit
8
+ - hoe je een exception logt met log_except
9
+ - hoe je console-output en logbestand-uitvoer combineert
10
+ via de logloc-parameter
11
+
12
+ Draai met:
13
+ python -m arin_log.demo_log
14
+ """
15
+
16
+ from arin_log.logger import log_start, log_notes, log_except, log_exit
17
+ from sys import _getframe
18
+ from os import path
19
+
20
+ prgnm = path.basename(__file__).split('.')[0]
21
+
22
+ def demo():
23
+ log_start(prgnm, logloc=prgnm)
24
+
25
+ log_notes("demo ; test ; logger")
26
+
27
+ try:
28
+ 1 / 0
29
+ except Exception:
30
+ log_except(_getframe(), "zero ; division ; exception", logloc=prgnm)
31
+
32
+ log_notes("continuing ; logging ; success")
33
+ log_notes("demo ; test ; success", logloc=prgnm)
34
+ log_exit(prgnm, logloc=prgnm)
35
+
36
+ if __name__ == "__main__":
37
+ demo()