Algomancy 0.3.12__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.
algomancy/__init__.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""A module for orchestrating components in a content creation and data analysis system.
|
|
2
|
+
|
|
3
|
+
This module integrates various components of a content creation and data-driven
|
|
4
|
+
workflow, including content creator library management, logging, data processing,
|
|
5
|
+
and scenario simulation. It serves as a central manager for handling interdependencies
|
|
6
|
+
and interactions between these subsystems.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__version__ = "0.2.4"
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
from typing import Dict, Any, Union
|
|
2
|
+
import importlib.metadata
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from waitress import serve
|
|
6
|
+
import dash_auth
|
|
7
|
+
from dash import get_app, Dash, html, dcc
|
|
8
|
+
from dash_bootstrap_components.themes import BOOTSTRAP
|
|
9
|
+
|
|
10
|
+
from algomancy_gui.layout import LayoutCreator
|
|
11
|
+
from algomancy_gui.contentregistry import ContentRegistry
|
|
12
|
+
from algomancy_gui.settingsmanager import SettingsManager
|
|
13
|
+
from algomancy_gui.sessionmanager import SessionManager
|
|
14
|
+
from algomancy_gui.componentids import ACTIVE_SESSION
|
|
15
|
+
from algomancy_gui.appconfiguration import AppConfiguration
|
|
16
|
+
from algomancy_content.librarymanager import LibraryManager as lm
|
|
17
|
+
from algomancy_utils.logger import MessageStatus
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class GuiLauncher:
|
|
21
|
+
@staticmethod
|
|
22
|
+
def build(cfg: Union[AppConfiguration, Dict[str, Any]]) -> Dash:
|
|
23
|
+
# Normalize configuration to AppConfiguration for a single source of truth
|
|
24
|
+
if isinstance(cfg, dict):
|
|
25
|
+
cfg_obj = AppConfiguration(**cfg)
|
|
26
|
+
elif isinstance(cfg, AppConfiguration):
|
|
27
|
+
cfg_obj = cfg
|
|
28
|
+
else:
|
|
29
|
+
raise TypeError("DashLauncher.build expects AppConfiguration or dict")
|
|
30
|
+
|
|
31
|
+
session_manager: SessionManager = SessionManager.from_config(cfg_obj)
|
|
32
|
+
|
|
33
|
+
# Create the app
|
|
34
|
+
app = GuiLauncher._construct(
|
|
35
|
+
cfg=cfg_obj,
|
|
36
|
+
session_manager=session_manager,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# register authentication if enabled
|
|
40
|
+
if cfg_obj.use_authentication:
|
|
41
|
+
if not os.getenv("APP_USERNAME") or not os.getenv("APP_PASSWORD"):
|
|
42
|
+
raise ValueError(
|
|
43
|
+
"Environment variables 'APP_USERNAME' and 'APP_PASSWORD' must be set"
|
|
44
|
+
) # todo document where to set username and password
|
|
45
|
+
|
|
46
|
+
# add authentication to the app
|
|
47
|
+
dash_auth.BasicAuth(
|
|
48
|
+
app,
|
|
49
|
+
[[os.getenv("APP_USERNAME"), os.getenv("APP_PASSWORD")]],
|
|
50
|
+
secret_key="secret-key",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return app
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def _construct(
|
|
57
|
+
cfg: AppConfiguration,
|
|
58
|
+
session_manager: SessionManager,
|
|
59
|
+
) -> Dash:
|
|
60
|
+
# Initialize the app
|
|
61
|
+
external_stylesheets = [
|
|
62
|
+
BOOTSTRAP,
|
|
63
|
+
"https://use.fontawesome.com/releases/v5.15.4/css/all.css",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
from pathlib import Path
|
|
67
|
+
|
|
68
|
+
assets_path = Path(os.getcwd()) / Path(cfg.assets_path)
|
|
69
|
+
|
|
70
|
+
app = Dash(
|
|
71
|
+
external_stylesheets=external_stylesheets,
|
|
72
|
+
suppress_callback_exceptions=True,
|
|
73
|
+
assets_folder=str(assets_path),
|
|
74
|
+
)
|
|
75
|
+
app.title = cfg.title
|
|
76
|
+
|
|
77
|
+
# register the scenario manager on the app object
|
|
78
|
+
app.server.session_manager = session_manager
|
|
79
|
+
|
|
80
|
+
# register the styling configuration on the app object
|
|
81
|
+
app.server.styling_config = cfg.styling_config
|
|
82
|
+
|
|
83
|
+
# register the settings manager on the app object for access in callbacks
|
|
84
|
+
app.server.settings = SettingsManager(cfg.as_dict())
|
|
85
|
+
|
|
86
|
+
# fetch standard pages
|
|
87
|
+
home_page, data_page, scenario_page, compare_page, overview_page = lm.get_pages(
|
|
88
|
+
cfg.as_dict()
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# register the content register functions
|
|
92
|
+
content_registry = ContentRegistry()
|
|
93
|
+
app.server.content_registry = content_registry
|
|
94
|
+
|
|
95
|
+
# register pages
|
|
96
|
+
content_registry.register_pages(
|
|
97
|
+
home_page, data_page, scenario_page, compare_page, overview_page
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# fill and run the app
|
|
101
|
+
app.layout = html.Div(
|
|
102
|
+
[
|
|
103
|
+
LayoutCreator.create_layout(cfg.styling_config),
|
|
104
|
+
dcc.Store(
|
|
105
|
+
id=ACTIVE_SESSION,
|
|
106
|
+
storage_type="session",
|
|
107
|
+
data=session_manager.start_session_name,
|
|
108
|
+
),
|
|
109
|
+
]
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return app
|
|
113
|
+
|
|
114
|
+
@staticmethod
|
|
115
|
+
def run(
|
|
116
|
+
app: Dash,
|
|
117
|
+
host: str,
|
|
118
|
+
port: int,
|
|
119
|
+
threads: int = 8,
|
|
120
|
+
connection_limit: int = 100,
|
|
121
|
+
debug: bool = False,
|
|
122
|
+
) -> None:
|
|
123
|
+
sm = get_app().server.session_manager
|
|
124
|
+
|
|
125
|
+
algomancy_version = importlib.metadata.version("algomancy")
|
|
126
|
+
sm.log(f"Algomancy version: {algomancy_version}", MessageStatus.INFO)
|
|
127
|
+
|
|
128
|
+
if not debug:
|
|
129
|
+
sm.log(
|
|
130
|
+
"--------------------------------------------------------------------",
|
|
131
|
+
MessageStatus.SUCCESS,
|
|
132
|
+
)
|
|
133
|
+
sm.log(
|
|
134
|
+
f"Starting Dashboard server with Waitress on {host}:{port}...",
|
|
135
|
+
MessageStatus.SUCCESS,
|
|
136
|
+
)
|
|
137
|
+
sm.log(
|
|
138
|
+
f" threads:{threads}, connection limit: {connection_limit}",
|
|
139
|
+
MessageStatus.SUCCESS,
|
|
140
|
+
)
|
|
141
|
+
sm.log(
|
|
142
|
+
"--------------------------------------------------------------------",
|
|
143
|
+
MessageStatus.SUCCESS,
|
|
144
|
+
)
|
|
145
|
+
serve(
|
|
146
|
+
app.server,
|
|
147
|
+
host=host,
|
|
148
|
+
port=port,
|
|
149
|
+
threads=threads,
|
|
150
|
+
connection_limit=connection_limit,
|
|
151
|
+
)
|
|
152
|
+
else:
|
|
153
|
+
sm.log(
|
|
154
|
+
f"Starting Dashboard server in debug mode on {host}:{port}...",
|
|
155
|
+
MessageStatus.SUCCESS,
|
|
156
|
+
)
|
|
157
|
+
app.run(
|
|
158
|
+
debug=debug,
|
|
159
|
+
host=host,
|
|
160
|
+
port=port,
|
|
161
|
+
dev_tools_silence_routes_logging=False,
|
|
162
|
+
)
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: Algomancy
|
|
3
|
+
Version: 0.3.12
|
|
4
|
+
Summary: A dashboarding framework for visualizing performances of algorithms or simulations in various scenarios.
|
|
5
|
+
Keywords: visualization,algorithm,simulation,scenario
|
|
6
|
+
Author: Pepijn Wissing
|
|
7
|
+
Author-email: Pepijn Wissing <pepijn.wissing@cqm.nl>
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Programming Language :: Python
|
|
11
|
+
Requires-Dist: algomancy-cli>=0.3.12
|
|
12
|
+
Requires-Dist: algomancy-content>=0.3.12
|
|
13
|
+
Requires-Dist: algomancy-data>=0.3.12
|
|
14
|
+
Requires-Dist: algomancy-gui>=0.3.12
|
|
15
|
+
Requires-Dist: algomancy-scenario>=0.3.12
|
|
16
|
+
Requires-Dist: algomancy-utils>=0.3.12
|
|
17
|
+
Requires-Dist: pytest>=8.4.2
|
|
18
|
+
Requires-Dist: ruff>=0.13.1
|
|
19
|
+
Requires-Dist: strenum>=0.4.15
|
|
20
|
+
Maintainer: Pepijn Wissing, Bart Post
|
|
21
|
+
Maintainer-email: Pepijn Wissing <pepijn.wissing@cqm.nl>, Bart Post <bart.post@cqm.nl>
|
|
22
|
+
Requires-Python: >=3.14
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# Algomancy
|
|
26
|
+
|
|
27
|
+
A lightweight framework for building interactive dashboards to visualize the performance of algorithms and/or simulations across scenarios. It provides data ingestion (ETL), scenario orchestration, KPI computation, and a Dash-based UI with modular pages.
|
|
28
|
+
|
|
29
|
+
### Overview
|
|
30
|
+
- Language/stack: Python 3.14+, Dash (frontend/server), Waitress (production WSGI), PyTest (tests), Ruff (lint). Optional: uv as package manager (uv.lock present).
|
|
31
|
+
- Package layout: Installable Python package (setuptools/pyproject). Library entry points are in algomancy/, with an example executable script main-example.py.
|
|
32
|
+
- Use cases: Rapid prototyping of algorithm scenario experiments and visual inspection of results.
|
|
33
|
+
|
|
34
|
+
### Requirements
|
|
35
|
+
- Python: 3.14+
|
|
36
|
+
- OS: Windows, macOS, or Linux
|
|
37
|
+
- Dependencies (core): dash, dash-bootstrap-components, dash-auth (optional), dash-extensions, dash-iconify, pandas, fastparquet, openpyxl, diskcache, strenum, tabulate, waitress, python-dotenv
|
|
38
|
+
- Dev/test tools: pytest, ruff, wheel
|
|
39
|
+
- Optional tools: uv (if you prefer uv over pip)
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
You can install the published package from the private Azure Artifacts feed (keep this section) or install locally in editable/development mode.
|
|
43
|
+
|
|
44
|
+
### From PyPI
|
|
45
|
+
- Install Algomancy:
|
|
46
|
+
```
|
|
47
|
+
uv add algomancy
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Running the Example App
|
|
51
|
+
This repo includes an example application that exercises the framework components.
|
|
52
|
+
- CLI
|
|
53
|
+
python main-example.py --host 127.0.0.1 --port 8050 --threads 8 --connections 100 --debug False
|
|
54
|
+
- Defaults
|
|
55
|
+
If flags are omitted, sensible defaults are applied inside main() (e.g., host differs by OS, port=8050).
|
|
56
|
+
- After starting, open http://127.0.0.1:8050 (or the host/port you chose) in your browser.
|
|
57
|
+
|
|
58
|
+
### Programmatic Usage (library)
|
|
59
|
+
You can embed Algomancy into your own app using the DashLauncher helper.
|
|
60
|
+
- Minimal sketch:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from src.algomancy import BaseDataSource
|
|
64
|
+
from src.algomancy.gui_launcher import GuiLauncher
|
|
65
|
+
from algomancy_gui.appconfiguration import AppConfiguration
|
|
66
|
+
|
|
67
|
+
configuration = {
|
|
68
|
+
"assets_path": "assets",
|
|
69
|
+
"data_path": "tests/data",
|
|
70
|
+
"has_persistent_state": True,
|
|
71
|
+
"save_type": "json",
|
|
72
|
+
"data_object_type": BaseDataSource,
|
|
73
|
+
"etl_factory": YourETLFactory,
|
|
74
|
+
"kpi_templates": your_kpi_templates,
|
|
75
|
+
"algo_templates": your_algorithm_templates,
|
|
76
|
+
"input_configs": your_input_configs,
|
|
77
|
+
"autorun": False,
|
|
78
|
+
"home_content": "placeholder",
|
|
79
|
+
"data_content": "placeholder",
|
|
80
|
+
"scenario_content": "placeholder",
|
|
81
|
+
"compare_content": "placeholder",
|
|
82
|
+
"compare_compare": "placeholder",
|
|
83
|
+
"compare_details": "placeholder",
|
|
84
|
+
"overview_content": "placeholder",
|
|
85
|
+
"home_callbacks": None,
|
|
86
|
+
"data_callbacks": None,
|
|
87
|
+
"scenario_callbacks": None,
|
|
88
|
+
"compare_callbacks": None,
|
|
89
|
+
"overview_callbacks": None,
|
|
90
|
+
"styling_config": None, # see StylingConfigurator for options
|
|
91
|
+
"title": "My Algomancy Dashboard",
|
|
92
|
+
"use_authentication": False,
|
|
93
|
+
}
|
|
94
|
+
app_cfg = AppConfiguration.from_dict(configuration) # or AppConfiguration(asset_path=...)
|
|
95
|
+
|
|
96
|
+
app = GuiLauncher.build(app_cfg)
|
|
97
|
+
GuiLauncher.run(app, host=app_cfg.host, port=app_cfg.port)
|
|
98
|
+
```
|
|
99
|
+
### Environment Variables
|
|
100
|
+
- Authentication (optional): If configuration["use_authentication"] is True, set these before launching:
|
|
101
|
+
APP_USERNAME=<username>
|
|
102
|
+
APP_PASSWORD=<password>
|
|
103
|
+
If either is missing, DashLauncher.build will raise a ValueError.
|
|
104
|
+
- Other env vars: Not required by default. You may use a .env file with python-dotenv if you extend the app. TODO: Document any project-specific environment variables if/when they are introduced.
|
|
105
|
+
|
|
106
|
+
### Scripts and Common Commands
|
|
107
|
+
- Run example app:
|
|
108
|
+
python main-example.py
|
|
109
|
+
- Run tests:
|
|
110
|
+
pytest -q
|
|
111
|
+
- Run tests with verbose output:
|
|
112
|
+
pytest -vv
|
|
113
|
+
- Lint with Ruff:
|
|
114
|
+
ruff check .
|
|
115
|
+
- Format with Ruff (if you choose to enable it):
|
|
116
|
+
ruff format .
|
|
117
|
+
|
|
118
|
+
### Testing
|
|
119
|
+
- Framework uses pytest; tests are under tests/.
|
|
120
|
+
- Example dataset is in tests/data and tests/data/example_data.
|
|
121
|
+
- Some tests are marked xfail intentionally (e.g., missing setters) to capture current behavior. You can run them as-is to verify baseline expectations.
|
|
122
|
+
|
|
123
|
+
### Project Structure
|
|
124
|
+
High-level layout (non-exhaustive):
|
|
125
|
+
- algomancy/ Core package
|
|
126
|
+
- launcher.py Build and run Dash app (DashLauncher)
|
|
127
|
+
- dataengine/ Data loading, ETL, schema, validation
|
|
128
|
+
- scenarioengine/ Scenario orchestration, algorithms, KPIs
|
|
129
|
+
- components/ Dash UI components and pages
|
|
130
|
+
- contentcreatorlibrary/ Ready-made content creators (examples/standard/placeholder)
|
|
131
|
+
- dashboardlogger/ Logging utilities
|
|
132
|
+
- settingsmanager.py Shared runtime settings access
|
|
133
|
+
- stylingconfigurator.py Theme, colors, layout selection
|
|
134
|
+
- example_implementation/ Example ETL, pages, and templates
|
|
135
|
+
- assets/ Static assets (images/styles)
|
|
136
|
+
- tests/ PyTest suites and data files
|
|
137
|
+
- main-example.py Example app entry point
|
|
138
|
+
- pyproject.toml Build configuration (setuptools)
|
|
139
|
+
- uv.lock Lock file for uv (optional)
|
|
140
|
+
|
|
141
|
+
### Entry Points
|
|
142
|
+
- Example executable: main-example.py (CLI and default run)
|
|
143
|
+
- Library: DashLauncher in algomancy/launcher.py
|
|
144
|
+
- There are no console_scripts defined in pyproject.toml.
|
|
145
|
+
|
|
146
|
+
### Configuration Notes
|
|
147
|
+
- Styling: See algomancy/stylingconfigurator.py for layout and color options.
|
|
148
|
+
- Content registration: algomancy/contentcreatorlibrary and algomancy/contentregistry.py provide standard/example/placeholder content.
|
|
149
|
+
- Server: DashLauncher.run uses Waitress in non-debug mode; Dash’s built-in server is used for debug.
|
|
150
|
+
|
|
151
|
+
### Package Management
|
|
152
|
+
- The project is defined via pyproject.toml with setuptools. Use pip for installs by default.
|
|
153
|
+
- A uv.lock file is present; you may use uv if preferred. This repository does not mandate uv.
|
|
154
|
+
|
|
155
|
+
### CI/CD
|
|
156
|
+
- Pipelines configuration files are present under Pipelines/ (Azure DevOps YAML). TODO: Document pipeline triggers, variables, and publishing steps if relevant.
|
|
157
|
+
|
|
158
|
+
### License
|
|
159
|
+
- License: Restricted (as declared in pyproject.toml). Distribution and usage may be limited. Consult the project owners for permissions.
|
|
160
|
+
|
|
161
|
+
### Changelog
|
|
162
|
+
- See changelog.md for notable changes.
|
|
163
|
+
|
|
164
|
+
### Contributing
|
|
165
|
+
- Open issues and pull requests as needed. Run ruff and pytest locally before pushing.
|
|
166
|
+
- TODO: Add contributor guidelines and code style policy if required.
|
|
167
|
+
|
|
168
|
+
### Support
|
|
169
|
+
- Maintainers: See pyproject.toml authors/maintainers fields.
|
|
170
|
+
- For private package feed access or deployment, contact project maintainers.
|
|
171
|
+
|
|
172
|
+
# Update version
|
|
173
|
+
Option A: Update Pipfile to point to the existing wheel (preferred)
|
|
174
|
+
In Pipfile, replace the algomancy source pointing to 0.2.5 with the local 0.2.6 wheel path:
|
|
175
|
+
Example: algomancy = {path = "dist/algomancy-0.2.6-py3-none-any.whl"}
|
|
176
|
+
Then regenerate lockfile and install:
|
|
177
|
+
pipenv lock --clear
|
|
178
|
+
pipenv install
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
algomancy/__init__.py,sha256=g3AqZHGkN5Ap2EHhnBnnAV9u2OhXy3MlAWTJOLp478s,409
|
|
2
|
+
algomancy/gui_launcher.py,sha256=TL-PkZgKCjMO9K0v1uekR3mYNsaqhPlOSe70_TQ_B_s,5324
|
|
3
|
+
algomancy-0.3.12.dist-info/licenses/LICENSE,sha256=pAZXnNE2dxxwXFIduGyn1gpvPefJtUYOYZOi3yeGG94,1068
|
|
4
|
+
algomancy-0.3.12.dist-info/WHEEL,sha256=fAguSjoiATBe7TNBkJwOjyL1Tt4wwiaQGtNtjRPNMQA,80
|
|
5
|
+
algomancy-0.3.12.dist-info/entry_points.txt,sha256=GjvkaIZyYVjM-PUQOiReMb_8MUJ944VU6LV0WqXSD9M,59
|
|
6
|
+
algomancy-0.3.12.dist-info/METADATA,sha256=J5zuWguYFs0PmGh1rRkahLDCjChRjL0IMuRbrsjQ1kY,7810
|
|
7
|
+
algomancy-0.3.12.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [year] [fullname]
|
|
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.
|