pfund-plot 0.0.1.dev1__tar.gz → 0.0.1.dev3__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.
- pfund_plot-0.0.1.dev3/PKG-INFO +101 -0
- pfund_plot-0.0.1.dev3/README.md +54 -0
- pfund_plot-0.0.1.dev3/pfund_plot/__init__.py +35 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/__init__.py +4 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/__pycache__/__init__.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/__pycache__/main.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/__pycache__/config.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/__pycache__/plot.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/config.py +81 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/commands/plot.py +7 -0
- pfund_plot-0.0.1.dev3/pfund_plot/cli/main.py +20 -0
- pfund_plot-0.0.1.dev3/pfund_plot/composites/composite.py +13 -0
- pfund_plot-0.0.1.dev3/pfund_plot/config_handler.py +136 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/__pycache__/paths.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__init__.py +6 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/__init__.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/dashboard_type.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/data_type.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/dataframe_backend.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/display_mode.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/notebook_type.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/__pycache__/plotting_backend.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/dashboard_type.py +8 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/data_type.py +6 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/dataframe_backend.py +6 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/display_mode.py +7 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/notebook_type.py +7 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/enums/plotting_backend.py +6 -0
- pfund_plot-0.0.1.dev3/pfund_plot/const/paths.py +15 -0
- pfund_plot-0.0.1.dev3/pfund_plot/exports/__init__.py +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/layout.py +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/main.py +18 -0
- pfund_plot-0.0.1.dev3/pfund_plot/mosaic.py +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/plots/__pycache__/candlestick.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/plots/__pycache__/dataframe.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/plots/__pycache__/line.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/plots/candlestick.py +234 -0
- pfund_plot-0.0.1.dev3/pfund_plot/plots/dataframe.py +159 -0
- pfund_plot-0.0.1.dev3/pfund_plot/plots/line.py +2 -0
- pfund_plot-0.0.1.dev3/pfund_plot/plots/orderbook.py +47 -0
- pfund_plot-0.0.1.dev3/pfund_plot/renderer.py +143 -0
- pfund_plot-0.0.1.dev3/pfund_plot/templates/__init__.py +2 -0
- pfund_plot-0.0.1.dev3/pfund_plot/templates/dashboard.py +13 -0
- pfund_plot-0.0.1.dev3/pfund_plot/templates/notebook.py +15 -0
- pfund_plot-0.0.1.dev3/pfund_plot/templates/spreadsheet.py +1 -0
- pfund_plot-0.0.1.dev3/pfund_plot/templates/template.py +10 -0
- pfund_plot-0.0.1.dev3/pfund_plot/types/__pycache__/core.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/types/__pycache__/literals.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/types/core.py +11 -0
- pfund_plot-0.0.1.dev3/pfund_plot/types/literals.py +6 -0
- pfund_plot-0.0.1.dev3/pfund_plot/utils/__pycache__/utils.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/utils/__pycache__/validate.cpython-311.pyc +0 -0
- pfund_plot-0.0.1.dev3/pfund_plot/utils/utils.py +42 -0
- pfund_plot-0.0.1.dev3/pfund_plot/utils/validate.py +50 -0
- pfund_plot-0.0.1.dev3/pyproject.toml +82 -0
- pfund_plot-0.0.1.dev1/PKG-INFO +0 -42
- pfund_plot-0.0.1.dev1/README.md +0 -3
- pfund_plot-0.0.1.dev1/pfund_plot/__init__.py +0 -1
- pfund_plot-0.0.1.dev1/pyproject.toml +0 -45
- {pfund_plot-0.0.1.dev1 → pfund_plot-0.0.1.dev3}/LICENSE +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pfund-plot
|
|
3
|
+
Version: 0.0.1.dev3
|
|
4
|
+
Summary: A library for financial data visualization, dashboard creation, and template sharing.
|
|
5
|
+
Home-page: https://pfund.ai
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Keywords: financial data,plotting,dashboards,charts,data visualization,graphs,plots
|
|
8
|
+
Author: stephenyau
|
|
9
|
+
Author-email: softwareentrepreneer+pfund-plot@gmail.com
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
25
|
+
Provides-Extra: all
|
|
26
|
+
Provides-Extra: dash
|
|
27
|
+
Provides-Extra: gradio
|
|
28
|
+
Provides-Extra: solara
|
|
29
|
+
Provides-Extra: streamlit
|
|
30
|
+
Provides-Extra: taipy
|
|
31
|
+
Requires-Dist: dash (>=2.18.1,<3.0.0) ; extra == "dash" or extra == "all"
|
|
32
|
+
Requires-Dist: gradio (>=5.9.1,<6.0.0) ; extra == "gradio" or extra == "all"
|
|
33
|
+
Requires-Dist: hvplot[datashader,plotly] (>=0.11.2,<0.12.0)
|
|
34
|
+
Requires-Dist: jupyter-bokeh (>=4.0.5,<5.0.0)
|
|
35
|
+
Requires-Dist: narwhals (>=1.19.1,<2.0.0)
|
|
36
|
+
Requires-Dist: panel (>=1.5.5,<2.0.0)
|
|
37
|
+
Requires-Dist: papermill (>=2.6.0,<3.0.0)
|
|
38
|
+
Requires-Dist: pfeed (>=0.0.2,<0.0.3)
|
|
39
|
+
Requires-Dist: pywebview (>=5.3.2,<6.0.0)
|
|
40
|
+
Requires-Dist: streamlit (>=1.41.1,<2.0.0) ; extra == "streamlit" or extra == "all"
|
|
41
|
+
Requires-Dist: taipy (>=4.0.0,<5.0.0) ; extra == "taipy" or extra == "all"
|
|
42
|
+
Requires-Dist: voila (>=0.5.8,<0.6.0)
|
|
43
|
+
Project-URL: Documentation, https://pfund-plot-docs.pfund.ai
|
|
44
|
+
Project-URL: Repository, https://github.com/PFund-Software-Ltd/pfund-plot
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
|
|
47
|
+
# PFund-Plot
|
|
48
|
+
|
|
49
|
+
[](https://x.com/pfund_ai)
|
|
50
|
+

|
|
51
|
+
[](https://jupyter.org)
|
|
52
|
+
[](https://marimo.io)
|
|
53
|
+

|
|
54
|
+
[](https://pypi.org/project/pfund-plot)
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
## Problem
|
|
58
|
+
Traders often need to quickly visualize their data without investing time in learning new tools.
|
|
59
|
+
For example, plotting an orderbook should be as simple as writing a single line of code.
|
|
60
|
+
|
|
61
|
+
## Solution
|
|
62
|
+
We created a high-level plotting library that combines the best features from existing plotting and dashboarding libraries into an easy-to-use interface.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
<img src="docs/assets/candlestick.gif" alt="pfund-plot candlestick streaming example" width="450">
|
|
66
|
+
|
|
67
|
+
<!-- <div style="display: flex; justify-content: space-around; align-items: center;">
|
|
68
|
+
<img src="docs/assets/candlestick.gif" alt="pfund-plot streaming example" width="450">
|
|
69
|
+
<img src="docs/assets/orderbook.gif" alt="pfund-plot streaming example" width="450">
|
|
70
|
+
</div> -->
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
PFund-Plot is a super high-level, out-of-the-box, domain-specific plotting library designed for traders that supports **financial data visualization**, **dashboard creation**, and **template sharing**.
|
|
75
|
+
|
|
76
|
+
> This library is not ready, please wait for version 0.0.1 release.
|
|
77
|
+
|
|
78
|
+
## Core Features
|
|
79
|
+
- [x] Multi-Display Mode: support displaying plots in a *Jupyter notebook*, *Marimo notebook*, *browser* and *desktop window*
|
|
80
|
+
- [x] Streaming Data: support streaming data in real-time by just setting `streaming=True`
|
|
81
|
+
- [x] DataFrame Agnostic: support pandas, polars, and dask
|
|
82
|
+
- [x] Big Data Plotting: support plotting large datasets
|
|
83
|
+
- [x] Financial Plots: plot financial data by just one function call, e.g. candlestick, orderbook, trades etc.
|
|
84
|
+
- [x] Combine multiple plots into a dashboard quickly for visualization
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
```bash
|
|
89
|
+
pip install pfund-plot
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## Usage
|
|
94
|
+
```python
|
|
95
|
+
import pfund_plot as plt
|
|
96
|
+
|
|
97
|
+
# TODO: get some sample data using pfeed
|
|
98
|
+
data = ...
|
|
99
|
+
fig = plt.ohlc(data)
|
|
100
|
+
```
|
|
101
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# PFund-Plot
|
|
2
|
+
|
|
3
|
+
[](https://x.com/pfund_ai)
|
|
4
|
+

|
|
5
|
+
[](https://jupyter.org)
|
|
6
|
+
[](https://marimo.io)
|
|
7
|
+

|
|
8
|
+
[](https://pypi.org/project/pfund-plot)
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Problem
|
|
12
|
+
Traders often need to quickly visualize their data without investing time in learning new tools.
|
|
13
|
+
For example, plotting an orderbook should be as simple as writing a single line of code.
|
|
14
|
+
|
|
15
|
+
## Solution
|
|
16
|
+
We created a high-level plotting library that combines the best features from existing plotting and dashboarding libraries into an easy-to-use interface.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
<img src="docs/assets/candlestick.gif" alt="pfund-plot candlestick streaming example" width="450">
|
|
20
|
+
|
|
21
|
+
<!-- <div style="display: flex; justify-content: space-around; align-items: center;">
|
|
22
|
+
<img src="docs/assets/candlestick.gif" alt="pfund-plot streaming example" width="450">
|
|
23
|
+
<img src="docs/assets/orderbook.gif" alt="pfund-plot streaming example" width="450">
|
|
24
|
+
</div> -->
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
PFund-Plot is a super high-level, out-of-the-box, domain-specific plotting library designed for traders that supports **financial data visualization**, **dashboard creation**, and **template sharing**.
|
|
29
|
+
|
|
30
|
+
> This library is not ready, please wait for version 0.0.1 release.
|
|
31
|
+
|
|
32
|
+
## Core Features
|
|
33
|
+
- [x] Multi-Display Mode: support displaying plots in a *Jupyter notebook*, *Marimo notebook*, *browser* and *desktop window*
|
|
34
|
+
- [x] Streaming Data: support streaming data in real-time by just setting `streaming=True`
|
|
35
|
+
- [x] DataFrame Agnostic: support pandas, polars, and dask
|
|
36
|
+
- [x] Big Data Plotting: support plotting large datasets
|
|
37
|
+
- [x] Financial Plots: plot financial data by just one function call, e.g. candlestick, orderbook, trades etc.
|
|
38
|
+
- [x] Combine multiple plots into a dashboard quickly for visualization
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
```bash
|
|
43
|
+
pip install pfund-plot
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
```python
|
|
49
|
+
import pfund_plot as plt
|
|
50
|
+
|
|
51
|
+
# TODO: get some sample data using pfeed
|
|
52
|
+
data = ...
|
|
53
|
+
fig = plt.ohlc(data)
|
|
54
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from importlib.metadata import version
|
|
2
|
+
|
|
3
|
+
import hvplot
|
|
4
|
+
import panel as pn
|
|
5
|
+
|
|
6
|
+
from pfund_plot.config_handler import get_config, configure
|
|
7
|
+
from pfund_plot.plots.dataframe import (
|
|
8
|
+
dataframe_plot as dataframe,
|
|
9
|
+
dataframe_plot as df,
|
|
10
|
+
)
|
|
11
|
+
from pfund_plot.plots.candlestick import (
|
|
12
|
+
candlestick_plot as candlestick,
|
|
13
|
+
candlestick_plot as ohlc,
|
|
14
|
+
candlestick_plot as kline,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
hvplot.extension('bokeh', 'plotly')
|
|
19
|
+
pn.extension('tabulator', 'perspective')
|
|
20
|
+
# used to throttle updates in panel plots
|
|
21
|
+
# NOTE: without it, e.g. dragging a slider will cause the plot to update rapidly and lead to an error
|
|
22
|
+
pn.config.throttled = True
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__version__ = version("pfund_plot")
|
|
26
|
+
__all__ = (
|
|
27
|
+
"__version__",
|
|
28
|
+
"get_config",
|
|
29
|
+
"configure",
|
|
30
|
+
"candlestick",
|
|
31
|
+
"ohlc",
|
|
32
|
+
"kline",
|
|
33
|
+
"dataframe",
|
|
34
|
+
"df",
|
|
35
|
+
)
|
|
Binary file
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from pfeed.const.enums import DataTool
|
|
4
|
+
from pfund_plot.const.paths import PROJ_NAME
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@click.group()
|
|
8
|
+
def config():
|
|
9
|
+
"""Manage configuration settings."""
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@config.command()
|
|
14
|
+
@click.pass_context
|
|
15
|
+
def list(ctx):
|
|
16
|
+
"""List all available options."""
|
|
17
|
+
from pprint import pformat
|
|
18
|
+
from dataclasses import asdict
|
|
19
|
+
config_dict = asdict(ctx.obj['config'])
|
|
20
|
+
content = click.style(pformat(config_dict), fg='green')
|
|
21
|
+
click.echo(f"{PROJ_NAME} config:\n{content}")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@config.command()
|
|
25
|
+
@click.pass_context
|
|
26
|
+
def reset(ctx):
|
|
27
|
+
"""Reset the configuration to defaults."""
|
|
28
|
+
ctx.obj['config'].reset()
|
|
29
|
+
click.echo(f"{PROJ_NAME} config reset successfully.")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@config.command()
|
|
33
|
+
@click.option('--data-tool', '--dt', type=click.Choice(DataTool, case_sensitive=False), help='Set the data tool')
|
|
34
|
+
@click.option('--max-points', '--mp', type=int, help='Set the maximum number of points to display in the plot')
|
|
35
|
+
@click.option('--data-path', '--dp', type=click.Path(resolve_path=True), help='Set the data path')
|
|
36
|
+
@click.option('--cache-path', '--cp', type=click.Path(resolve_path=True), help='Set the cache path')
|
|
37
|
+
def set(**kwargs):
|
|
38
|
+
"""Configures pfund_plot settings."""
|
|
39
|
+
from pfund_plot.config_handler import configure
|
|
40
|
+
provided_options = {k: v for k, v in kwargs.items() if v is not None}
|
|
41
|
+
if not provided_options:
|
|
42
|
+
raise click.UsageError(f"No options provided. Please run '{PROJ_NAME} config set --help' to see all available options.")
|
|
43
|
+
else:
|
|
44
|
+
configure(write=True, **kwargs)
|
|
45
|
+
click.echo(f"{PROJ_NAME} config updated successfully.")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@config.command()
|
|
49
|
+
@click.option('--config-file', '-c', is_flag=True, help=f'Open the {PROJ_NAME}_config.yml file')
|
|
50
|
+
@click.option('--default-editor', '-E', is_flag=True, help='Use default editor')
|
|
51
|
+
def open(config_file, default_editor):
|
|
52
|
+
"""Opens config files, e.g. pfund_plot_config.yml."""
|
|
53
|
+
from pfund_plot.const.paths import CONFIG_FILE_PATH
|
|
54
|
+
|
|
55
|
+
if sum([config_file]) > 1:
|
|
56
|
+
click.echo('Please specify only one file to open')
|
|
57
|
+
return
|
|
58
|
+
else:
|
|
59
|
+
if config_file:
|
|
60
|
+
file_path = CONFIG_FILE_PATH
|
|
61
|
+
else:
|
|
62
|
+
click.echo(f'Please specify a file to open, run "{PROJ_NAME} config open --help" for more info')
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
if default_editor:
|
|
66
|
+
click.edit(filename=file_path)
|
|
67
|
+
else:
|
|
68
|
+
open_with_vscode(file_path)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def open_with_vscode(file_path):
|
|
72
|
+
import subprocess
|
|
73
|
+
try:
|
|
74
|
+
subprocess.run(["code", str(file_path)], check=True)
|
|
75
|
+
click.echo(f"Opened {file_path} with VS Code")
|
|
76
|
+
except subprocess.CalledProcessError:
|
|
77
|
+
click.echo("Failed to open with VS Code. Falling back to default editor.")
|
|
78
|
+
click.edit(filename=file_path)
|
|
79
|
+
except FileNotFoundError:
|
|
80
|
+
click.echo("VS Code command 'code' not found. Falling back to default editor.")
|
|
81
|
+
click.edit(filename=file_path)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from trogon import tui
|
|
3
|
+
|
|
4
|
+
from pfund_plot.config_handler import get_config
|
|
5
|
+
from pfund_plot.cli.commands.plot import plot
|
|
6
|
+
from pfund_plot.cli.commands.config import config
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@tui(command='tui', help="Open terminal UI")
|
|
10
|
+
@click.group(context_settings={"help_option_names": ["-h", "--help"]})
|
|
11
|
+
@click.pass_context
|
|
12
|
+
@click.version_option()
|
|
13
|
+
def pfund_plot_group(ctx):
|
|
14
|
+
"""PFundPlot's CLI"""
|
|
15
|
+
ctx.ensure_object(dict)
|
|
16
|
+
ctx.obj['config'] = get_config(verbose=False)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
pfund_plot_group.add_command(plot)
|
|
20
|
+
pfund_plot_group.add_command(config)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# TEMP
|
|
2
|
+
# composites are plots combined together on the same canvas
|
|
3
|
+
# it can be used to perform comparison analysis, create a graph that has the price line, equity curve etc.
|
|
4
|
+
|
|
5
|
+
# use plotly for composite plots
|
|
6
|
+
class CompositePlot:
|
|
7
|
+
def __init__(self, plots):
|
|
8
|
+
self.plots = plots
|
|
9
|
+
|
|
10
|
+
def render(self):
|
|
11
|
+
# Implement logic to combine plots
|
|
12
|
+
# This is non-trivial and may require standardizing on a single backend
|
|
13
|
+
pass
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
from dataclasses import dataclass, asdict
|
|
4
|
+
|
|
5
|
+
import yaml
|
|
6
|
+
|
|
7
|
+
from pfund_plot.const.paths import (
|
|
8
|
+
PROJ_NAME,
|
|
9
|
+
DATA_PATH,
|
|
10
|
+
CACHE_PATH,
|
|
11
|
+
CONFIG_PATH,
|
|
12
|
+
CONFIG_FILE_PATH
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'get_config',
|
|
18
|
+
'configure',
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class ConfigHandler:
|
|
24
|
+
data_path: str = str(DATA_PATH)
|
|
25
|
+
cache_path: str = str(CACHE_PATH)
|
|
26
|
+
|
|
27
|
+
_instance = None
|
|
28
|
+
_verbose = False
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def get_instance(cls):
|
|
32
|
+
if cls._instance is None:
|
|
33
|
+
cls._instance = cls.load()
|
|
34
|
+
return cls._instance
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def set_verbose(cls, verbose: bool):
|
|
38
|
+
cls._verbose = verbose
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def load(cls):
|
|
42
|
+
'''Loads user's config file and returns a ConfigHandler object'''
|
|
43
|
+
CONFIG_FILE_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
# Create default config from dataclass fields
|
|
45
|
+
default_config = {
|
|
46
|
+
field.name: field.default
|
|
47
|
+
for field in cls.__dataclass_fields__.values()
|
|
48
|
+
if not field.name.startswith('_') # Skip private fields
|
|
49
|
+
}
|
|
50
|
+
needs_update = False
|
|
51
|
+
if CONFIG_FILE_PATH.is_file():
|
|
52
|
+
with open(CONFIG_FILE_PATH, 'r') as f:
|
|
53
|
+
saved_config = yaml.safe_load(f) or {}
|
|
54
|
+
if cls._verbose:
|
|
55
|
+
print(f"{PROJ_NAME} config loaded from {CONFIG_FILE_PATH}.")
|
|
56
|
+
# Check for new or removed fields
|
|
57
|
+
new_fields = set(default_config.keys()) - set(saved_config.keys())
|
|
58
|
+
removed_fields = set(saved_config.keys()) - set(default_config.keys())
|
|
59
|
+
needs_update = bool(new_fields or removed_fields)
|
|
60
|
+
|
|
61
|
+
if cls._verbose and needs_update:
|
|
62
|
+
if new_fields:
|
|
63
|
+
print(f"New config fields detected: {new_fields}")
|
|
64
|
+
if removed_fields:
|
|
65
|
+
print(f"Removed config fields detected: {removed_fields}")
|
|
66
|
+
|
|
67
|
+
# Filter out removed fields and merge with defaults
|
|
68
|
+
saved_config = {k: v for k, v in saved_config.items() if k in default_config}
|
|
69
|
+
config = {**default_config, **saved_config}
|
|
70
|
+
else:
|
|
71
|
+
config = default_config
|
|
72
|
+
needs_update = True
|
|
73
|
+
config_handler = cls(**config)
|
|
74
|
+
if needs_update:
|
|
75
|
+
config_handler.dump()
|
|
76
|
+
return config_handler
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def reset(cls):
|
|
80
|
+
'''Resets the config by deleting the user config directory and reloading the config'''
|
|
81
|
+
shutil.rmtree(CONFIG_PATH)
|
|
82
|
+
if cls._verbose:
|
|
83
|
+
print(f"{PROJ_NAME} config successfully reset.")
|
|
84
|
+
return cls.load()
|
|
85
|
+
|
|
86
|
+
def dump(self):
|
|
87
|
+
with open(CONFIG_FILE_PATH, 'w') as f:
|
|
88
|
+
yaml.dump(asdict(self), f, default_flow_style=False)
|
|
89
|
+
if self._verbose:
|
|
90
|
+
print(f"{PROJ_NAME} config saved to {CONFIG_FILE_PATH}.")
|
|
91
|
+
|
|
92
|
+
def __post_init__(self):
|
|
93
|
+
self._initialize_configs()
|
|
94
|
+
|
|
95
|
+
def _initialize_configs(self):
|
|
96
|
+
for path in [self.data_path, self.cache_path]:
|
|
97
|
+
if not os.path.exists(path):
|
|
98
|
+
os.makedirs(path)
|
|
99
|
+
if self._verbose:
|
|
100
|
+
print(f'{PROJ_NAME} created {path}')
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def configure(
|
|
104
|
+
data_path: str | None = None,
|
|
105
|
+
cache_path: str | None = None,
|
|
106
|
+
verbose: bool = False,
|
|
107
|
+
write: bool = False,
|
|
108
|
+
):
|
|
109
|
+
'''Configures the global config object.
|
|
110
|
+
It will override the existing config values from the existing config file or the default values.
|
|
111
|
+
Args:
|
|
112
|
+
write: If True, the config will be saved to the config file.
|
|
113
|
+
'''
|
|
114
|
+
NON_CONFIG_KEYS = ['verbose', 'write']
|
|
115
|
+
config_updates = locals()
|
|
116
|
+
for k in NON_CONFIG_KEYS:
|
|
117
|
+
config_updates.pop(k)
|
|
118
|
+
config_updates.pop('NON_CONFIG_KEYS')
|
|
119
|
+
|
|
120
|
+
config = get_config(verbose=verbose)
|
|
121
|
+
|
|
122
|
+
# Apply updates for non-None values
|
|
123
|
+
for k, v in config_updates.items():
|
|
124
|
+
if v is not None:
|
|
125
|
+
setattr(config, k, v)
|
|
126
|
+
|
|
127
|
+
if write:
|
|
128
|
+
config.dump()
|
|
129
|
+
|
|
130
|
+
config._initialize_configs()
|
|
131
|
+
return config
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def get_config(verbose: bool = False) -> ConfigHandler:
|
|
135
|
+
ConfigHandler.set_verbose(verbose)
|
|
136
|
+
return ConfigHandler.get_instance()
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from pfund_plot.const.enums.notebook_type import NotebookType
|
|
2
|
+
from pfund_plot.const.enums.dashboard_type import DashboardType
|
|
3
|
+
from pfund_plot.const.enums.plotting_backend import PlottingBackend
|
|
4
|
+
from pfund_plot.const.enums.display_mode import DisplayMode
|
|
5
|
+
from pfund_plot.const.enums.data_type import DataType
|
|
6
|
+
from pfund_plot.const.enums.dataframe_backend import DataFrameBackend
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from platformdirs import user_data_dir, user_config_dir, user_cache_dir
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# project paths
|
|
6
|
+
PROJ_NAME = Path(__file__).resolve().parents[1].name
|
|
7
|
+
MAIN_PATH = Path(__file__).resolve().parents[2]
|
|
8
|
+
PROJ_PATH = MAIN_PATH / PROJ_NAME
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# user paths
|
|
12
|
+
DATA_PATH = Path(user_data_dir()) / PROJ_NAME
|
|
13
|
+
CACHE_PATH = Path(user_cache_dir()) / PROJ_NAME
|
|
14
|
+
CONFIG_PATH = Path(user_config_dir()) / PROJ_NAME / 'config'
|
|
15
|
+
CONFIG_FILE_PATH = CONFIG_PATH / f'{PROJ_NAME}_config.yml'
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import atexit
|
|
2
|
+
|
|
3
|
+
from pfund_plot.cli import pfund_plot_group
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def exit_cli():
|
|
7
|
+
"""Application Exitpoint."""
|
|
8
|
+
print("Cleanup actions here...")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def run_cli() -> None:
|
|
12
|
+
"""Application Entrypoint."""
|
|
13
|
+
# atexit.register(exit_cli)
|
|
14
|
+
pfund_plot_group(obj={})
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == '__main__':
|
|
18
|
+
run_cli()
|
|
File without changes
|
|
Binary file
|