Not much to say here, just a snippet to share.
def periodic(interval, times = -1):
def outer_wrap(function):
def wrap(*args, **kwargs):
stop = threading.Event()
def inner_wrap():
i = 0
while i != times and not stop.isSet():
stop.wait(interval)
function(*args, **kwargs)
i += 1
t = threading.Timer(0, inner_wrap)
t.daemon = True
t.start()
return stop
return wrap
return outer_wrap