Remote tqdm progress dashboards with a FastAPI push gateway and live web UI.
Project description
Progressista
Progressista is a tiny “push gateway” for progress bars. Swap your existing tqdm
instances with a drop-in subclass that streams progress updates to a FastAPI
server. The server keeps tasks in memory and serves a live HTML dashboard over
WebSocket so you can monitor many worker bars from a single browser tab.
Why? When long-running experiments or ETL jobs run on remote machines you often lose the nice
tqdmprogress output. Progressista lets you restore that feedback loop without SSH-ing into every node.
Features
- ⚡️ Drop-in
RemoteTqdmreplacement fortqdm. - 🌐 Live dashboard powered by FastAPI and WebSockets.
- 🧰 Simple CLI:
progressista serveandprogressista demo. - 🪄 Seamless retrofits via
progressista runorsitecustomizepatching. - 🔧 Configurable server URL via CLI flags or environment variables.
- 🗂️ Dashboard buckets for active/stale/completed tasks with one-click cleanup.
- 🔐 Optional CORS allow-list for remote dashboards.
- 🧹 Automatic cleanup of completed tasks with configurable retention.
Quick start
# 1. Install locally (requires Python 3.10+)
pip install -e .
# 2. Run the server
progressista serve --host 0.0.0.0 --port 8000
# 3. Open the dashboard
open http://localhost:8000/static/index.html
# 4. Send progress from Python code
python - <<'PY'
from time import sleep
from progressista import RemoteTqdm
for _ in RemoteTqdm(range(100), desc="Demo workload"):
sleep(0.05)
PY
Or use the built-in demo generator:
progressista demo --bars 4 --total 80 --delay 0.1
Using RemoteTqdm
from time import sleep
from progressista import RemoteTqdm
# Point to your server (defaults to http://localhost:8000/progress)
for _ in RemoteTqdm(range(100), desc="ETL: stage 1", unit="it"):
sleep(0.05)
Multiple bars? Just give each one a task_id:
workers = [
RemoteTqdm(total=50, desc=f"worker {i}", task_id=f"job-x:worker-{i}")
for i in range(3)
]
for _ in range(50):
for bar in workers:
bar.update(1)
sleep(0.05)
for bar in workers:
bar.close()
Use without modifying existing scripts
-
Run any script through Progressista without touching its source:
progressista run your_script.py -- --arg1 value progressista run -m package.module -- --flag progressista run your_script.py --server-url https://example.com/progress -- --arg
All imports of
tqdm(includingfrom tqdm.auto import tqdm) become remote-aware, while the original terminal or notebook rendering stays intact. -
Need this automatically? Drop the following
sitecustomize.pyon yourPYTHONPATH:from progressista.patch import install install() # accepts server_url=..., headers=..., etc.
Python imports
sitecustomizebefore your program starts, so every script inherits the patch.
Dashboard controls
- Active tasks stay in the main lane. When a bar stops reporting for more than
PROGRESSISTA_STALE_SECONDS(if set), it moves to the Needs Attention pile. - Closed bars land under Completed and only the most recent six stay visible so the list stays compact.
- Use the toolbar to clear all completed or stale tasks, or discard individual cards via the button on each tile. All actions replicate instantly across connected browsers.
Configuration
Progressista reads optional environment variables so you can configure it in Docker images, systemd units, or cloud runners:
| Variable | Description | Default |
|---|---|---|
PROGRESSISTA_HOST |
Interface for the server to bind | 0.0.0.0 |
PROGRESSISTA_PORT |
Port used by progressista serve |
8000 |
PROGRESSISTA_STORAGE_PATH |
JSON file that stores task snapshots for crash recovery | unset |
PROGRESSISTA_ALLOW_ORIGINS |
Comma-separated CORS origins | disabled |
PROGRESSISTA_RETENTION_SECONDS |
Keep closed tasks visible for (s) | 86400 |
PROGRESSISTA_CLEANUP_INTERVAL |
Cleanup frequency (s) | 5 |
PROGRESSISTA_SERVER_URL |
Default client post URL | http://localhost:8000/progress |
PROGRESSISTA_PUSH_INTERVAL |
Client throttle window in seconds | 0.25 |
PROGRESSISTA_REQUEST_TIMEOUT |
HTTP timeout in seconds | 2.0 |
PROGRESSISTA_API_TOKEN |
Shared bearer token for server & client | unset |
PROGRESSISTA_API_TOKENS |
Comma-separated list of valid tokens | unset |
PROGRESSISTA_STALE_SECONDS |
Mark tasks as stale after this many idle seconds (0 disables) |
0 |
PROGRESSISTA_MAX_TASK_AGE |
Automatically discard tasks older than this many seconds (0 disables) |
0 |
All CLI options override the corresponding environment variable for the current invocation.
Packaging
progressista.serverexposescreate_app(FastAPI factory) andrun_serverutility if you want to embed the app elsewhere.progressista.client.RemoteTqdmgives programmatic access to the client.progressista.cliprovides the Typer-based commands used by the entry point.- Version strings live in
progressista/__init__.pyand are managed by Hatch ([tool.hatch.version]). Usemake sync-version TAG=vX.Y.Zbefore tagging a release.
Development
python -m venv .venv
source .venv/bin/activate
pip install -e .[dev]
make test
make docs
make version # prints the git-derived version
Documentation
Additional docs live in docs/:
- MkDocs site: https://filipinascimento.github.io/progressista/
- Run
make docs-servefor a live preview (mkdocs serve). docs/architecture.md— system design and data flow.docs/server.md— FastAPI endpoints and configuration.docs/client.md— client API and integration notes.docs/runbook.md— deployment tips and troubleshooting.docs/hosting.md— free-tier hosting options and deployment tips.
Security
-
Set a shared token on both server and clients:
export PROGRESSISTA_API_TOKEN="super-secret" progressista serve
Clients pick it up automatically (via environment variable) or you can pass it explicitly:
PROGRESSISTA_API_TOKEN=super-secret python your_script.py # or progressista run script.py --api-token super-secret
-
Requests must include an
Authorization: Bearer ...header; open the dashboard ashttp://host/static/index.html?token=super-secretso the WebSocket connection inherits the same key. -
Want per-user credentials? Set
PROGRESSISTA_API_TOKENS="alpha,beta"on the server and hand out individual strings.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file progressista-0.2.1.tar.gz.
File metadata
- Download URL: progressista-0.2.1.tar.gz
- Upload date:
- Size: 26.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
058991f8e7254a8a87e35329ddcb51d3861a667db47b1bb697d8c352fce5c2c9
|
|
| MD5 |
6ad037ecb7599c293818e10b1ce74499
|
|
| BLAKE2b-256 |
fbb93289075b6cb02608af94232e94f0c8f72c9c398872b94c775b969298c74d
|
Provenance
The following attestation bundles were made for progressista-0.2.1.tar.gz:
Publisher:
python-publish.yml on filipinascimento/progressista
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
progressista-0.2.1.tar.gz -
Subject digest:
058991f8e7254a8a87e35329ddcb51d3861a667db47b1bb697d8c352fce5c2c9 - Sigstore transparency entry: 646860708
- Sigstore integration time:
-
Permalink:
filipinascimento/progressista@994c9bae9d5eaaa2576345489f9abfa19e6a0213 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/filipinascimento
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@994c9bae9d5eaaa2576345489f9abfa19e6a0213 -
Trigger Event:
release
-
Statement type:
File details
Details for the file progressista-0.2.1-py3-none-any.whl.
File metadata
- Download URL: progressista-0.2.1-py3-none-any.whl
- Upload date:
- Size: 20.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
556c01b93bd4290b41222281a99f001cdc0d369e5689544001472e7cc77e195c
|
|
| MD5 |
80a1d54f2b9e5e7cfba1b8f09bab00a8
|
|
| BLAKE2b-256 |
764596c08c9fb4d366b2e62b4060eea950cce8bd8017b9e9c3e56c2a3d11d1e6
|
Provenance
The following attestation bundles were made for progressista-0.2.1-py3-none-any.whl:
Publisher:
python-publish.yml on filipinascimento/progressista
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
progressista-0.2.1-py3-none-any.whl -
Subject digest:
556c01b93bd4290b41222281a99f001cdc0d369e5689544001472e7cc77e195c - Sigstore transparency entry: 646860724
- Sigstore integration time:
-
Permalink:
filipinascimento/progressista@994c9bae9d5eaaa2576345489f9abfa19e6a0213 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/filipinascimento
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@994c9bae9d5eaaa2576345489f9abfa19e6a0213 -
Trigger Event:
release
-
Statement type: