tqdm-live 0.7.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.
- tqdm_live-0.7.0/.gitignore +9 -0
- tqdm_live-0.7.0/PKG-INFO +104 -0
- tqdm_live-0.7.0/README.md +79 -0
- tqdm_live-0.7.0/pyproject.toml +38 -0
- tqdm_live-0.7.0/tests/conftest.py +19 -0
- tqdm_live-0.7.0/tests/test_accounts.py +530 -0
- tqdm_live-0.7.0/tests/test_tqdm_live.py +1112 -0
- tqdm_live-0.7.0/tqdm_live/__init__.py +697 -0
- tqdm_live-0.7.0/tqdm_live/cli.py +584 -0
tqdm_live-0.7.0/PKG-INFO
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: tqdm-live
|
|
3
|
+
Version: 0.7.0
|
|
4
|
+
Summary: Stream your tqdm progress bars to any browser, realtime. Zero config.
|
|
5
|
+
Project-URL: Homepage, https://runpeek.app
|
|
6
|
+
Project-URL: Documentation, https://runpeek.app/docs
|
|
7
|
+
Project-URL: Pricing, https://runpeek.app/pricing
|
|
8
|
+
Author-email: Bitgate <kevin@bitgate.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: ml,monitoring,progress,progress-bar,tqdm,training
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Framework :: Jupyter
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Topic :: System :: Monitoring
|
|
22
|
+
Requires-Python: >=3.8
|
|
23
|
+
Requires-Dist: tqdm>=4.60
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# tqdm-live
|
|
27
|
+
|
|
28
|
+
Stream your tqdm progress bars to any browser, realtime. Zero config, anonymous by default.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install tqdm-live
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from tqdm_live import tqdm
|
|
36
|
+
|
|
37
|
+
for epoch in tqdm(range(epochs)):
|
|
38
|
+
train_one_epoch()
|
|
39
|
+
|
|
40
|
+
# prints: runpeek ▶ https://runpeek.app/b/<uuid> (expires 30 min after the last update; 'tqdml login' saves runs)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Or leave your code completely untouched:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import tqdm_live
|
|
47
|
+
tqdm_live.patch() # every tqdm bar in this process now streams
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Open the printed URL on your phone. Done.
|
|
51
|
+
|
|
52
|
+
## Runs
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
tqdm_live.start_run("train-resnet") # one link for every bar in this process
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
tqdml run -- python train.py --epochs 30
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
A run shows the process lifecycle next to its bars and closes with the real exit code. `tqdml run` wraps any command, streams its stdout/stderr and patches tqdm in the child without code changes.
|
|
63
|
+
|
|
64
|
+
## Alerts
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
tqdm_live.start_run("train-resnet")
|
|
68
|
+
tqdm_live.notify("https://discord.com/api/webhooks/...") # finished or failed
|
|
69
|
+
tqdm_live.notify("https://hooks.slack.com/services/...", events=("failed",), stall_after_minutes=15)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Discord and Slack webhooks get a formatted message, any other URL receives the raw JSON event. `stall_after_minutes` (1 to 1440) also alerts when the run goes silent that long. `notify()` needs an active run and returns whether the webhook was registered. `TQDMLIVE_NOTIFY` (comma-separated URLs) registers webhooks for every run, `tqdml run` included.
|
|
73
|
+
|
|
74
|
+
## Save runs to your dashboard
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
tqdml login # approve once in the browser
|
|
78
|
+
tqdml whoami # the account your runs are saved to
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Once logged in, every script that shows a bar is saved as a run named after the script, next to your `start_run()` and `tqdml run` runs. On servers and CI, set `RUNPEEK_TOKEN` instead (create a token on the dashboard's Setup page). `tqdml logout` removes the saved login.
|
|
82
|
+
|
|
83
|
+
Notebooks, IPython and the Python REPL are the exception: bars there stay anonymous, so an idle kernel never becomes a run.
|
|
84
|
+
To save an experiment from a notebook, call `tqdm_live.start_run("my-experiment")` before the loop and `tqdm_live.end_run()` when it's done.
|
|
85
|
+
|
|
86
|
+
Free accounts keep 7 days of history, [Pro](https://runpeek.app/pricing) ($9/mo) keeps a year. Over the monthly saved-run limit a run still streams live, it just isn't saved.
|
|
87
|
+
|
|
88
|
+
## Notes
|
|
89
|
+
|
|
90
|
+
- Bars are addressed by unguessable UUIDs. No account needed, logging in is optional.
|
|
91
|
+
- Heartbeats are throttled (~0.75s) and sent from a daemon thread; your loop never blocks on the network, and send failures never raise into your code.
|
|
92
|
+
- An unsaved bar or run expires 30 minutes after its last heartbeat.
|
|
93
|
+
|
|
94
|
+
## Config (all optional)
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import tqdm_live
|
|
98
|
+
tqdm_live.setup(endpoint="https://runpeek.app", link_base="https://runpeek.link", min_interval=0.75, token="rpk_...")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Env vars: `RUNPEEK_TOKEN`, `TQDMLIVE_ENDPOINT`, `TQDMLIVE_LINK_BASE`, `TQDMLIVE_MIN_INTERVAL`, `TQDMLIVE_NOTIFY`, `TQDMLIVE_DISABLE=1`.
|
|
102
|
+
Printed view links use the link base; it defaults to the endpoint itself when unset, so
|
|
103
|
+
self-hosted setups keep working. A token is picked from `setup(token=...)`, then `RUNPEEK_TOKEN`,
|
|
104
|
+
then the login saved by `tqdml login` (`~/.config/runpeek/config.json`).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# tqdm-live
|
|
2
|
+
|
|
3
|
+
Stream your tqdm progress bars to any browser, realtime. Zero config, anonymous by default.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install tqdm-live
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from tqdm_live import tqdm
|
|
11
|
+
|
|
12
|
+
for epoch in tqdm(range(epochs)):
|
|
13
|
+
train_one_epoch()
|
|
14
|
+
|
|
15
|
+
# prints: runpeek ▶ https://runpeek.app/b/<uuid> (expires 30 min after the last update; 'tqdml login' saves runs)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or leave your code completely untouched:
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
import tqdm_live
|
|
22
|
+
tqdm_live.patch() # every tqdm bar in this process now streams
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Open the printed URL on your phone. Done.
|
|
26
|
+
|
|
27
|
+
## Runs
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
tqdm_live.start_run("train-resnet") # one link for every bar in this process
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
tqdml run -- python train.py --epochs 30
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
A run shows the process lifecycle next to its bars and closes with the real exit code. `tqdml run` wraps any command, streams its stdout/stderr and patches tqdm in the child without code changes.
|
|
38
|
+
|
|
39
|
+
## Alerts
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
tqdm_live.start_run("train-resnet")
|
|
43
|
+
tqdm_live.notify("https://discord.com/api/webhooks/...") # finished or failed
|
|
44
|
+
tqdm_live.notify("https://hooks.slack.com/services/...", events=("failed",), stall_after_minutes=15)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Discord and Slack webhooks get a formatted message, any other URL receives the raw JSON event. `stall_after_minutes` (1 to 1440) also alerts when the run goes silent that long. `notify()` needs an active run and returns whether the webhook was registered. `TQDMLIVE_NOTIFY` (comma-separated URLs) registers webhooks for every run, `tqdml run` included.
|
|
48
|
+
|
|
49
|
+
## Save runs to your dashboard
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
tqdml login # approve once in the browser
|
|
53
|
+
tqdml whoami # the account your runs are saved to
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Once logged in, every script that shows a bar is saved as a run named after the script, next to your `start_run()` and `tqdml run` runs. On servers and CI, set `RUNPEEK_TOKEN` instead (create a token on the dashboard's Setup page). `tqdml logout` removes the saved login.
|
|
57
|
+
|
|
58
|
+
Notebooks, IPython and the Python REPL are the exception: bars there stay anonymous, so an idle kernel never becomes a run.
|
|
59
|
+
To save an experiment from a notebook, call `tqdm_live.start_run("my-experiment")` before the loop and `tqdm_live.end_run()` when it's done.
|
|
60
|
+
|
|
61
|
+
Free accounts keep 7 days of history, [Pro](https://runpeek.app/pricing) ($9/mo) keeps a year. Over the monthly saved-run limit a run still streams live, it just isn't saved.
|
|
62
|
+
|
|
63
|
+
## Notes
|
|
64
|
+
|
|
65
|
+
- Bars are addressed by unguessable UUIDs. No account needed, logging in is optional.
|
|
66
|
+
- Heartbeats are throttled (~0.75s) and sent from a daemon thread; your loop never blocks on the network, and send failures never raise into your code.
|
|
67
|
+
- An unsaved bar or run expires 30 minutes after its last heartbeat.
|
|
68
|
+
|
|
69
|
+
## Config (all optional)
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import tqdm_live
|
|
73
|
+
tqdm_live.setup(endpoint="https://runpeek.app", link_base="https://runpeek.link", min_interval=0.75, token="rpk_...")
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Env vars: `RUNPEEK_TOKEN`, `TQDMLIVE_ENDPOINT`, `TQDMLIVE_LINK_BASE`, `TQDMLIVE_MIN_INTERVAL`, `TQDMLIVE_NOTIFY`, `TQDMLIVE_DISABLE=1`.
|
|
77
|
+
Printed view links use the link base; it defaults to the endpoint itself when unset, so
|
|
78
|
+
self-hosted setups keep working. A token is picked from `setup(token=...)`, then `RUNPEEK_TOKEN`,
|
|
79
|
+
then the login saved by `tqdml login` (`~/.config/runpeek/config.json`).
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tqdm-live"
|
|
7
|
+
version = "0.7.0"
|
|
8
|
+
description = "Stream your tqdm progress bars to any browser, realtime. Zero config."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Bitgate", email = "kevin@bitgate.com" }]
|
|
13
|
+
keywords = ["tqdm", "progress", "progress-bar", "monitoring", "ml", "training"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Framework :: Jupyter",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
23
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
24
|
+
"Topic :: Software Development :: Libraries",
|
|
25
|
+
"Topic :: System :: Monitoring",
|
|
26
|
+
]
|
|
27
|
+
dependencies = ["tqdm>=4.60"]
|
|
28
|
+
|
|
29
|
+
[project.scripts]
|
|
30
|
+
tqdml = "tqdm_live.cli:main"
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://runpeek.app"
|
|
34
|
+
Documentation = "https://runpeek.app/docs"
|
|
35
|
+
Pricing = "https://runpeek.app/pricing"
|
|
36
|
+
|
|
37
|
+
[tool.hatch.build.targets.wheel]
|
|
38
|
+
packages = ["tqdm_live"]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
import tqdm_live
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.fixture(autouse=True)
|
|
7
|
+
def isolated_login(tmp_path, monkeypatch):
|
|
8
|
+
# A developer's own login must never leak into the suite
|
|
9
|
+
config_home = str(tmp_path / "config")
|
|
10
|
+
monkeypatch.delenv("RUNPEEK_TOKEN", raising=False)
|
|
11
|
+
monkeypatch.setenv("XDG_CONFIG_HOME", config_home)
|
|
12
|
+
monkeypatch.setenv("APPDATA", config_home)
|
|
13
|
+
monkeypatch.setattr(tqdm_live, "_TOKEN", None)
|
|
14
|
+
monkeypatch.setattr(tqdm_live, "_config_cache", None)
|
|
15
|
+
monkeypatch.setattr(tqdm_live, "_implicit_checked", False)
|
|
16
|
+
monkeypatch.setattr(tqdm_live, "_implicit_run", False)
|
|
17
|
+
monkeypatch.setattr(tqdm_live, "_wrapper_owns_run", False)
|
|
18
|
+
tqdm_live._notices_shown.clear()
|
|
19
|
+
tqdm_live._errors_shown.clear()
|