deepboard 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.
Files changed (69) hide show
  1. deepboard/__init__.py +1 -0
  2. deepboard/__version__.py +4 -0
  3. deepboard/gui/THEME.yml +28 -0
  4. deepboard/gui/__init__.py +0 -0
  5. deepboard/gui/assets/artefacts.css +108 -0
  6. deepboard/gui/assets/base.css +208 -0
  7. deepboard/gui/assets/base.js +77 -0
  8. deepboard/gui/assets/charts.css +188 -0
  9. deepboard/gui/assets/compare.css +90 -0
  10. deepboard/gui/assets/datagrid.css +120 -0
  11. deepboard/gui/assets/fileview.css +13 -0
  12. deepboard/gui/assets/right_panel.css +227 -0
  13. deepboard/gui/assets/theme.css +85 -0
  14. deepboard/gui/components/__init__.py +8 -0
  15. deepboard/gui/components/artefact_group.py +12 -0
  16. deepboard/gui/components/chart_type.py +22 -0
  17. deepboard/gui/components/legend.py +34 -0
  18. deepboard/gui/components/log_selector.py +22 -0
  19. deepboard/gui/components/modal.py +20 -0
  20. deepboard/gui/components/smoother.py +21 -0
  21. deepboard/gui/components/split_selector.py +21 -0
  22. deepboard/gui/components/stat_line.py +8 -0
  23. deepboard/gui/entry.py +21 -0
  24. deepboard/gui/main.py +93 -0
  25. deepboard/gui/pages/__init__.py +1 -0
  26. deepboard/gui/pages/compare_page/__init__.py +6 -0
  27. deepboard/gui/pages/compare_page/compare_page.py +22 -0
  28. deepboard/gui/pages/compare_page/components/__init__.py +4 -0
  29. deepboard/gui/pages/compare_page/components/card_list.py +19 -0
  30. deepboard/gui/pages/compare_page/components/chart.py +54 -0
  31. deepboard/gui/pages/compare_page/components/compare_setup.py +30 -0
  32. deepboard/gui/pages/compare_page/components/split_card.py +51 -0
  33. deepboard/gui/pages/compare_page/components/utils.py +20 -0
  34. deepboard/gui/pages/compare_page/routes.py +58 -0
  35. deepboard/gui/pages/main_page/__init__.py +4 -0
  36. deepboard/gui/pages/main_page/datagrid/__init__.py +5 -0
  37. deepboard/gui/pages/main_page/datagrid/compare_button.py +21 -0
  38. deepboard/gui/pages/main_page/datagrid/datagrid.py +67 -0
  39. deepboard/gui/pages/main_page/datagrid/handlers.py +54 -0
  40. deepboard/gui/pages/main_page/datagrid/header.py +43 -0
  41. deepboard/gui/pages/main_page/datagrid/routes.py +112 -0
  42. deepboard/gui/pages/main_page/datagrid/row.py +20 -0
  43. deepboard/gui/pages/main_page/datagrid/sortable_column_js.py +45 -0
  44. deepboard/gui/pages/main_page/datagrid/utils.py +9 -0
  45. deepboard/gui/pages/main_page/handlers.py +16 -0
  46. deepboard/gui/pages/main_page/main_page.py +21 -0
  47. deepboard/gui/pages/main_page/right_panel/__init__.py +12 -0
  48. deepboard/gui/pages/main_page/right_panel/config.py +57 -0
  49. deepboard/gui/pages/main_page/right_panel/fragments.py +133 -0
  50. deepboard/gui/pages/main_page/right_panel/hparams.py +25 -0
  51. deepboard/gui/pages/main_page/right_panel/images.py +358 -0
  52. deepboard/gui/pages/main_page/right_panel/run_info.py +86 -0
  53. deepboard/gui/pages/main_page/right_panel/scalars.py +251 -0
  54. deepboard/gui/pages/main_page/right_panel/template.py +151 -0
  55. deepboard/gui/pages/main_page/routes.py +25 -0
  56. deepboard/gui/pages/not_found.py +3 -0
  57. deepboard/gui/requirements.txt +5 -0
  58. deepboard/gui/utils.py +267 -0
  59. deepboard/resultTable/__init__.py +2 -0
  60. deepboard/resultTable/cursor.py +20 -0
  61. deepboard/resultTable/logwritter.py +667 -0
  62. deepboard/resultTable/resultTable.py +529 -0
  63. deepboard/resultTable/scalar.py +29 -0
  64. deepboard/resultTable/table_schema.py +135 -0
  65. deepboard/resultTable/utils.py +50 -0
  66. deepboard-0.2.0.dist-info/METADATA +164 -0
  67. deepboard-0.2.0.dist-info/RECORD +69 -0
  68. deepboard-0.2.0.dist-info/WHEEL +4 -0
  69. deepboard-0.2.0.dist-info/entry_points.txt +2 -0
