hectiqlab 0.1.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.
Files changed (172) hide show
  1. hectiqlab-0.1.0/.gitignore +281 -0
  2. hectiqlab-0.1.0/.python-version +1 -0
  3. hectiqlab-0.1.0/PKG-INFO +122 -0
  4. hectiqlab-0.1.0/README.md +102 -0
  5. hectiqlab-0.1.0/hectiqlab/__init__.py +64 -0
  6. hectiqlab-0.1.0/hectiqlab/_internal/__init__.py +1 -0
  7. hectiqlab-0.1.0/hectiqlab/_internal/call.py +152 -0
  8. hectiqlab-0.1.0/hectiqlab/_internal/credentials.py +208 -0
  9. hectiqlab-0.1.0/hectiqlab/_internal/fields.py +91 -0
  10. hectiqlab-0.1.0/hectiqlab/_internal/lazy.py +51 -0
  11. hectiqlab-0.1.0/hectiqlab/_internal/login.py +70 -0
  12. hectiqlab-0.1.0/hectiqlab/_internal/progress.py +236 -0
  13. hectiqlab-0.1.0/hectiqlab/_internal/settings.py +112 -0
  14. hectiqlab-0.1.0/hectiqlab/_internal/stack.py +59 -0
  15. hectiqlab-0.1.0/hectiqlab/_internal/storage.py +259 -0
  16. hectiqlab-0.1.0/hectiqlab/_internal/times.py +42 -0
  17. hectiqlab-0.1.0/hectiqlab/_internal/toml.py +96 -0
  18. hectiqlab-0.1.0/hectiqlab/_internal/transport.py +272 -0
  19. hectiqlab-0.1.0/hectiqlab/_internal/worker.py +281 -0
  20. hectiqlab-0.1.0/hectiqlab/artifacts/__init__.py +5 -0
  21. hectiqlab-0.1.0/hectiqlab/artifacts/namespace.py +176 -0
  22. hectiqlab-0.1.0/hectiqlab/artifacts/record.py +41 -0
  23. hectiqlab-0.1.0/hectiqlab/cli/__init__.py +24 -0
  24. hectiqlab-0.1.0/hectiqlab/cli/app.py +155 -0
  25. hectiqlab-0.1.0/hectiqlab/cli/artifacts.py +115 -0
  26. hectiqlab-0.1.0/hectiqlab/cli/metrics.py +68 -0
  27. hectiqlab-0.1.0/hectiqlab/cli/runs.py +201 -0
  28. hectiqlab-0.1.0/hectiqlab/cli/shared.py +191 -0
  29. hectiqlab-0.1.0/hectiqlab/cli/tags.py +41 -0
  30. hectiqlab-0.1.0/hectiqlab/cli/versioned.py +257 -0
  31. hectiqlab-0.1.0/hectiqlab/errors.py +87 -0
  32. hectiqlab-0.1.0/hectiqlab/integrations/__init__.py +1 -0
  33. hectiqlab-0.1.0/hectiqlab/integrations/linear.py +381 -0
  34. hectiqlab-0.1.0/hectiqlab/metrics/__init__.py +5 -0
  35. hectiqlab-0.1.0/hectiqlab/metrics/namespace.py +113 -0
  36. hectiqlab-0.1.0/hectiqlab/metrics/record.py +44 -0
  37. hectiqlab-0.1.0/hectiqlab/projects/__init__.py +6 -0
  38. hectiqlab-0.1.0/hectiqlab/projects/namespace.py +46 -0
  39. hectiqlab-0.1.0/hectiqlab/projects/record.py +19 -0
  40. hectiqlab-0.1.0/hectiqlab/projects/workspace.py +140 -0
  41. hectiqlab-0.1.0/hectiqlab/records.py +25 -0
  42. hectiqlab-0.1.0/hectiqlab/result.py +148 -0
  43. hectiqlab-0.1.0/hectiqlab/runs/__init__.py +29 -0
  44. hectiqlab-0.1.0/hectiqlab/runs/factory.py +78 -0
  45. hectiqlab-0.1.0/hectiqlab/runs/handle.py +330 -0
  46. hectiqlab-0.1.0/hectiqlab/runs/namespace.py +271 -0
  47. hectiqlab-0.1.0/hectiqlab/runs/pending.py +101 -0
  48. hectiqlab-0.1.0/hectiqlab/runs/provenance.py +170 -0
  49. hectiqlab-0.1.0/hectiqlab/runs/record.py +129 -0
  50. hectiqlab-0.1.0/hectiqlab/runs/refs.py +136 -0
  51. hectiqlab-0.1.0/hectiqlab/runs/stack.py +108 -0
  52. hectiqlab-0.1.0/hectiqlab/session.py +44 -0
  53. hectiqlab-0.1.0/hectiqlab/stages/__init__.py +1 -0
  54. hectiqlab-0.1.0/hectiqlab/stages/opening.py +180 -0
  55. hectiqlab-0.1.0/hectiqlab/stages/record.py +52 -0
  56. hectiqlab-0.1.0/hectiqlab/stages/stack.py +27 -0
  57. hectiqlab-0.1.0/hectiqlab/stages/stage.py +206 -0
  58. hectiqlab-0.1.0/hectiqlab/tags/__init__.py +5 -0
  59. hectiqlab-0.1.0/hectiqlab/tags/namespace.py +48 -0
  60. hectiqlab-0.1.0/hectiqlab/tags/record.py +15 -0
  61. hectiqlab-0.1.0/hectiqlab/tui/__init__.py +25 -0
  62. hectiqlab-0.1.0/hectiqlab/tui/app.py +202 -0
  63. hectiqlab-0.1.0/hectiqlab/tui/app.tcss +367 -0
  64. hectiqlab-0.1.0/hectiqlab/tui/events.py +396 -0
  65. hectiqlab-0.1.0/hectiqlab/tui/format.py +215 -0
  66. hectiqlab-0.1.0/hectiqlab/tui/palette.py +98 -0
  67. hectiqlab-0.1.0/hectiqlab/tui/prefs.py +66 -0
  68. hectiqlab-0.1.0/hectiqlab/tui/preview/__init__.py +9 -0
  69. hectiqlab-0.1.0/hectiqlab/tui/preview/preview.py +34 -0
  70. hectiqlab-0.1.0/hectiqlab/tui/preview/read_bytes.py +38 -0
  71. hectiqlab-0.1.0/hectiqlab/tui/preview/read_csv.py +52 -0
  72. hectiqlab-0.1.0/hectiqlab/tui/preview/read_image.py +111 -0
  73. hectiqlab-0.1.0/hectiqlab/tui/preview/read_parquet.py +79 -0
  74. hectiqlab-0.1.0/hectiqlab/tui/preview/read_tensors.py +137 -0
  75. hectiqlab-0.1.0/hectiqlab/tui/preview/read_text.py +66 -0
  76. hectiqlab-0.1.0/hectiqlab/tui/preview/read_tree.py +96 -0
  77. hectiqlab-0.1.0/hectiqlab/tui/preview/registry.py +113 -0
  78. hectiqlab-0.1.0/hectiqlab/tui/preview/remote.py +121 -0
  79. hectiqlab-0.1.0/hectiqlab/tui/reads/__init__.py +37 -0
  80. hectiqlab-0.1.0/hectiqlab/tui/reads/facts.py +161 -0
  81. hectiqlab-0.1.0/hectiqlab/tui/reads/lab.py +569 -0
  82. hectiqlab-0.1.0/hectiqlab/tui/reads/models.py +141 -0
  83. hectiqlab-0.1.0/hectiqlab/tui/reads/series.py +131 -0
  84. hectiqlab-0.1.0/hectiqlab/tui/reads/source.py +191 -0
  85. hectiqlab-0.1.0/hectiqlab/tui/reads/stages.py +107 -0
  86. hectiqlab-0.1.0/hectiqlab/tui/screens/__init__.py +1 -0
  87. hectiqlab-0.1.0/hectiqlab/tui/screens/compare.py +190 -0
  88. hectiqlab-0.1.0/hectiqlab/tui/screens/dashboard/__init__.py +27 -0
  89. hectiqlab-0.1.0/hectiqlab/tui/screens/dashboard/cards.py +461 -0
  90. hectiqlab-0.1.0/hectiqlab/tui/screens/dashboard/grid.py +152 -0
  91. hectiqlab-0.1.0/hectiqlab/tui/screens/dashboard/numbers.py +116 -0
  92. hectiqlab-0.1.0/hectiqlab/tui/screens/dashboard/screen.py +238 -0
  93. hectiqlab-0.1.0/hectiqlab/tui/screens/edit.py +148 -0
  94. hectiqlab-0.1.0/hectiqlab/tui/screens/help.py +88 -0
  95. hectiqlab-0.1.0/hectiqlab/tui/screens/home.py +554 -0
  96. hectiqlab-0.1.0/hectiqlab/tui/screens/metric.py +294 -0
  97. hectiqlab-0.1.0/hectiqlab/tui/screens/preview.py +243 -0
  98. hectiqlab-0.1.0/hectiqlab/tui/screens/project.py +75 -0
  99. hectiqlab-0.1.0/hectiqlab/tui/screens/run/__init__.py +7 -0
  100. hectiqlab-0.1.0/hectiqlab/tui/screens/run/artifacts.py +106 -0
  101. hectiqlab-0.1.0/hectiqlab/tui/screens/run/config.py +22 -0
  102. hectiqlab-0.1.0/hectiqlab/tui/screens/run/failure.py +29 -0
  103. hectiqlab-0.1.0/hectiqlab/tui/screens/run/provenance.py +36 -0
  104. hectiqlab-0.1.0/hectiqlab/tui/screens/run/screen.py +302 -0
  105. hectiqlab-0.1.0/hectiqlab/tui/screens/run/series.py +137 -0
  106. hectiqlab-0.1.0/hectiqlab/tui/screens/run/stages.py +182 -0
  107. hectiqlab-0.1.0/hectiqlab/tui/screens/theme.py +73 -0
  108. hectiqlab-0.1.0/hectiqlab/tui/screens/versioned.py +335 -0
  109. hectiqlab-0.1.0/hectiqlab/tui/widgets/__init__.py +1 -0
  110. hectiqlab-0.1.0/hectiqlab/tui/widgets/banner.py +59 -0
  111. hectiqlab-0.1.0/hectiqlab/tui/widgets/binds.py +59 -0
  112. hectiqlab-0.1.0/hectiqlab/tui/widgets/chart.py +203 -0
  113. hectiqlab-0.1.0/hectiqlab/tui/widgets/columns.py +79 -0
  114. hectiqlab-0.1.0/hectiqlab/tui/widgets/filter.py +129 -0
  115. hectiqlab-0.1.0/hectiqlab/tui/widgets/gantt.py +193 -0
  116. hectiqlab-0.1.0/hectiqlab/tui/widgets/gauge.py +76 -0
  117. hectiqlab-0.1.0/hectiqlab/tui/widgets/kpi.py +120 -0
  118. hectiqlab-0.1.0/hectiqlab/tui/widgets/live.py +79 -0
  119. hectiqlab-0.1.0/hectiqlab/tui/widgets/multiples.py +102 -0
  120. hectiqlab-0.1.0/hectiqlab/tui/widgets/places.py +57 -0
  121. hectiqlab-0.1.0/hectiqlab/tui/widgets/ranked.py +100 -0
  122. hectiqlab-0.1.0/hectiqlab/tui/widgets/readout.py +100 -0
  123. hectiqlab-0.1.0/hectiqlab/tui/widgets/ribbon.py +90 -0
  124. hectiqlab-0.1.0/hectiqlab/tui/widgets/sections.py +84 -0
  125. hectiqlab-0.1.0/hectiqlab/tui/widgets/series.py +181 -0
  126. hectiqlab-0.1.0/hectiqlab/tui/widgets/share.py +86 -0
  127. hectiqlab-0.1.0/hectiqlab/tui/widgets/sortable.py +442 -0
  128. hectiqlab-0.1.0/hectiqlab/tui/widgets/state.py +38 -0
  129. hectiqlab-0.1.0/hectiqlab/tui/widgets/tile.py +130 -0
  130. hectiqlab-0.1.0/hectiqlab/tui/widgets/travel.py +162 -0
  131. hectiqlab-0.1.0/hectiqlab/versioned/__init__.py +5 -0
  132. hectiqlab-0.1.0/hectiqlab/versioned/namespace.py +492 -0
  133. hectiqlab-0.1.0/hectiqlab/versioned/record.py +88 -0
  134. hectiqlab-0.1.0/pyproject.toml +216 -0
  135. hectiqlab-0.1.0/testing/hectiqlab_stack.py +198 -0
  136. hectiqlab-0.1.0/tests/conftest.py +13 -0
  137. hectiqlab-0.1.0/tests/double.py +131 -0
  138. hectiqlab-0.1.0/tests/integration/test_command_line.py +93 -0
  139. hectiqlab-0.1.0/tests/integration/test_recording.py +100 -0
  140. hectiqlab-0.1.0/tests/integration/test_the_wire.py +23 -0
  141. hectiqlab-0.1.0/tests/integration/test_uploads.py +121 -0
  142. hectiqlab-0.1.0/tests/tui/conftest.py +40 -0
  143. hectiqlab-0.1.0/tests/tui/helpers.py +80 -0
  144. hectiqlab-0.1.0/tests/tui/integration/conftest.py +18 -0
  145. hectiqlab-0.1.0/tests/tui/integration/test_against_the_api.py +132 -0
  146. hectiqlab-0.1.0/tests/tui/seed.py +999 -0
  147. hectiqlab-0.1.0/tests/tui/test_chrome.py +78 -0
  148. hectiqlab-0.1.0/tests/tui/test_compare.py +22 -0
  149. hectiqlab-0.1.0/tests/tui/test_dashboard.py +363 -0
  150. hectiqlab-0.1.0/tests/tui/test_groups.py +431 -0
  151. hectiqlab-0.1.0/tests/tui/test_home.py +214 -0
  152. hectiqlab-0.1.0/tests/tui/test_lab.py +283 -0
  153. hectiqlab-0.1.0/tests/tui/test_places.py +172 -0
  154. hectiqlab-0.1.0/tests/tui/test_primary.py +157 -0
  155. hectiqlab-0.1.0/tests/tui/test_remote.py +222 -0
  156. hectiqlab-0.1.0/tests/tui/test_run_screen.py +288 -0
  157. hectiqlab-0.1.0/tests/tui/test_versioned_screen.py +247 -0
  158. hectiqlab-0.1.0/tests/unit/conftest.py +25 -0
  159. hectiqlab-0.1.0/tests/unit/test_cli.py +193 -0
  160. hectiqlab-0.1.0/tests/unit/test_credentials.py +123 -0
  161. hectiqlab-0.1.0/tests/unit/test_files.py +277 -0
  162. hectiqlab-0.1.0/tests/unit/test_linear.py +214 -0
  163. hectiqlab-0.1.0/tests/unit/test_namespaces.py +144 -0
  164. hectiqlab-0.1.0/tests/unit/test_progress.py +37 -0
  165. hectiqlab-0.1.0/tests/unit/test_records.py +102 -0
  166. hectiqlab-0.1.0/tests/unit/test_run.py +222 -0
  167. hectiqlab-0.1.0/tests/unit/test_stages.py +90 -0
  168. hectiqlab-0.1.0/tests/unit/test_storage.py +84 -0
  169. hectiqlab-0.1.0/tests/unit/test_transport.py +102 -0
  170. hectiqlab-0.1.0/tests/unit/test_worker.py +123 -0
  171. hectiqlab-0.1.0/tests/unit/test_workspace.py +64 -0
  172. hectiqlab-0.1.0/uv.lock +861 -0
