rootlp 0.1.7__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.
Files changed (36) hide show
  1. rootlp/__init__.py +23 -0
  2. rootlp/modules/Section_LP/Section.py +177 -0
  3. rootlp/modules/Section_LP/__init__.py +0 -0
  4. rootlp/modules/Section_LP/test_Section.py +44 -0
  5. rootlp/modules/__init__.py +0 -0
  6. rootlp/modules/getfunction_LP/__init__.py +0 -0
  7. rootlp/modules/getfunction_LP/getfunction.py +97 -0
  8. rootlp/modules/getfunction_LP/test_getfunction.py +79 -0
  9. rootlp/modules/main_LP/__init__.py +0 -0
  10. rootlp/modules/main_LP/main.py +437 -0
  11. rootlp/modules/main_LP/test_main.py +74 -0
  12. rootlp/modules/menu_LP/__init__.py +0 -0
  13. rootlp/modules/menu_LP/menu.py +78 -0
  14. rootlp/modules/menu_LP/test_menu.py +79 -0
  15. rootlp/modules/mo_LP/__init__.py +0 -0
  16. rootlp/modules/mo_LP/mo.py +23 -0
  17. rootlp/modules/mo_LP/test_mo.py +79 -0
  18. rootlp/modules/print_LP/__init__.py +0 -0
  19. rootlp/modules/print_LP/print.py +337 -0
  20. rootlp/modules/print_LP/test_print.py +109 -0
  21. rootlp/modules/project_server_LP/__init__.py +0 -0
  22. rootlp/modules/project_server_LP/project_server.py +86 -0
  23. rootlp/modules/project_server_LP/test_project_server.py +79 -0
  24. rootlp/modules/readme_string_LP/__init__.py +0 -0
  25. rootlp/modules/readme_string_LP/readme_string.py +53 -0
  26. rootlp/modules/readme_string_LP/test_readme_string.py +79 -0
  27. rootlp/modules/user_inputs_LP/__init__.py +0 -0
  28. rootlp/modules/user_inputs_LP/test_user_inputs.py +46 -0
  29. rootlp/modules/user_inputs_LP/user_inputs.py +103 -0
  30. rootlp/modules.json +56 -0
  31. rootlp/py.typed +0 -0
  32. rootlp/scripts/__init__.py +0 -0
  33. rootlp/scripts.json +1 -0
  34. rootlp-0.1.7.dist-info/METADATA +41 -0
  35. rootlp-0.1.7.dist-info/RECORD +36 -0
  36. rootlp-0.1.7.dist-info/WHEEL +4 -0
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2026-01-18
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : rootLP
7
+ # Module : mo
8
+
9
+ """
10
+ This file allows to test mo
11
+
12
+ mo : Marimo library shortcut.
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import print, debug
19
+ import pytest
20
+ from rootlp import mo
21
+ debug_folder = debug(__file__)
22
+
23
+
24
+
25
+ # %% Function test
26
+ def test_function() :
27
+ '''
28
+ Test mo function
29
+ '''
30
+ print('Hello world!')
31
+
32
+
33
+
34
+ # %% Instance fixture
35
+ @pytest.fixture()
36
+ def instance() :
37
+ '''
38
+ Create a new instance at each test function
39
+ '''
40
+ return mo()
41
+
42
+ def test_instance(instance) :
43
+ '''
44
+ Test on fixture
45
+ '''
46
+ pass
47
+
48
+
49
+ # %% Returns test
50
+ @pytest.mark.parametrize("args, kwargs, expected, message", [
51
+ #([], {}, None, ""),
52
+ ([], {}, None, ""),
53
+ ])
54
+ def test_returns(args, kwargs, expected, message) :
55
+ '''
56
+ Test mo return values
57
+ '''
58
+ assert mo(*args, **kwargs) == expected, message
59
+
60
+
61
+
62
+ # %% Error test
63
+ @pytest.mark.parametrize("args, kwargs, error, error_message", [
64
+ #([], {}, None, ""),
65
+ ([], {}, None, ""),
66
+ ])
67
+ def test_errors(args, kwargs, error, error_message) :
68
+ '''
69
+ Test mo error values
70
+ '''
71
+ with pytest.raises(error, match=error_message) :
72
+ mo(*args, **kwargs)
73
+
74
+
75
+
76
+ # %% Test function run
77
+ if __name__ == "__main__":
78
+ from corelp import test
79
+ test(__file__)
File without changes
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-08-27
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : coreLP
7
+ # Module : print
8
+
9
+ """
10
+ This function overrides python built in print function to add functionnalities.
11
+ """
12
+
13
+
14
+
15
+ # %% Libraries
16
+
17
+
18
+
19
+ # %% Libraries
20
+ from corelp import prop
21
+ from dataclasses import dataclass, field
22
+ from datetime import datetime, timedelta
23
+ from rich import print as richprint
24
+ from rich.console import Console
25
+ from rich.theme import Theme
26
+ from rich.markdown import Markdown
27
+ from rich.traceback import Traceback
28
+ from rich.progress import (
29
+ Progress,
30
+ BarColumn,
31
+ TextColumn,
32
+ TaskProgressColumn,
33
+ TimeElapsedColumn,
34
+ TimeRemainingColumn,
35
+ ProgressColumn,
36
+ )
37
+ import traceback as tb_module
38
+ from time import perf_counter
39
+ from pathlib import Path
40
+ import marimo as mo
41
+ pyprint = print
42
+
43
+
44
+
45
+ # %% Class
46
+ @dataclass(slots=True, kw_only=True)
47
+ class Print() :
48
+ r"""
49
+ Enhanced replacement for the built-in :func:`print` function, adding muting,
50
+ logging, rich formatting, and progress utilities.
51
+
52
+ This class is callable and behaves like :func:`print`, with extra arguments.
53
+
54
+ Parameters
55
+ ----------
56
+ *strings : tuple
57
+ The objects to print. Its :meth:`__str__` representation is used.
58
+ verbose : bool, optional
59
+ If ``True`` (default), printing is performed.
60
+ If ``False``, printing is skipped unless overridden.
61
+ return_string : bool, optional
62
+ If ``True``, return the processed string instead of ``None``.
63
+ file : str or pathlib.Path or None, optional
64
+ If provided, overrides the configured log file.
65
+ mode : {"w", "a"}, optional
66
+ File mode used when writing logs. Default is ``"a"``.
67
+ end : str, optional
68
+ End-of-line character(s). Defaults to ``"\n"``.
69
+ **kwargs :
70
+ Additional keyword arguments passed to :func:`print` or Rich's :func:`Console.print`.
71
+
72
+ Examples
73
+ --------
74
+ Basic usage::
75
+
76
+ >>> from corelp import print
77
+ >>> s = "Hello *world*!\nThis is a print **example**"
78
+ >>> print(s)
79
+
80
+ Muting::
81
+
82
+ >>> print.verbose = False
83
+ >>> print(s) # muted
84
+ >>> print(s, verbose=True) # forced printing
85
+ >>> print.verbose = True
86
+ >>> print(s) # prints again
87
+ >>> print(s, verbose=False) # forced mute
88
+
89
+ Access to underlying print functions::
90
+
91
+ >>> print.pyprint(s) # built-in print
92
+ >>> print.richprint(s) # rich.print
93
+ >>> print.print(s) # Console.print
94
+ >>> print.log(s) # Console.log
95
+
96
+ Logging::
97
+
98
+ >>> print.file = "log.txt"
99
+ >>> print("Hello") # also writes to file
100
+
101
+ Console styling::
102
+
103
+ >>> print.theme = {"success": "green"}
104
+ >>> print("Done!", style="success")
105
+ >>> try:
106
+ ... 1/0
107
+ ... except Exception:
108
+ ... print.error()
109
+ >>> print.export_html("log.html")
110
+
111
+ Progress / Clock::
112
+
113
+ >>> from time import sleep
114
+ >>> for i in print.clock(15, "Outer"):
115
+ ... for j in print.clock(10, "Inner"):
116
+ ... sleep(1)
117
+
118
+ Attributes
119
+ ----------
120
+ verbose : bool
121
+ Global muting switch.
122
+ pyprint : callable
123
+ Built-in Python :func:`print`.
124
+ richprint : callable
125
+ :mod:`rich` print function.
126
+ console : rich.console.Console
127
+ The Rich console instance used for styled printing.
128
+ file : pathlib.Path or None
129
+ Path to the log file.
130
+ progress : rich.progress.Progress
131
+ Active Rich progress manager.
132
+ bars : dict
133
+ Dictionary storing active progress bars.
134
+ theme : dict
135
+ Custom Rich style definitions.
136
+ """
137
+
138
+ # Main function
139
+ def __call__(self, *strings, verbose=None, do_stdout=True, do_file=True, return_string=False, file=None, mode='a', end='\n', **kwargs) :
140
+
141
+ # Muting
142
+ verbose = verbose if verbose is not None else self.verbose
143
+ if not verbose :
144
+ return None
145
+
146
+ # Formatting string
147
+ string = ", ".join([str(string) for string in strings]) + end
148
+
149
+ # Printing markdown
150
+ if do_stdout :
151
+ string2print = Markdown(string) if self.buffer is None else string
152
+ self.print(string2print, **kwargs)
153
+
154
+ # Writting to file
155
+ if do_file :
156
+ file = file if file is not None else self.file
157
+ if file is not None :
158
+ with open(Path(file), mode) as file :
159
+ file.write(string)
160
+
161
+ # Refresh buffer
162
+ if self.buffer is not None :
163
+ mo.output.replace(mo.md(self.buffer.getvalue()))
164
+
165
+ # Return
166
+ if return_string :
167
+ return string
168
+
169
+
170
+ # MUTING
171
+ verbose : bool = True # True to print
172
+
173
+
174
+
175
+ # PRINT
176
+
177
+ @property
178
+ def print(self) :
179
+ return self.console.print
180
+ @property
181
+ def log(self) :
182
+ return self.console.log
183
+ pyprint = pyprint # python print
184
+ richprint = richprint # rich prints
185
+ buffer : object = field(default=None, repr=False) # Marimo buffer where to print
186
+
187
+
188
+
189
+ # LOGGING
190
+
191
+ _file : Path = None
192
+ @property
193
+ def file(self) :
194
+ return self._file
195
+ @file.setter
196
+ def file(self, value) :
197
+ self._file = Path(value)
198
+
199
+
200
+
201
+ # CONSOLE
202
+
203
+ _theme = {}
204
+ @property
205
+ def theme(self) :
206
+ return self._theme
207
+ @theme.setter
208
+ def theme(self, value) :
209
+ self._theme.update(value)
210
+ self._console = None
211
+
212
+ _console : Console = field(default=None, repr=False)
213
+ @prop(cache=True)
214
+ def console(self) :
215
+ theme = Theme(self.theme)
216
+ return Console(theme=theme, record=True)
217
+
218
+ def error(self) :
219
+ rich_tb = Traceback.from_exception(*tb_module.sys.exc_info())
220
+ self.console.print(rich_tb)
221
+
222
+ def print_locals(self) :
223
+ self.console.log(log_locals=True)
224
+
225
+ def export_html(self, path) :
226
+ if path is None :
227
+ return
228
+ path = Path(path)
229
+ html_content = self.console.export_html(inline_styles=True)
230
+ with open(path, "w", encoding="utf-8") as file:
231
+ file.write(html_content)
232
+
233
+
234
+
235
+ # CLOCK
236
+
237
+ def clock(self, iterable, title="Working...") :
238
+
239
+ # Get iterable
240
+ iterable = range(iterable) if isinstance(iterable, int) else iterable
241
+ iterable = list(iterable)
242
+
243
+ # Marimo
244
+ if self.buffer is not None :
245
+ verbose, self.verbose = self.verbose, False
246
+ for item in mo.status.progress_bar(iterable, title=title, show_rate=True, show_eta=True, remove_on_exit=True) :
247
+ yield item
248
+ self.verbose = verbose
249
+ return
250
+
251
+ # Detect if progressbar already exists
252
+ first_bar = getattr(self, "_progress", None) is None
253
+ progress = self.progress
254
+ bars = self.bars
255
+
256
+ # Opens progress
257
+ if first_bar :
258
+ verbose, self.verbose = self.verbose, False
259
+
260
+ # Write to file
261
+ if self.file is not None :
262
+ with open(Path(self.file), "a") as file :
263
+ file.write(f'{title}...\n')
264
+ progress.start()
265
+
266
+ # Create new task
267
+ task = bars.get(title, None)
268
+ if task is None : # No bar with this name exists
269
+ task = progress.add_task(title, total=len(iterable), avg_time=0.0)
270
+ bars[title] = task # store it
271
+ else :
272
+ progress.reset(task)
273
+
274
+ # Loop
275
+ loop_counter = 0
276
+ start = perf_counter()
277
+ for item in iterable :
278
+ yield item
279
+ loop_counter += 1
280
+ elapsed = perf_counter() - start
281
+ avg_time = elapsed / loop_counter if loop_counter else 0
282
+ progress.update(task, advance=1, avg_time=avg_time)
283
+
284
+ # Clean up
285
+ if first_bar :
286
+ progress.stop()
287
+ del(self.bars)
288
+ del(self.progress)
289
+ self.verbose = verbose
290
+
291
+ _progress : Progress = field(default=None, repr=False)
292
+ @prop(cache=True)
293
+ def progress(self) :
294
+ return Progress(
295
+ TextColumn("{task.description}"),
296
+ BarColumn(),
297
+ TaskProgressColumn(),
298
+ TextColumn("[magenta]/{task.total}[/]"),
299
+ TimeElapsedColumn(),
300
+ AvgLoopTimeColumn(),
301
+ TimeRemainingColumn(),
302
+ EndTimeColumn(),
303
+ transient=False,
304
+ console=self.console
305
+ )
306
+
307
+ _bars : dict = field(default=None, repr=False)
308
+ @prop(cache=True)
309
+ def bars(self) :
310
+ return {}
311
+
312
+
313
+
314
+ # Get instance
315
+ print = Print() # Instance to use everywhere
316
+
317
+ # Custom Progress bar columns
318
+ class AvgLoopTimeColumn(ProgressColumn):
319
+ def render(self, task):
320
+ avg_time = task.fields.get("avg_time", None)
321
+ if avg_time is not None and task.completed > 0:
322
+ string = f"[yellow]↻ {avg_time:.2f}s[/]" if avg_time > 1 else f"[yellow]↻ {avg_time*1000:.2f}ms[/]"
323
+ return string
324
+ return ""
325
+ class EndTimeColumn(ProgressColumn):
326
+ def render(self, task):
327
+ if task.time_remaining is not None:
328
+ end_time = datetime.now() + timedelta(seconds=task.time_remaining)
329
+ return f"[cyan]{end_time:%m-%d %H:%M:%S}[/] "
330
+ return ""
331
+
332
+
333
+
334
+ # %% Test function run
335
+ if __name__ == "__main__":
336
+ from corelp import test
337
+ test(__file__)
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2025-08-27
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : coreLP
7
+ # Module : print
8
+
9
+ """
10
+ This file allows to test print
11
+
12
+ print : This function overrides python built in print function to add functionnalities.
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from rootlp import print
19
+ from corelp import debug
20
+ import pytest
21
+ from time import sleep
22
+ debug_folder = debug(__file__)
23
+
24
+
25
+ # %% test prints
26
+ def test_print() :
27
+ '''
28
+ Test print
29
+ '''
30
+ string = "# TEST\nHello *world*!\n\nThis is 1 print **example**"
31
+ print(string, style="magenta")
32
+ print.print(string, style="magenta")
33
+ print.log(string, style="magenta")
34
+ print.pyprint(string)
35
+ print.richprint(string)
36
+
37
+
38
+
39
+ # %% test verbose
40
+ def test_verbose() :
41
+ '''
42
+ Test verbose
43
+ '''
44
+ print.verbose = False # Muting
45
+ print("Should not print") # Does not print
46
+ print("Should print", verbose=True) # Does print
47
+ print("Should not print") # Does not print
48
+ print.verbose = True # Unmuting
49
+ print("Should print") # Does print
50
+ print("Should not print", verbose=False) # Does not print
51
+ print("Should print") # Does print
52
+
53
+
54
+
55
+ # %% test logging
56
+ def test_logging() :
57
+ '''
58
+ Test logging
59
+ '''
60
+ print.theme = {"success" : "green"}
61
+ string = "# TEST\nHello *world*!\n\nThis is 1 print **example**"
62
+ print(string, style="success")
63
+ print.print_locals()
64
+ try :
65
+ 1/0
66
+ except Exception :
67
+ print.error()
68
+ file = debug_folder / "log.html"
69
+ print.export_html(file)
70
+
71
+
72
+
73
+ # %% test console
74
+ def test_console() :
75
+ '''
76
+ Test console
77
+ '''
78
+ file = debug_folder / 'log.md'
79
+ print.file = file
80
+ string = "# TEST\nHello *world*!\n\nThis is 1 print **example**"
81
+ print(string, style="magenta")
82
+ assert file.exists()
83
+
84
+
85
+
86
+ # %% test clock
87
+ def test_clock() :
88
+ '''
89
+ Test clock
90
+ '''
91
+ for i in print.clock(5, "Outer loop") :
92
+ print("Should not print")
93
+ for j in print.clock(5, "Inner loop") :
94
+ sleep(1)
95
+ print("Should not print")
96
+
97
+ for i in print.clock(10, "Other loop") :
98
+ sleep(1)
99
+ print("Should not print")
100
+
101
+
102
+
103
+
104
+
105
+
106
+ # %% Test function run
107
+ if __name__ == "__main__":
108
+ from corelp import test
109
+ test(__file__)
File without changes
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2026-01-18
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : rootLP
7
+ # Module : project_server
8
+
9
+ """
10
+ This module creates and run a custom marimo server for the project.
11
+ """
12
+
13
+
14
+
15
+ # %% Libraries
16
+ from pathlib import Path
17
+ import marimo as mo
18
+ from fastapi import FastAPI
19
+ from fastapi.responses import RedirectResponse
20
+ import uvicorn
21
+ import webbrowser
22
+ import threading
23
+
24
+
25
+
26
+ # %% Function
27
+ def project_server(file) :
28
+ '''
29
+ This module creates and run a custom marimo server for the project.
30
+
31
+ Parameters
32
+ ----------
33
+ file : str
34
+ String with the main file path.
35
+
36
+ Examples
37
+ --------
38
+ >>> from rootlp import project_server
39
+ ...
40
+ >>> project_server(__file__)
41
+ '''
42
+
43
+ # Folder
44
+ folder = Path(file).parent # folder / main.py
45
+ name = folder.name
46
+
47
+ # Notebooks
48
+ pages = [notebook.stem for notebook in (folder / 'pages').iterdir() if not notebook.name.startswith('__')]
49
+ scripts = [notebook.stem for notebook in (folder / 'scripts').iterdir() if not notebook.name.startswith('__')]
50
+ figures = [notebook.stem for notebook in (folder / 'figures').iterdir() if not notebook.name.startswith('__')]
51
+
52
+ # Create a marimo asgi app
53
+ server = mo.create_asgi_app()
54
+ server = server.with_app(path=f"/", root=folder/"pages/home.py")
55
+ for page in pages :
56
+ server = server.with_app(path=f"/{page}", root=folder/f"pages/{page}.py")
57
+ for script in scripts :
58
+ server = server.with_app(path=f"/{script}", root=folder/f"scripts/{script}.py")
59
+ for figure in figures :
60
+ server = server.with_app(path=f"/{figure}", root=folder/f"figures/{figure}.py")
61
+
62
+ # Create and configure FastAPI
63
+ app = FastAPI()
64
+ app.mount(f"/{name}", server.build())
65
+
66
+ # Prints
67
+ url = f'http://localhost:9797/{name}/'
68
+ print("\n" + "*" * (len(name) + 4))
69
+ print(f"| {name.upper()} |")
70
+ print("*" * (len(name) + 4) + "\n")
71
+ print(f"Ctrl+Click in terminal or copy-paste the following URL in browser:\n")
72
+ print(f" ➜ {url} \n")
73
+ print(f"📌 Do not close this terminal window until you finished with {name}!")
74
+
75
+ # Open browser in a separate thread (so it doesn't block the server)
76
+ threading.Timer(1.0, lambda: webbrowser.open(url)).start()
77
+
78
+ # Run the server
79
+ uvicorn.run(app, host="localhost", port=9797, log_level="critical")
80
+
81
+
82
+
83
+ # %% Test function run
84
+ if __name__ == "__main__":
85
+ from corelp import test
86
+ test(__file__)
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Date : 2026-01-18
4
+ # Author : Lancelot PINCET
5
+ # GitHub : https://github.com/LancelotPincet
6
+ # Library : rootLP
7
+ # Module : project_server
8
+
9
+ """
10
+ This file allows to test project_server
11
+
12
+ project_server : This module creates and run a custom marimo server for the project.
13
+ """
14
+
15
+
16
+
17
+ # %% Libraries
18
+ from corelp import print, debug
19
+ import pytest
20
+ from rootlp import project_server
21
+ debug_folder = debug(__file__)
22
+
23
+
24
+
25
+ # %% Function test
26
+ def test_function() :
27
+ '''
28
+ Test project_server function
29
+ '''
30
+ print('Hello world!')
31
+
32
+
33
+
34
+ # %% Instance fixture
35
+ @pytest.fixture()
36
+ def instance() :
37
+ '''
38
+ Create a new instance at each test function
39
+ '''
40
+ return project_server()
41
+
42
+ def test_instance(instance) :
43
+ '''
44
+ Test on fixture
45
+ '''
46
+ pass
47
+
48
+
49
+ # %% Returns test
50
+ @pytest.mark.parametrize("args, kwargs, expected, message", [
51
+ #([], {}, None, ""),
52
+ ([], {}, None, ""),
53
+ ])
54
+ def test_returns(args, kwargs, expected, message) :
55
+ '''
56
+ Test project_server return values
57
+ '''
58
+ assert project_server(*args, **kwargs) == expected, message
59
+
60
+
61
+
62
+ # %% Error test
63
+ @pytest.mark.parametrize("args, kwargs, error, error_message", [
64
+ #([], {}, None, ""),
65
+ ([], {}, None, ""),
66
+ ])
67
+ def test_errors(args, kwargs, error, error_message) :
68
+ '''
69
+ Test project_server error values
70
+ '''
71
+ with pytest.raises(error, match=error_message) :
72
+ project_server(*args, **kwargs)
73
+
74
+
75
+
76
+ # %% Test function run
77
+ if __name__ == "__main__":
78
+ from corelp import test
79
+ test(__file__)
File without changes