Python Tip: How to abort a code block if its taking too long

Sharing a quick tip that helped me a lot the other day.

Whenever you use python to integrate anything 3rd party, there is a risk that a transaction with this 3rd party API might be hanging. This happened to me recently when interacting with Salesforce via the simple-salesforce module. I would work for hours, but then seemingly randomly get stuck somewhere deep down in the HTTP / SSL layer of python.

Here is how I’ve overcome this, inspired by this Stackoverflow post python - Timeout function if it takes too long to finish - Stack Overflow

import time
import signal

class timeout:
    def __init__(self, seconds=1, error_message='Timeout'):
        self.seconds = seconds
        self.error_message = error_message
    def handle_timeout(self, signum, frame):
        raise TimeoutError(self.error_message)
    def __enter__(self):
        signal.signal(signal.SIGALRM, self.handle_timeout)
        signal.alarm(self.seconds)
    def __exit__(self, type, value, traceback):
        signal.alarm(0)

with timeout(seconds=5):
    print('doing something that takes longer than 5 seconds')
    time.sleep(6)

The neat part of this approach is that you can use a “with” block to declare an acceptable timeout for an entire block. If it oversteps this, a TimeoutError is raised which you can then choose to handle or not.

Note that the signal method only works on UNIX-style systems, Linux and Max for example.

2 Likes