@@ -0,0 +1,281 @@
1
+ # Created by https://www.toptal.com/developers/gitignore/api/vue,nextjs,vuejs,python
2
+ # Edit at https://www.toptal.com/developers/gitignore?templates=vue,nextjs,vuejs,python
3
+
4
+ ### NextJS ###
5
+ # dependencies
6
+ /node_modules
7
+ /.pnp
8
+ .pnp.js
9
+
10
+ # testing
11
+ /coverage
12
+
13
+ # next.js
14
+ /.next/
15
+ /out/
16
+
17
+ # production
18
+ /build
19
+
20
+ # misc
21
+ .DS_Store
22
+ *.pem
23
+
24
+ # debug
25
+ npm-debug.log*
26
+ yarn-debug.log*
27
+ yarn-error.log*
28
+ .pnpm-debug.log*
29
+
30
+ # local env files
31
+ .env*.local
32
+
33
+ # vercel
34
+ .vercel
35
+
36
+ # typescript
37
+ *.tsbuildinfo
38
+ next-env.d.ts
39
+
40
+ ### Python ###
41
+ # Byte-compiled / optimized / DLL files
42
+ __pycache__/
43
+ *.py[cod]
44
+ *$py.class
45
+
46
+ # C extensions
47
+ *.so
48
+
49
+ # Distribution / packaging
50
+ .Python
51
+ build/
52
+ develop-eggs/
53
+ dist/
54
+ downloads/
55
+ eggs/
56
+ .eggs/
57
+ lib/
58
+ lib64/
59
+ parts/
60
+ sdist/
61
+ var/
62
+ wheels/
63
+ share/python-wheels/
64
+ *.egg-info/
65
+ .installed.cfg
66
+ *.egg
67
+ MANIFEST
68
+
69
+ # PyInstaller
70
+ # Usually these files are written by a python script from a template
71
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
72
+ *.manifest
73
+ *.spec
74
+
75
+ # Installer logs
76
+ pip-log.txt
77
+ pip-delete-this-directory.txt
78
+
79
+ # Unit test / coverage reports
80
+ htmlcov/
81
+ .tox/
82
+ .nox/
83
+ .coverage
84
+ .coverage.*
85
+ .cache
86
+ nosetests.xml
87
+ coverage.xml
88
+ *.cover
89
+ *.py,cover
90
+ .hypothesis/
91
+ .pytest_cache/
92
+ cover/
93
+
94
+ # Translations
95
+ *.mo
96
+ *.pot
97
+
98
+ # Django stuff:
99
+ *.log
100
+ local_settings.py
101
+ db.sqlite3
102
+ db.sqlite3-journal
103
+
104
+ # Flask stuff:
105
+ instance/
106
+ .webassets-cache
107
+
108
+ # Scrapy stuff:
109
+ .scrapy
110
+
111
+ # Sphinx documentation
112
+ docs/_build/
113
+
114
+ # PyBuilder
115
+ .pybuilder/
116
+ target/
117
+
118
+ # Jupyter Notebook
119
+ .ipynb_checkpoints
120
+
121
+ # IPython
122
+ profile_default/
123
+ ipython_config.py
124
+
125
+ # pyenv
126
+ # For a library or package, you might want to ignore these files since the code is
127
+ # intended to run in multiple environments; otherwise, check them in:
128
+ # .python-version
129
+
130
+ # pipenv
131
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
132
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
133
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
134
+ # install all needed dependencies.
135
+ #Pipfile.lock
136
+
137
+ # poetry
138
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
139
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
140
+ # commonly ignored for libraries.
141
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
142
+ #poetry.lock
143
+
144
+ # pdm
145
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
146
+ #pdm.lock
147
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
148
+ # in version control.
149
+ # https://pdm.fming.dev/#use-with-ide
150
+ .pdm.toml
151
+
152
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
153
+ __pypackages__/
154
+
155
+ # Celery stuff
156
+ celerybeat-schedule
157
+ celerybeat.pid
158
+
159
+ # SageMath parsed files
160
+ *.sage.py
161
+
162
+ # Environments
163
+ .env
164
+ .venv
165
+ env/
166
+ venv/
167
+ ENV/
168
+ env.bak/
169
+ venv.bak/
170
+
171
+ # Spyder project settings
172
+ .spyderproject
173
+ .spyproject
174
+
175
+ # Rope project settings
176
+ .ropeproject
177
+
178
+ # mkdocs documentation
179
+ /site
180
+
181
+ # mypy
182
+ .mypy_cache/
183
+ .dmypy.json
184
+ dmypy.json
185
+
186
+ # Pyre type checker
187
+ .pyre/
188
+
189
+ # pytype static type analyzer
190
+ .pytype/
191
+
192
+ dev
193
+
194
+ # Cython debug symbols
195
+ cython_debug/
196
+
197
+ # PyCharm
198
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
199
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
200
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
201
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
202
+ #.idea/
203
+
204
+ ### Python Patch ###
205
+ # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
206
+ poetry.toml
207
+
208
+ # ruff
209
+ .ruff_cache/
210
+
211
+ # LSP config files
212
+ pyrightconfig.json
213
+
214
+ ### Vue ###
215
+ # gitignore template for Vue.js projects
216
+ #
217
+ # Recommended template: Node.gitignore
218
+
219
+ # TODO: where does this rule come from?
220
+ docs/_book
221
+
222
+ # TODO: where does this rule come from?
223
+ test/
224
+
225
+ ### Vuejs ###
226
+ # Recommended template: Node.gitignore
227
+
228
+ node_modules/
229
+ npm-debug.log
230
+ yarn-error.log
231
+
232
+ # End of https://www.toptal.com/developers/gitignore/api/vue,nextjs,vuejs,python
233
+
234
+
235
+ ### VSCode ###
236
+ .vscode/*
237
+ *.code-workspace
238
+ # Created by https://www.toptal.com/developers/gitignore/api/terraform
239
+ # Edit at https://www.toptal.com/developers/gitignore?templates=terraform
240
+
241
+ ### Terraform ###
242
+ # Local .terraform directories
243
+ **/.terraform/*
244
+
245
+ # .tfstate files
246
+ *.tfstate
247
+ *.tfstate.*
248
+
249
+ # Crash log files
250
+ crash.log
251
+ crash.*.log
252
+
253
+ # Exclude all .tfvars files, which are likely to contain sensitive data, such as
254
+ # password, private keys, and other secrets. These should not be part of version
255
+ # control as they are data points which are potentially sensitive and subject
256
+ # to change depending on the environment.
257
+ *.tfvars
258
+ *.tfvars.json
259
+
260
+ # Ignore override files as they are usually used to override resources locally and so
261
+ # are not checked in
262
+ override.tf
263
+ override.tf.json
264
+ *_override.tf
265
+ *_override.tf.json
266
+
267
+ # Include override files you do wish to add to version control using negated pattern
268
+ # !example_override.tf
269
+
270
+ # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
271
+ # example: *tfplan*
272
+
273
+ # Ignore CLI configuration files
274
+ .terraformrc
275
+ terraform.rc
276
+
277
+ # End of https://www.toptal.com/developers/gitignore/api/terraform
278
+
279
+ ## Dev scripts
280
+ dev.ipynb
281
+ dev.py
@@ -0,0 +1 @@
1
+ 3.13
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.5
2
+ Name: hectiqlab
3
+ Version: 0.1.0
4
+ Summary: Record runs, stages, metrics, datasets and models to Hectiq Lab, from a script or the command line.
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: httpx>=0.27
7
+ Requires-Dist: pydantic-settings>=2.3
8
+ Requires-Dist: pydantic>=2.7
9
+ Requires-Dist: rich>=13.7
10
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
11
+ Provides-Extra: cli
12
+ Requires-Dist: typer>=0.12; extra == 'cli'
13
+ Provides-Extra: parquet
14
+ Requires-Dist: pyarrow>=15; extra == 'parquet'
15
+ Provides-Extra: tui
16
+ Requires-Dist: textual-plotext>=1.0; extra == 'tui'
17
+ Requires-Dist: textual>=8.2; extra == 'tui'
18
+ Requires-Dist: typer>=0.12; extra == 'tui'
19
+ Description-Content-Type: text/markdown
20
+
21
+ # hectiqlab
22
+
23
+ Record runs, stages, metrics, datasets and models to [Hectiq Lab](https://lab.hectiq.ai), from a training script or the command line. Everything goes to the API the web app reads, over HTTP, from one background thread, so a training loop never waits on the network.
24
+
25
+ This package lives beside `pyhectiqlab` (in `sdk/`) and does not replace it: both can be installed together, and they share `~/.hectiq-lab/credentials.toml`.
26
+
27
+ ```bash
28
+ pip install hectiqlab # the SDK
29
+ pip install "hectiqlab[cli]" # and the `hlab` command line
30
+ pip install "hectiqlab[tui]" # and the dashboard `hlab ui` opens
31
+ pip install "hectiqlab[tui,parquet]" # and parquet previews in it, which take pyarrow
32
+ ```
33
+
34
+ ## A script
35
+
36
+ ```python
37
+ import hectiqlab as hl
38
+
39
+ with hl.run(
40
+ "two-tower, 3 epochs",
41
+ category="training",
42
+ tags=["linear:ENG-42"],
43
+ config={"lr": 1e-3, "epochs": 3},
44
+ ):
45
+ data = hl.datasets.get("interactions").unwrap()
46
+ hl.datasets.attach(data.id)
47
+ with hl.stage("train"):
48
+ for epoch in hl.each(range(3), "epoch"):
49
+ loss = train_one_epoch()
50
+ hl.add_metric("loss", step=epoch, value=loss)
51
+ hl.models.create("checkpoints/", name="two-tower").result()
52
+ ```
53
+
54
+ A run captures its commit, branch, diff, installed packages, machine and command line as it opens, and ends `completed`, `failed` (with its traceback) or `stopped`, whether it was opened with `with` or left open until the script crashed or exited. One exit it cannot see: a run opened without `with` in a script that calls `sys.exit(1)` ends `completed`, because Python never hands a `SystemExit` to the exception hook; open the run with `with` to record the exit status. Stages nest: a `with`, a decorated function or a named `each` opens a stage inside whatever is open. Reads and changes return a `Result`; uploads and downloads return a `Future`, and an upload made while a run is open holds the run open until it lands, however long that takes (the bar shows it moving; Ctrl-C ends the run `stopped` without it).
55
+
56
+ An API that is down, slow or refusing never raises in the middle of a training loop: a failed read or change is an `Err`, and what a run recorded that did not land is said once, as a warning, when the run closes (`run.result()` raises it instead). A mistake in the call itself does raise, at once: a metric or a stage with no run open, a category the web app does not know.
57
+
58
+ Uploads and downloads draw a progress bar on stderr when it is a terminal. `progress=False` on the call, or `HECTIQLAB_PROGRESS=false`, draws none; `progress=True` draws one anyway.
59
+
60
+ The project comes from `project=`, `hl.set_project(...)`, `HECTIQLAB_PROJECT`, or the `.hectiqlab/config.toml` that `hlab init` writes. `HECTIQLAB_DISABLE=1`, or a `RANK`/`LOCAL_RANK` other than 0, records nothing.
61
+
62
+ A tag written `linear:ENG-42` speaks to that Linear issue, and `linear:project:<slug>` to a Linear project (the slug is the end of the project's Linear address). A run carrying one comments there when it starts, when it ends, and when the tag is attached; a dataset or a model version comments when such a tag is attached to it, which is how a deliverable is marked. Creating a version or removing a tag says nothing, and a bare `ENG-42` or `GPT-4` never speaks to Linear. The key belongs to the project, since a client's project comments in the client's Linear: `hlab login --linear -p org/project` keeps it in the credentials file as `[linear."org/project"]`, and `LINEAR_API_KEY` overrides it for one process. A project without a key comments nowhere; there is no key shared by every project.
63
+
64
+ ## The command line
65
+
66
+ ```bash
67
+ hlab login # make a key with your email and password
68
+ hlab init hectiq-ai/recsys # this checkout records to that project
69
+ hlab run list --tag linear:ENG-42
70
+ hlab run get 42 --json # runs are named by their rank, or their id
71
+ hlab run stages 42
72
+ hlab run tag 42 best # dataset and model tag the same way
73
+ hlab metric get 42 loss
74
+ hlab dataset create data/ --name interactions --no-upload
75
+ hlab model download two-tower --version 1.3
76
+ hlab artifact get art_4f2c
77
+ ```
78
+
79
+ Every command that reads or changes something takes `--json`, and prints one JSON document on stdout; prompts and progress bars go to stderr.
80
+
81
+ ## The dashboard
82
+
83
+ `hlab ui` opens a terminal dashboard onto a project, `hectiqlab.tui`; `?` lists the keys. It opens on the project the SDK would record to (`-p`, `HECTIQLAB_PROJECT`, or `.hectiqlab/config.toml`), and on the switcher when nothing names one; `P` switches from anywhere. `1` to `5` are the dashboard, runs, datasets, models and tags.
84
+
85
+ Everything it shows comes from the API the web app reads, through the SDK's own read functions: it refreshes every second, and reads the series of the open runs and of those that ended in the last fourteen days, a hundred runs to a request. It reads only the series on screen: an older run's come when it is opened. An open run that has given no sign of life for an hour, no change to its row, no sample, no stage, is shown as silent and read once a minute. A file previews over its signed address a range at a time, so a 20 GB parquet shows its schema, its row count and its first rows without being downloaded; without the `parquet` extra, a parquet says what to install instead.
86
+
87
+ A screen (`tui/screens/`, built from `tui/widgets/`) never calls the SDK. It asks `tui/reads/`, and draws the SDK's own records. Importing `hectiqlab` never imports the dashboard.
88
+
89
+ ## Development
90
+
91
+ ```bash
92
+ cd sdk_v2
93
+ uv sync
94
+ uv run ruff check . && uv run ruff format --check . && uv run ty check && uv run lint-imports
95
+ uv run pytest -m "not integration"
96
+ ```
97
+
98
+ The integration tests talk to the API running in `api/compose.yaml`, logged in as the user they seed it with, whose email and password come from your environment. They are skipped when the stack is not up or the login is not set, and fail instead with `HECTIQLAB_INTEGRATION=required`, as in CI:
99
+
100
+ ```bash
101
+ docker compose -f ../api/compose.yaml up -d --build
102
+ export HECTIQLAB_TEST_EMAIL=you@example.com HECTIQLAB_TEST_PASSWORD=... # 8+ chars, upper, lower, digit
103
+ uv run pytest -m integration
104
+ ```
105
+
106
+ The stack, its login, the fresh key and project each test gets, and the clean process every test starts from are in `testing/hectiqlab_stack.py`, a pytest plugin every test loads. It is not part of the wheel. The dashboard's tests, in `tests/tui/`, read a seeded project instead of the API, except those in `tests/tui/integration/`.
107
+
108
+ On a pull request that touches `api/` or `sdk_v2/`, `.github/workflows/hectiqlab_checks.yml` runs these checks and the unit tests on Python 3.10 and 3.13, and the integration tests against one stack.
109
+
110
+ ## Releasing
111
+
112
+ `hectiqlab` is one package, the SDK, the command line and the dashboard at one version. A release is one button: **Actions → Release hectiqlab → Run workflow** on `main`, picking `patch`, `minor` or `major` (or `gh workflow run release_hectiqlab.yml -f bump=minor`).
113
+
114
+ The workflow (`.github/workflows/release_hectiqlab.yml`) runs the checks, including the integration tests; moves the version and re-locks; builds the package and checks its metadata; commits `Release hectiqlab X.Y.Z` to `main` and tags it `hectiqlab-vX.Y.Z`; creates the GitHub release with the subjects of the commits under `sdk_v2/` since the last release; then publishes it to PyPI. Nobody edits a version by hand. If only the publishing fails, re-running that job publishes the distributions already built.
115
+
116
+ The version steps live in `.github/scripts/release_hectiqlab.py`, which runs the same on a clone (`bump`, `notes`, `check`).
117
+
118
+ Once, before the first release, and close together, because a pending publisher does not reserve the name ([PyPI docs](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/)):
119
+
120
+ 1. On pypi.org, under your account's **Publishing** page, add a GitHub Actions pending publisher for the project `hectiqlab`: repository `HectiqAI/hectiq-lab-revision`, workflow `release_hectiqlab.yml`, environment `pypi`.
121
+ 2. In the repository's settings, create the `pypi` environment. Required reviewers on it make every release wait for an approval before it publishes.
122
+ 3. Run the first release. It ships the version the pyproject already declares, `0.1.0`, whichever bump is picked; every release after it bumps.
@@ -0,0 +1,102 @@
1
+ # hectiqlab
2
+
3
+ Record runs, stages, metrics, datasets and models to [Hectiq Lab](https://lab.hectiq.ai), from a training script or the command line. Everything goes to the API the web app reads, over HTTP, from one background thread, so a training loop never waits on the network.
4
+
5
+ This package lives beside `pyhectiqlab` (in `sdk/`) and does not replace it: both can be installed together, and they share `~/.hectiq-lab/credentials.toml`.
6
+
7
+ ```bash
8
+ pip install hectiqlab # the SDK
9
+ pip install "hectiqlab[cli]" # and the `hlab` command line
10
+ pip install "hectiqlab[tui]" # and the dashboard `hlab ui` opens
11
+ pip install "hectiqlab[tui,parquet]" # and parquet previews in it, which take pyarrow
12
+ ```
13
+
14
+ ## A script
15
+
16
+ ```python
17
+ import hectiqlab as hl
18
+
19
+ with hl.run(
20
+ "two-tower, 3 epochs",
21
+ category="training",
22
+ tags=["linear:ENG-42"],
23
+ config={"lr": 1e-3, "epochs": 3},
24
+ ):
25
+ data = hl.datasets.get("interactions").unwrap()
26
+ hl.datasets.attach(data.id)
27
+ with hl.stage("train"):
28
+ for epoch in hl.each(range(3), "epoch"):
29
+ loss = train_one_epoch()
30
+ hl.add_metric("loss", step=epoch, value=loss)
31
+ hl.models.create("checkpoints/", name="two-tower").result()
32
+ ```
33
+
34
+ A run captures its commit, branch, diff, installed packages, machine and command line as it opens, and ends `completed`, `failed` (with its traceback) or `stopped`, whether it was opened with `with` or left open until the script crashed or exited. One exit it cannot see: a run opened without `with` in a script that calls `sys.exit(1)` ends `completed`, because Python never hands a `SystemExit` to the exception hook; open the run with `with` to record the exit status. Stages nest: a `with`, a decorated function or a named `each` opens a stage inside whatever is open. Reads and changes return a `Result`; uploads and downloads return a `Future`, and an upload made while a run is open holds the run open until it lands, however long that takes (the bar shows it moving; Ctrl-C ends the run `stopped` without it).
35
+
36
+ An API that is down, slow or refusing never raises in the middle of a training loop: a failed read or change is an `Err`, and what a run recorded that did not land is said once, as a warning, when the run closes (`run.result()` raises it instead). A mistake in the call itself does raise, at once: a metric or a stage with no run open, a category the web app does not know.
37
+
38
+ Uploads and downloads draw a progress bar on stderr when it is a terminal. `progress=False` on the call, or `HECTIQLAB_PROGRESS=false`, draws none; `progress=True` draws one anyway.
39
+
40
+ The project comes from `project=`, `hl.set_project(...)`, `HECTIQLAB_PROJECT`, or the `.hectiqlab/config.toml` that `hlab init` writes. `HECTIQLAB_DISABLE=1`, or a `RANK`/`LOCAL_RANK` other than 0, records nothing.
41
+
42
+ A tag written `linear:ENG-42` speaks to that Linear issue, and `linear:project:<slug>` to a Linear project (the slug is the end of the project's Linear address). A run carrying one comments there when it starts, when it ends, and when the tag is attached; a dataset or a model version comments when such a tag is attached to it, which is how a deliverable is marked. Creating a version or removing a tag says nothing, and a bare `ENG-42` or `GPT-4` never speaks to Linear. The key belongs to the project, since a client's project comments in the client's Linear: `hlab login --linear -p org/project` keeps it in the credentials file as `[linear."org/project"]`, and `LINEAR_API_KEY` overrides it for one process. A project without a key comments nowhere; there is no key shared by every project.
43
+
44
+ ## The command line
45
+
46
+ ```bash
47
+ hlab login # make a key with your email and password
48
+ hlab init hectiq-ai/recsys # this checkout records to that project
49
+ hlab run list --tag linear:ENG-42
50
+ hlab run get 42 --json # runs are named by their rank, or their id
51
+ hlab run stages 42
52
+ hlab run tag 42 best # dataset and model tag the same way
53
+ hlab metric get 42 loss
54
+ hlab dataset create data/ --name interactions --no-upload
55
+ hlab model download two-tower --version 1.3
56
+ hlab artifact get art_4f2c
57
+ ```
58
+
59
+ Every command that reads or changes something takes `--json`, and prints one JSON document on stdout; prompts and progress bars go to stderr.
60
+
61
+ ## The dashboard
62
+
63
+ `hlab ui` opens a terminal dashboard onto a project, `hectiqlab.tui`; `?` lists the keys. It opens on the project the SDK would record to (`-p`, `HECTIQLAB_PROJECT`, or `.hectiqlab/config.toml`), and on the switcher when nothing names one; `P` switches from anywhere. `1` to `5` are the dashboard, runs, datasets, models and tags.
64
+
65
+ Everything it shows comes from the API the web app reads, through the SDK's own read functions: it refreshes every second, and reads the series of the open runs and of those that ended in the last fourteen days, a hundred runs to a request. It reads only the series on screen: an older run's come when it is opened. An open run that has given no sign of life for an hour, no change to its row, no sample, no stage, is shown as silent and read once a minute. A file previews over its signed address a range at a time, so a 20 GB parquet shows its schema, its row count and its first rows without being downloaded; without the `parquet` extra, a parquet says what to install instead.
66
+
67
+ A screen (`tui/screens/`, built from `tui/widgets/`) never calls the SDK. It asks `tui/reads/`, and draws the SDK's own records. Importing `hectiqlab` never imports the dashboard.
68
+
69
+ ## Development
70
+
71
+ ```bash
72
+ cd sdk_v2
73
+ uv sync
74
+ uv run ruff check . && uv run ruff format --check . && uv run ty check && uv run lint-imports
75
+ uv run pytest -m "not integration"
76
+ ```
77
+
78
+ The integration tests talk to the API running in `api/compose.yaml`, logged in as the user they seed it with, whose email and password come from your environment. They are skipped when the stack is not up or the login is not set, and fail instead with `HECTIQLAB_INTEGRATION=required`, as in CI:
79
+
80
+ ```bash
81
+ docker compose -f ../api/compose.yaml up -d --build
82
+ export HECTIQLAB_TEST_EMAIL=you@example.com HECTIQLAB_TEST_PASSWORD=... # 8+ chars, upper, lower, digit
83
+ uv run pytest -m integration
84
+ ```
85
+
86
+ The stack, its login, the fresh key and project each test gets, and the clean process every test starts from are in `testing/hectiqlab_stack.py`, a pytest plugin every test loads. It is not part of the wheel. The dashboard's tests, in `tests/tui/`, read a seeded project instead of the API, except those in `tests/tui/integration/`.
87
+
88
+ On a pull request that touches `api/` or `sdk_v2/`, `.github/workflows/hectiqlab_checks.yml` runs these checks and the unit tests on Python 3.10 and 3.13, and the integration tests against one stack.
89
+
90
+ ## Releasing
91
+
92
+ `hectiqlab` is one package, the SDK, the command line and the dashboard at one version. A release is one button: **Actions → Release hectiqlab → Run workflow** on `main`, picking `patch`, `minor` or `major` (or `gh workflow run release_hectiqlab.yml -f bump=minor`).
93
+
94
+ The workflow (`.github/workflows/release_hectiqlab.yml`) runs the checks, including the integration tests; moves the version and re-locks; builds the package and checks its metadata; commits `Release hectiqlab X.Y.Z` to `main` and tags it `hectiqlab-vX.Y.Z`; creates the GitHub release with the subjects of the commits under `sdk_v2/` since the last release; then publishes it to PyPI. Nobody edits a version by hand. If only the publishing fails, re-running that job publishes the distributions already built.
95
+
96
+ The version steps live in `.github/scripts/release_hectiqlab.py`, which runs the same on a clone (`bump`, `notes`, `check`).
97
+
98
+ Once, before the first release, and close together, because a pending publisher does not reserve the name ([PyPI docs](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/)):
99
+
100
+ 1. On pypi.org, under your account's **Publishing** page, add a GitHub Actions pending publisher for the project `hectiqlab`: repository `HectiqAI/hectiq-lab-revision`, workflow `release_hectiqlab.yml`, environment `pypi`.
101
+ 2. In the repository's settings, create the `pypi` environment. Required reviewers on it make every release wait for an approval before it publishes.
102
+ 3. Run the first release. It ships the version the pyproject already declares, `0.1.0`, whichever bump is picked; every release after it bumps.
@@ -0,0 +1,64 @@
1
+ """hectiqlab: record runs, stages, metrics, datasets and models to Hectiq Lab.
2
+
3
+ Example::
4
+
5
+ import hectiqlab as hl
6
+
7
+ with hl.run("two-tower", category="training", config={"lr": 1e-3}):
8
+ for epoch in hl.each(range(3), "epoch"):
9
+ hl.add_metric("loss", step=epoch, value=train_one_epoch())
10
+ """
11
+
12
+ from importlib.metadata import version
13
+
14
+ from hectiqlab import artifacts, metrics, projects, records, runs, tags
15
+ from hectiqlab.errors import (
16
+ LabAuthError,
17
+ LabConnectionError,
18
+ LabError,
19
+ LabNotFoundError,
20
+ LabServerError,
21
+ LabValidationError,
22
+ LabWarning,
23
+ )
24
+ from hectiqlab.metrics import add_metric
25
+ from hectiqlab.projects.workspace import set_project
26
+ from hectiqlab.result import Err, Ok, Result
27
+ from hectiqlab.runs.factory import run
28
+ from hectiqlab.runs.handle import Run
29
+ from hectiqlab.session import shutdown
30
+ from hectiqlab.stages.opening import each, stage
31
+ from hectiqlab.stages.stage import Stage
32
+ from hectiqlab.versioned import datasets, models
33
+
34
+ __version__ = version("hectiqlab")
35
+
36
+ __all__ = [
37
+ "Err",
38
+ "LabAuthError",
39
+ "LabConnectionError",
40
+ "LabError",
41
+ "LabNotFoundError",
42
+ "LabServerError",
43
+ "LabValidationError",
44
+ "LabWarning",
45
+ "Ok",
46
+ "Result",
47
+ "Run",
48
+ "Stage",
49
+ "__version__",
50
+ "add_metric",
51
+ "artifacts",
52
+ "datasets",
53
+ "each",
54
+ "metrics",
55
+ "models",
56
+ "projects",
57
+ "records",
58
+ "run",
59
+ "runs",
60
+ "set_project",
61
+ "shutdown",
62
+ "stage",
63
+ "tags",
64
+ ]
@@ -0,0 +1 @@
1
+ """The SDK's machinery: what every module of the package imports, and no user ever does."""