Недавно делал обёртку для SteamAPI. Так как он очень лагающий, использовал такой класс-декоратор:
class Retry(object):
"""
Retries function with exponential delay if it's releasing exception.
"""
def __init__(self, tries, exceptions=None, delay=1, exponent=1.5):
self.tries = tries
if exceptions:
self.exceptions = tuple(exceptions)
else:
self.exceptions = (Exception,)
self.delay = delay
self.exponent = exponent
def __call__(self, f):
def fn(*args, **kwargs):
exception = None
for i in range(self.tries):
try:
return f(*args, **kwargs)
except self.exceptions as e:
delay = self.delay * self.exponent ** i
if i + 1 == self.tries:
raise exception
sleep(delay)
exception = e
raise exception
return fn
Ну и использование такое:
@Retry(3)
def f():
...
Повторяет функцию ещё раз (заданное кол-во раз), если функция вернула exception. Каждый раз время увеличивается экспоненциально.
Что касается асинхронности - копайте в сторону asyncio и aiohttp.