@@ -0,0 +1,135 @@
1
+ import sqlite3
2
+
3
+ def create_database(db_path):
4
+ conn = sqlite3.connect(db_path)
5
+ cursor = conn.cursor()
6
+
7
+ # Create Experiments table
8
+ cursor.execute("""
9
+ CREATE TABLE IF NOT EXISTS Experiments
10
+ (
11
+ run_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
12
+ experiment varchar(128) NOT NULL,
13
+ config varchar(128),
14
+ config_hash varchar(64),
15
+ cli varchar(512),
16
+ command varchar(256),
17
+ comment TEXT,
18
+ start DATETIME NOT NULL,
19
+ status TEXT CHECK (status IN ('running', 'finished', 'failed')) DEFAULT 'running',
20
+ commit_hash varchar(40),
21
+ diff TEXT,
22
+ hidden INTEGER NOT NULL DEFAULT 0
23
+ );
24
+ """)
25
+
26
+ # Create Results table
27
+ cursor.execute("""
28
+ CREATE TABLE IF NOT EXISTS Results
29
+ (
30
+ id_ INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ run_id INTEGER NOT NULL,
32
+ metric varchar(128) NOT NULL,
33
+ value NOT NULL,
34
+ is_hparam INTEGER DEFAULT 0,
35
+ FOREIGN KEY (run_id) REFERENCES Experiments(run_id)
36
+ );
37
+ """)
38
+
39
+ # Create Logs table for scalar values
40
+ # Wall time is in seconds
41
+ cursor.execute("""
42
+ CREATE TABLE IF NOT EXISTS Logs
43
+ (
44
+ id_ INTEGER PRIMARY KEY AUTOINCREMENT,
45
+ run_id INTEGER NOT NULL,
46
+ epoch INTEGER,
47
+ step INTEGER NOT NULL,
48
+ split varchar (128) NOT NULL,
49
+ label varchar(128) NOT NULL,
50
+ value REAL NOT NULL,
51
+ wall_time REAL NOT NULL,
52
+ run_rep INTEGER NOT NULL,
53
+ FOREIGN KEY(run_id) REFERENCES Experiments(run_id)
54
+ );
55
+ """)
56
+
57
+ # Create an Image table to store images
58
+ cursor.execute("""
59
+ CREATE TABLE IF NOT EXISTS Images
60
+ (
61
+ id_ INTEGER PRIMARY KEY AUTOINCREMENT,
62
+ run_id INTEGER NOT NULL,
63
+ step INTEGER NOT NULL,
64
+ epoch INTEGER,
65
+ run_rep INTEGER NOT NULL,
66
+ img_type varchar(64) NOT NULL, -- IMAGE or PLOT
67
+ split varchar(128),
68
+ image BLOB NOT NULL,
69
+ FOREIGN KEY(run_id) REFERENCES Experiments(run_id)
70
+ );
71
+ """)
72
+ # Create a table to store text data
73
+ cursor.execute("""
74
+ CREATE TABLE IF NOT EXISTS Fragments
75
+ (
76
+ id_ INTEGER PRIMARY KEY AUTOINCREMENT,
77
+ run_id INTEGER NOT NULL,
78
+ step INTEGER NOT NULL,
79
+ epoch INTEGER,
80
+ run_rep INTEGER NOT NULL,
81
+ fragment_type varchar(64) NOT NULL, -- RAW or HTML
82
+ split varchar(128),
83
+ fragment text NOT NULL,
84
+ FOREIGN KEY(run_id) REFERENCES Experiments(run_id)
85
+ );
86
+ """)
87
+ # Display Table
88
+ # This table stores every column of Results, their order and whether they displayed or not
89
+ # If order is Null, it means that the column is not displayed
90
+ cursor.execute("""
91
+ CREATE TABLE IF NOT EXISTS ResultDisplay
92
+ (
93
+ Name varchar(128) NOT NULL, display_order INTEGER,
94
+ alias varchar(128) NOT NULL,
95
+ PRIMARY KEY(Name)
96
+ );
97
+ """) # We can put order to unique, because each NULL value will be unique
98
+
99
+ # Add default columns
100
+ cursor.execute("""
101
+ INSERT
102
+ OR IGNORE INTO ResultDisplay (Name, display_order, alias) VALUES
103
+ ('run_id', 0, 'Run ID'),
104
+ ('experiment', 1, 'Experiment'),
105
+ ('config', 2, 'Config'),
106
+ ('config_hash', NULL, 'Config Hash'),
107
+ ('cli', NULL, 'Cli'),
108
+ ('command', NULL, 'Command'),
109
+ ('comment', 4, 'Comment'),
110
+ ('start', NULL, 'Start'),
111
+ ('status', NULL, 'Status'),
112
+ ('commit_hash', NULL, 'Commit'),
113
+ ('diff', NULL, 'Diff'),
114
+ ('hidden', NULL, 'Hidden');
115
+ """)
116
+
117
+ # Create a trigger to add a new metric to the display table
118
+ cursor.execute("""
119
+ CREATE TRIGGER IF NOT EXISTS after_result_insert
120
+ AFTER INSERT ON Results
121
+ BEGIN
122
+ -- Insert a row into ResultDisplay if the Name does not exist
123
+ INSERT
124
+ OR IGNORE INTO ResultDisplay (Name, display_order, alias)
125
+ SELECT NEW.metric,
126
+ COALESCE(MAX(display_order), 0) + 1,
127
+ NEW.metric
128
+ FROM ResultDisplay;
129
+ END;
130
+ """)
131
+ # Create index for speed
132
+ cursor.execute(
133
+ "CREATE INDEX IF NOT EXISTS idx_config_hash ON Experiments(experiment, config, config_hash, cli, comment);")
134
+ conn.commit()
135
+ conn.close()
@@ -0,0 +1,50 @@
1
+ import sqlite3
2
+ from datetime import datetime, date
3
+ from typing import *
4
+ import subprocess
5
+
6
+ def adapt_date_iso(val):
7
+ """Adapt datetime.date to ISO 8601 date."""
8
+ return val.isoformat()
9
+
10
+ def adapt_datetime_iso(val):
11
+ """Adapt datetime.datetime to timezone-naive ISO 8601 date."""
12
+ return val.isoformat()
13
+
14
+ sqlite3.register_adapter(datetime.date, adapt_date_iso)
15
+ sqlite3.register_adapter(datetime, adapt_datetime_iso)
16
+
17
+ def convert_date(val):
18
+ """Convert ISO 8601 date to datetime.date object."""
19
+ return date.fromisoformat(val.decode())
20
+
21
+ def convert_datetime(val):
22
+ """Convert ISO 8601 datetime to datetime.datetime object."""
23
+ return datetime.fromisoformat(val.decode())
24
+
25
+ sqlite3.register_converter("date", convert_date)
26
+ sqlite3.register_converter("datetime", convert_datetime)
27
+
28
+ def get_last_commit() -> Optional[str]:
29
+ try:
30
+ result = subprocess.run(
31
+ ["git", "rev-parse", "--short", "HEAD"],
32
+ capture_output=True,
33
+ text=True,
34
+ check=True
35
+ )
36
+ return result.stdout.strip()
37
+ except subprocess.CalledProcessError:
38
+ return None
39
+
40
+ def get_diff() -> Optional[str]:
41
+ try:
42
+ result = subprocess.run(
43
+ ["git", "diff", "HEAD"],
44
+ capture_output=True,
45
+ text=True,
46
+ check=True
47
+ )
48
+ return result.stdout.strip()
49
+ except subprocess.CalledProcessError:
50
+ return None
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepboard
3
+ Version: 0.2.0
4
+ Summary: Organize your research project like a pro with Deepboard
5
+ Project-URL: Homepage, https://github.com/anthol42/deepboard
6
+ Project-URL: Issues, https://github.com/anthol42/deepboard/issues
7
+ Author-email: Anthony Lavertu <alavertu2@gmail.com>
8
+ Keywords: board,deep,deepboard,jax,pytorch,tensorboard,tensorflow,torch
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Education
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.10
17
+ Requires-Dist: matplotlib
18
+ Requires-Dist: pandas
19
+ Requires-Dist: pillow
20
+ Provides-Extra: full
21
+ Requires-Dist: fh-plotly; extra == 'full'
22
+ Requires-Dist: markupsafe; extra == 'full'
23
+ Requires-Dist: python-fasthtml; extra == 'full'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Deepboard
27
+ This package include two modules that are work together:
28
+ `deepboard gui` and `resultTable`. The `resultTable` module
29
+ keeps track of all of your experiment and helps you organize
30
+ your code to make results reproducible. The `deepboard gui` module
31
+ implement a webUI to visualize the training details and training
32
+ curves of any runs. In addition, it lets you commpare training curves
33
+ between runs. You can even download the charts that you have generated:)
34
+ ## 🔥 Screenshots 🔥
35
+ ![](./assets/main_view.png)
36
+
37
+
38
+ ![](./assets/compare_view.png)
39
+
40
+
41
+ ![](./assets/full_table_view.png)
42
+ ## 🌟 Project Philosophy
43
+ Before diving in, it’s important to understand the philosophy behind this project. In deep learning, it’s easy to get
44
+ swept up in the excitement — experimenting with countless configurations in search of the perfect setup. 🔬✨
45
+ Eventually, we stumble upon something that works well... only to keep tweaking and lose track of what actually worked
46
+ best. This package is built to help you stay focused, organized, and efficient — so you never lose track of that perfect
47
+ combination again. 🧠✅
48
+
49
+ The idea is simple: always make your code reproducible!
50
+ Sure, easier said than done... 😅 My recommended approach is to use a multi-level configuration system. Let me explain
51
+ how it works! 👇
52
+
53
+ Before jumping into experiments, we usually know the minimal set of parameters required for a project to run.
54
+ For instance, if you're training a Transformer model, you already know you'll need to specify things like the number of
55
+ layers, number of attention heads, learning rate, and so on. All these known parameters can (and should) be stored in a
56
+ configuration file — I personally prefer using YAML for its readability. 📄 When running the experiment, we simply load
57
+ this config file and use it to parameterize each part of the code. Usually, the parameters stored in the config gives
58
+ us the baseline.
59
+
60
+ Once we’ve established a baseline, it’s natural to want to improve it — whether it's by testing out a new technique from
61
+ a paper or an idea that came to us in a dream. 🚀 But here's the challenge: how do we add new functionality to our code
62
+ without breaking compatibility with earlier runs? In other words, if we use the same config file and script parameters,
63
+ we should still get the exact same results as before. My solution? Add new parameters to functions with sensible
64
+ default values — specifically, defaults that reflect the original behavior. You can then include these parameters in
65
+ your configuration file and toggle them on or off to test their effect. For example, say you’re building an image
66
+ classifier and want to try `MixUp`. Your training function might look like this:
67
+ ```python
68
+ def train_model(..., use_mixup: bool = False):
69
+ ...
70
+ ```
71
+ By setting the default to False, your baseline run remains intact. Only when `use_mixup` is explicitly set to True will
72
+ the new logic kick in. This approach ensures clean, reproducible experimentation with minimal disruption. ✅
73
+
74
+ Sometimes, we don’t want to modify the configuration file directly — for example, when we've decided that a particular
75
+ config represents a fixed setup for a specific model or training strategy.
76
+ In these cases, it's often more convenient to override a few parameters via the command line. 🧪
77
+ To do this, I use Python’s built-in argparse module. It adds an extra layer of configuration that’s ideal for quick
78
+ experiments — without changing the original YAML file. And just like before, the same principle applies: always use
79
+ default values that reproduce the results of previous runs. This ensures your experiments stay flexible and reproducible. 🔁
80
+
81
+ This project promotes a simple but powerful principle: make your deep learning experiments reproducible — without
82
+ slowing down iteration or innovation. To achieve that, it recommends a multi-level configuration system:
83
+ 1. YAML Configuration Files – Store all known parameters for a clean, reproducible baseline. 📄
84
+ 2. Function Defaults – Add new features with default values that preserve past behavior. This ensures that re-running
85
+ with the same config and cli parameters always gives the same result. ✅
86
+ 3. CLI Overrides – For quick tweaks, use cli parameters to add new functionalities or to override config's parameters
87
+ without editing the base config. Perfect for fast experimentation. 🧪
88
+
89
+ This layered setup keeps your workflow organized, traceable, and easy to extend, so you can explore new ideas without
90
+ losing sight of what actually works. 🔁
91
+
92
+ If you're feeling a bit overwhelmed or would like a project example, the
93
+ [torchbuilder](https://github.com/anthol42/torchbuilder/tree/dev) app can generate various project templates. The
94
+ default template implements this philosophy, including the resultTable, making it a great starting point! 🚀
95
+
96
+ ## 🛠️ Installation
97
+ To install only the `resultTable` module, which allows you to log your results inside a single file, you can run:
98
+ ```shell
99
+ pip install deepboard
100
+ ```
101
+
102
+ To also install the `GUI` module, which allows you to visualize your results in a web UI, you can run:
103
+ ```shell
104
+ pip install deepboard[full]
105
+ ```
106
+
107
+ ## 🚀 How to Use
108
+ For your project, you will only need the `resultTable` module, as the `deepboard` module is primarily for the UI.
109
+
110
+ ### ResultTable
111
+ First, import the `ResultTable` class from `deepboard.resultTable`, then create a new run. You can also create a debug run.
112
+ A **debug run** will be logged in the result table like any other run, but all results will be overwritten by the next
113
+ debug run. This helps keep the result table clean by containing only the runs you intend to test, rather than those
114
+ meant solely for verifying if the code executed correctly.
115
+
116
+ Note: **Debug runs always have a runID of -1.** 🔧
117
+ ```python
118
+ from deepboard.resultTable import ResultTable
119
+
120
+ rtable = ResultTable("results/resultTable.db")
121
+ if DEBUG:
122
+ resultSocket = rtable.new_debug_run("Experiment1", "path/to/config", cli=vars(args).copy())
123
+ else:
124
+ resultSocket = rtable.new_run("Experiment1", "path/to/config", cli=vars(args).copy())
125
+ ```
126
+
127
+ Next, you can specify hyperparameters that will appear in the table
128
+ ```python
129
+ resultSocket.add_hparams(
130
+ lr=config["training"]["learning_rate"],
131
+ wd=...,
132
+ min_lr=...,
133
+ dropout2d=...,
134
+ dropout=...
135
+ )
136
+ ```
137
+
138
+ During training, we can log scalars associated to the run with:
139
+ ```python
140
+ resultSocket.add_scalar(f'Train/Accuracy', 0.99, step)
141
+ ```
142
+
143
+ Finally, you can log the final evaluation results that will be included into the table with:
144
+ ```python
145
+ resultSocket.write_result(accuracy=final_accuracy, crossEntropy=final_loss)
146
+ ```
147
+
148
+ Note: If you want to do multiple training iterations of the same run (to test variance for example), you can call the
149
+ ```resultSocket.new_repetition``` method after each repetition.
150
+ ```python
151
+ for rep in range(number_of_repetitions):
152
+ for epoch in range(n_epochs):
153
+ ... # Train here
154
+ resultSocket.new_repetition()
155
+
156
+ # Finally, write the final results once:
157
+ resultSocket.write_result(accuracy=accuracies.mean(), crossEntropy=losses.mean())
158
+ ```
159
+
160
+ ### Deepboard UI
161
+ To launch deepboard Web UI, simply run the command `deepboard` in your terminal with the path to your resultTable db:
162
+ ```shell
163
+ deepboard /path/to/resultTable.db
164
+ ```
@@ -0,0 +1,69 @@
1
+ deepboard/__init__.py,sha256=nMXg9GFsk8gCcyBnh1MAeUPvo4Zcuv3sdwGHZrxfpPE,36
2
+ deepboard/__version__.py,sha256=73xmj_rtt0boRuIZ0h5wqHItFsCNZHTC-Wa0tSeAxyY,171
3
+ deepboard/gui/THEME.yml,sha256=Cj7iDLGOYi_rmj6O7REadkukoiZkut-faNPDlD9qkII,645
4
+ deepboard/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ deepboard/gui/entry.py,sha256=GPG5BJ2nOVqRfTlPFL-wYIcvySZEotk6gO52Ww_LUxA,576
6
+ deepboard/gui/main.py,sha256=gT6zMGa3AdrWKvblIBEfkyT42YN9iCvgSgY87jcaiF4,3406
7
+ deepboard/gui/requirements.txt,sha256=pOXbI6s6re_6zBe8rAWlx7VxxTYJucyoJ9wCespWu3M,51
8
+ deepboard/gui/utils.py,sha256=9z9LOhXW2LA5heQEpI7nEeK463O6INSypOotPLdQnHI,9235
9
+ deepboard/gui/assets/artefacts.css,sha256=5B-uBbwZ2-1aLVNShb61OejFQjMgS_9tzXmhCgLSLSE,2414
10
+ deepboard/gui/assets/base.css,sha256=V341OJirGVse8hbw1B8_xwMm41idkehYaF5p7QR5vD8,3994
11
+ deepboard/gui/assets/base.js,sha256=6CinWmaHwTRQJemXdjRTp7HVfAIH2gMkm6CQ-6pkuSA,2682
12
+ deepboard/gui/assets/charts.css,sha256=_PgD1QHQUWYapeH6gJDS96dFsYz0YSOSMjF0TtBvwi4,3719
13
+ deepboard/gui/assets/compare.css,sha256=u5BSr38ZdPlon7TaheHhV5K2jwloYnkShN5C9IdB7y0,1932
14
+ deepboard/gui/assets/datagrid.css,sha256=_OTQqjrRY28A8uI9FFcr2fIWVR7Uxu-qVRfWH5T9zO4,2358
15
+ deepboard/gui/assets/fileview.css,sha256=a_WKfqIBCCqJkrpUA7U2O-2_4dPDjW9pcMeUKeX2Ldk,250
16
+ deepboard/gui/assets/right_panel.css,sha256=55bnhRBfXHGv0ELQK-0fU7PtYz9Wjk0vmiVCrFtSftM,5016
17
+ deepboard/gui/assets/theme.css,sha256=WKq9dGm0R850xRCoCFN5OkSXRzq738tSQJva7zJHcpM,2622
18
+ deepboard/gui/components/__init__.py,sha256=67VIta8hGT67m5kFT_k9isr9edGdkKfjQxb23R3ETPQ,271
19
+ deepboard/gui/components/artefact_group.py,sha256=0OTbCFRyD7Oh9ScUZKsfNtu4iou0AMSTp0bEYTwZPok,331
20
+ deepboard/gui/components/chart_type.py,sha256=fGjeT8Emw4HzGJd7pl1lij1pvV-9-cN0Dem_Tk8T9nc,1135
21
+ deepboard/gui/components/legend.py,sha256=yznW0VYGMB7MeHSdV6Lb3rly_IcbzNa1r6-GQtE6Ktk,1427
22
+ deepboard/gui/components/log_selector.py,sha256=pJBtkRyRQ3wS5h7d7q06Ga5yHOsiXAcGjuGv4BH0m9E,1134
23
+ deepboard/gui/components/modal.py,sha256=B7QsqRctawL55u5YKm9HMlAuVjC-uZ2HR8s53-kV4Uk,515
24
+ deepboard/gui/components/smoother.py,sha256=cNAD4B-efUSJsY3hGA5Rz1WkCsJd3Yt5siDKEOcxmc4,954
25
+ deepboard/gui/components/split_selector.py,sha256=j_vwMuNduQ4afq5CHKSkesvL6cu9o4Q-0Fq7kDqK0io,818
26
+ deepboard/gui/components/stat_line.py,sha256=B0uBRlooxMgFeRWjx92x7KOr25jOH3zViRWSFMdD7LY,298
27
+ deepboard/gui/pages/__init__.py,sha256=VV7KBURlxVm953dMxR29doXaYQaPB-0t_ifs3YOwGYU,33
28
+ deepboard/gui/pages/not_found.py,sha256=qTNcMG2okmdklZOCVeI6K6OmZ717Tn8TekUNSRX1izc,152
29
+ deepboard/gui/pages/compare_page/__init__.py,sha256=0RIIQ6mXWr1ztOYAcpbsccQXAjbQhCnGH7sdaiiBMGI,273
30
+ deepboard/gui/pages/compare_page/compare_page.py,sha256=UDLqKTK9F5cK7ynMVrjb0RX0XDdJG-z4pst1z5HYZCI,643
31
+ deepboard/gui/pages/compare_page/routes.py,sha256=FtUotUJq1tKUL-07Cbpw1E7xzdt4sQZP97mCkrw9PfI,2554
32
+ deepboard/gui/pages/compare_page/components/__init__.py,sha256=eKlD7qn2jtBLQqqNsnkwVxDMp-Ln4Z39X5AGMvcWBns,149
33
+ deepboard/gui/pages/compare_page/components/card_list.py,sha256=MaZyqHM75UA1VPOfzoKfPi2N1rdVLfiwnLFBlxh-dvo,785
34
+ deepboard/gui/pages/compare_page/components/chart.py,sha256=4KZlYOwr0wRemSUjrD1glBnGizEh2kUgmeUGU9_pM7A,2219
35
+ deepboard/gui/pages/compare_page/components/compare_setup.py,sha256=mf-qChvLsjcoIJW_pcfHtHb2VuGgmw7fwX7jNarlij0,1564
36
+ deepboard/gui/pages/compare_page/components/split_card.py,sha256=nABAKLtOL_xBDGsvGAkxHQnjf3-EkQFRcgUj_cENiyE,2140
37
+ deepboard/gui/pages/compare_page/components/utils.py,sha256=MfM7gu4hCqF1Mps9uzKwY3cssgsp2tWPrhkFJYkQokg,750
38
+ deepboard/gui/pages/main_page/__init__.py,sha256=yu7LEqMe2cu0bmxgu7V4fRV0FJjCeb82sHzjAnTAeeE,159
39
+ deepboard/gui/pages/main_page/handlers.py,sha256=BTZaKmlBIZXmlfwMo70Kx0mKR6pls-Hqj5rvqpdghks,600
40
+ deepboard/gui/pages/main_page/main_page.py,sha256=lrHkrXzUvwTfuLI9lrSyW-R5ADO5cLAso-VDtfHHhVg,769
41
+ deepboard/gui/pages/main_page/routes.py,sha256=r7YgV_6xv7e0sOCa8fkhyH-gq-6Q2T7O_n9AP1Gn1kE,770
42
+ deepboard/gui/pages/main_page/datagrid/__init__.py,sha256=wVP6ETJVFJmVOOxHeyP90KHNSdlMw9eCsb3JyEcqnrQ,234
43
+ deepboard/gui/pages/main_page/datagrid/compare_button.py,sha256=-_BwxpKMvvYWmBUD1v0ZFEa9cVOWzyfsu2Co3FTfyuw,839
44
+ deepboard/gui/pages/main_page/datagrid/datagrid.py,sha256=WxVzGzJIlmLx6s-FrMwtG5lw6PAyc9hSvFQ_vvz09M8,2721
45
+ deepboard/gui/pages/main_page/datagrid/handlers.py,sha256=kp6hx7qXeBNokCHay9tcAt-ZMG2YOFCZSuBWKI7vj5U,2760
46
+ deepboard/gui/pages/main_page/datagrid/header.py,sha256=OzhfkokmCfga_VEnUdL2UDxZkU8TiELZatoQihqdKZY,1436
47
+ deepboard/gui/pages/main_page/datagrid/routes.py,sha256=2I-eKm-DKZUaD5bUJnlZOr66SGlsiUJnzlDChH-Rwlo,3656
48
+ deepboard/gui/pages/main_page/datagrid/row.py,sha256=aUKmet_BuYAC39nvCzh57p2U7RvdE3jD3phualu5MPg,742
49
+ deepboard/gui/pages/main_page/datagrid/sortable_column_js.py,sha256=NyzULiCjUtcvrOcIS68hbo7UPtJwCoa4WTqdlGvNszk,1586
50
+ deepboard/gui/pages/main_page/datagrid/utils.py,sha256=xgTju4w7gacVQhDMPN3bxY2qZedhTlC2jeAOgXT2yTg,299
51
+ deepboard/gui/pages/main_page/right_panel/__init__.py,sha256=L4zdoW-0HJtP49rS8l52D4Prbv6S7pLBMm0ufZf64Mc,413
52
+ deepboard/gui/pages/main_page/right_panel/config.py,sha256=Qtk7kXXvlzLpBMEnCBojXSHrij7uEBnMACj5KoQ2g5Q,1567
53
+ deepboard/gui/pages/main_page/right_panel/fragments.py,sha256=XcPs3TKzHEF-GreDpnKwHs2G2xJAWtNtv0SQCVg1TXQ,4503
54
+ deepboard/gui/pages/main_page/right_panel/hparams.py,sha256=KrLpUEccGMn-rCBA2tztcM0XxV6MD2oUsx3UbJ2XZYQ,605
55
+ deepboard/gui/pages/main_page/right_panel/images.py,sha256=Phf8vY8-Md3vFTI-7Ri5wwK-WNzVuyCKrCpTyLudGs0,11698
56
+ deepboard/gui/pages/main_page/right_panel/run_info.py,sha256=UqJZWz4i32bOQirVAlEjrDraYVaHsVNevV3Bng35TqU,2820
57
+ deepboard/gui/pages/main_page/right_panel/scalars.py,sha256=psJj5xUqYyZjJA62ymz3CYzck9EF5TkVcA0Z4_UVHqs,9835
58
+ deepboard/gui/pages/main_page/right_panel/template.py,sha256=zI4ShVwadXi6Dwe-mB_cIN5ZU7GHnb7_Ow_ezGD-b-o,5756
59
+ deepboard/resultTable/__init__.py,sha256=qjeK7bIYHeWTM6Lp9V1HLB_8gCeEMonKDvjHXfBWeSA,86
60
+ deepboard/resultTable/cursor.py,sha256=YZrCQeISPqXcH9KhKhearK5LEyM2rc_fqH8axnFUXPY,699
61
+ deepboard/resultTable/logwritter.py,sha256=iXbPkfp5t0dd4Ojydw0zWKEpgKE7SXEmmasSfmPjegM,27046
62
+ deepboard/resultTable/resultTable.py,sha256=e_xSAZmA6xAKL7sdKo_43ToDUsr6JI0TgHL7x3paltQ,24584
63
+ deepboard/resultTable/scalar.py,sha256=6pakiOafTxoj2yCTCn0Y300ECK23KKQ-orTHvWT5pLI,1347
64
+ deepboard/resultTable/table_schema.py,sha256=EYdP3c8WcimmcA50ecX10tyd5jcry2aVZBN--DICbck,4322
65
+ deepboard/resultTable/utils.py,sha256=3K0rt5QDHv0aOld8KiXFGXvTUBiTskgnNxEjAApqCFQ,1424
66
+ deepboard-0.2.0.dist-info/METADATA,sha256=PsYCOM1VyigWLn5M7kUSGh7oOqgJGxrIjk-PtmCyXOU,8340
67
+ deepboard-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
68
+ deepboard-0.2.0.dist-info/entry_points.txt,sha256=SFQjQXlWt2867B5_Lu9PVzB8pIUYbCSpPsViqyRZCyk,55
69
+ deepboard-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ deepboard = deepboard.gui.entry:main