Get timeouts right, without the hassle.
Project description
Get timeouts right, without the hassle.
So you’re writing a function that takes a timeout
def foo(timeout):
...
and inside it you do something like
bar(timeout)
qux(timeout)
Wrong! The right way is to subtract the time spent in the first function, and pass just the remaining time as the timeout to the second function.
Or maybe you want to put a retry loop around a function that takes a timeout:
while ...:
foo(timeout)
The right way is to set a timeout for the whole loop, subtract the time each iteration took, pass the remaining time to the function, and break out once we’re out of time.
totaltimeout lets you code timeouts the right way, without writing all that boilerplate to calculate the remaining time.
Versioning
This library’s version numbers follow the SemVer 2.0.0 specification.
Installation
pip install totaltimeout
Usage
Import the Timeout class.
from totaltimeout import Timeout
Waiting in a “timed loop” for an API with retries (useful for unreliable APIs that may either hang or need retries):
for time_left in Timeout(SOME_NUMBER_OF_SECONDS):
reply = requests.get(api_url, timeout=time_left)
if reply.status == 200:
break
Same as above, but with a wait between retries:
timeout = Timeout(SOME_NUMBER_OF_SECONDS)
for time_left in timeout:
reply = requests.get(api_url, timeout=time_left)
if reply.status == 200:
break
# If you need to get the remaining time again in the same
# loop iteration, you have to use the .time_left() method:
if timeout.time_left() <= RETRY_DELAY:
break
time.sleep(RETRY_DELAY)
Waiting for multiple tasks to finish:
timeout = Timeout(10.0)
thread_foo.join(timeout.time_left())
thread_bar.join(timeout.time_left())
thread_qux.join(timeout.time_left())
# Works out almost as if we waited 10
# seconds for each thread in parallel.
Waiting for multiple tasks within each iteration of a “timed loop”:
timeout = Timeout(SOME_NUMBER_OF_SECONDS)
for time_left in timeout:
some_work(timeout=time_left)
some_more_work(timeout=timeout.time_left())
some_other_work(timeout=timeout.time_left())
Using a monotonic clock instead of the wall clock:
import time
timeout = Timeout(10.0, clock=time.monotonic)
You can also set the starting time of the timeout. This lets timeouts count down from a well-known point in time, which can be useful for testing, for synchronizing timeouts across networks, and so on:
start_of_this_minute = (time.now() // 60) * 60
timeout = Timeout(10.0, start=start_of_this_minute)
moment_in_time = time.now()
timeout = Timeout(10.0, start=moment_in_time)
time.sleep(1)
identical_timeout = Timeout(10.0, start=moment_in_time)
# both timeouts have exactly the same amount of time left
Finally, totaltimeout can be an ergonomic way to put a time limit on a loop even if the code in the loop does not support timeouts, so long as each iteration does not block for too long:
counter = 0
for _ in Timeout(30):
counter += 1
Project details
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
Hashes for totaltimeout-3.0.0-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6510f39c692831216d5a8ef28a84d11b7cbac4f15c1592dbaf006094c004d06c |
|
MD5 | f3e083ba16f18074b896a85f37b99f8c |
|
BLAKE2b-256 | 94bc89cb264f1c3f6e658a680a3e380c633782616976a06cdb465a94a3029bea |