Execution timeout on Python functions

17th February, 2020

There are at times when we need to have a defined maximum execution time for some functions in order to avoid script/server blockage. A simple solution using decorator can be implemented for such cases as shown below.

 

import signal


class TimedOutException(Exception):
    pass


def func_timeout(timeout):
    def func_decorator(func):
        def wrapper(*args, **kwargs):
            def handler(signum, frame):
                raise TimedOutException("method: {}, params: {} took longer than {} seconds".format(
                    func.__name__,
                    ", ".join([str(i) for i in (args or kwargs.values())]),
                    timeout
                ))

            def func_timed():
                signal.signal(signal.SIGALRM, handler)
                signal.alarm(timeout)
                return func(*args, **kwargs)
                signal.alarm(0)

            return func_timed()
        return wrapper
    return func_decorator

# example
@func_timeout(2) # in seconds
def very_slow_func(mult):
    count = 0
    while(True):
        count += 1 * mult
        print(count)


very_slow_func(mult=100)

 

That's it. The func_timeout decorator will put a timeout for the decorated functions.