I have been going over the tqdm docs, but no matter where I look, I cannot find a method by which to extract the time passed and estimated time remaining fields (basically the center of the progress bar on each line: 00:00<00:02
).
0%| | 0/200 [00:00<?, ?it/s]
4%|▎ | 7/200 [00:00<00:02, 68.64it/s]
8%|▊ | 16/200 [00:00<00:02, 72.87it/s]
12%|█▎ | 25/200 [00:00<00:02, 77.15it/s]
17%|█▋ | 34/200 [00:00<00:02, 79.79it/s]
22%|██▏ | 43/200 [00:00<00:01, 79.91it/s]
26%|██▌ | 52/200 [00:00<00:01, 80.23it/s]
30%|███ | 61/200 [00:00<00:01, 82.13it/s]
....
100%|██████████| 200/200 [00:02<00:00, 81.22it/s]
tqdm
works via essentially printing a dynamic progress bar anytime an update occurs, but is there a way to "just" print the 00:01
and 00:02
portions, so I could use them elsewhere in my Python program, such as in automatic stopping code that halts the process if it is taking too long?
Edit: see the library maintainer's answer below. Turns out, it is possible to get this information in the public API.
tqdm
does not expose that information as part of its public API, and I don't recommend trying to hack your own into it. Then you would be depending on implementation details of tqdm
that might change at any time.
However, that shouldn't stop you from writing your own. It's easy enough to instrument a loop with a timer, and you can then abort the loop if it takes too long. Here's a quick, rough example that still uses tqdm
to provide visual feedback:
import time
from tqdm import tqdm
def long_running_function(n, timeout=5):
start_time = time.time()
for _ in tqdm(list(range(n))):
time.sleep(1) # doing some expensive work...
elapsed_time = time.time() - start_time
if elapsed_time > timeout:
raise TimeoutError("long_running_function took too long!")
long_running_function(100, timeout=10)
If you run this, the function will stop its own execution after 10 seconds by raising an exception. You could catch this exception at the call site and respond to it in whatever way you deem appropriate.
If you want to be clever, you could even factor this out in a tqdm
-like wrapper like this:
def timed_loop(iterator, timeout):
start_time = time.time()
iterator = iter(iterator)
while True:
elapsed_time = time.time() - start_time
if elapsed_time > timeout:
raise TimeoutError("long_running_function took too long!")
try:
yield next(iterator)
except StopIteration:
pass
def long_running_function(n, timeout=5):
for _ in timed_loop(tqdm(list(range(n))), timeout=timeout):
time.sleep(0.1)
long_running_function(100, timeout=5)