Динамические параметры с декоратором повторных попыток Python

В настоящее время я использую пакет повторных попыток python, который содержит декоратор @retry с рядом необязательных параметры. У меня правильно установлены эти параметры для нашей производственной среды с достаточно длительным временем ожидания между повторными попытками (ниже установлено значение 2000 миллисекунд), но я хотел бы установить эти значения по-другому для целей модульного тестирования, чтобы выполнение было очень быстрым.

Например, здесь для рабочей среды для параметра wait_fixed установлено значение 2000 миллисекунд, но для моего модульного теста, вызывающего some_function(), я бы хотел переопределить параметр wait_fixed равным 1 миллисекунде, чтобы он выполнялся очень быстро.

@retry(stop_max_attempt_number=3, wait_fixed=2000)
def some_function(self):
    return True

Проблема, с которой я сталкиваюсь, заключается в том, что декоратор интерпретируется, когда функция определен, поэтому пока я не нашел способа переопределить параметр wait_fixed из моих модульных тестов.


person Andrew Thompson    schedule 30.07.2015    source источник
comment
Глядя на источник, нет простого способа получить доступ к этим параметрам через объект оболочки, который вы возвращаете.   -  person jonrsharpe    schedule 30.07.2015
comment
Рассматривали ли вы наличие файла конфигурации для вашего проекта? Файл конфигурации может хранить такие константы, и вы можете настроить файлы конфигурации для dev/test/prod.   -  person Adam    schedule 30.07.2015


Ответы (3)


main.py

import settings
from retrying import retry


@retry(stop_max_attempt_number=settings.STOP_MAX_ATTEMPT_NUMBER, 
       wait_fixed=settings.WAIT_FIXED)
def some_function(self):
    return True

settings.py

import json


with open('config.json') as jsonf:
    config = json.loads(jsonf.read())

WAIT_FIXED=int(config['WAIT_FIXED'])
STOP_MAX_ATTEMPT_NUMBER=int(config['STOP_MAX_ATTEMPT_NUMBER'])

config.json

{
    "STOP_MAX_ATTEMPT_NUMBER" : "3",
    "WAIT_FIXED" : "2000"
}

Попросите вашего тестировщика поставить подходящий config.json на место.

person Adam    schedule 30.07.2015
comment
Спасибо, Horba, в настоящее время я использую Heroku, поэтому добавление этого типа настроек в файл .env сработало, а затем я установил значение по умолчанию для wait_fixed равным 2000 мс. - person Andrew Thompson; 31.07.2015

Недавно я столкнулся с проблемой, которая разрешилась наличием def внутри def.


Мне нужно использовать декоратор повторных попыток для функции get_url, но мне нужно передать настраиваемое значение для stop_max_attempt_number. Я никак не могу придумать get_url вместе с другими функциями с тем же отступом.

Чтобы решить эту проблему, у меня есть функция get_url, определенная внутри функции get_analytic. Для иллюстрации:

def get_analytics(conf: Configuration, assets: list, cache: dict) -> list:
    STOP_MAX_ATTEMPT_NUMBER = int(conf.num_retry)
    WAIT_FIXED = int(conf.retry_timeout)
    @retry(stop_max_attempt_number=STOP_MAX_ATTEMPT_NUMBER, wait_fixed=WAIT_FIXED)
    def get_url(disable_https: bool, url: str, user: str, password: str) -> Response:
person Edmond Wong    schedule 21.07.2017

Мне нужно было иметь возможность динамически устанавливать параметры повтора при вызове функции, для меня это хорошо сработало:

import random
from retrying import retry


class MyClass(object):

    def try_stuff(self, string, attempts, wait):
        self.do_something_with_retry = retry(stop_max_attempt_number=attempts,
                                             wait_fixed=wait)(self.do_something_unreliable)
        return self.do_something_with_retry(string)

    def do_something_unreliable(self, string):
        print(string)
        if random.randint(0, 10) > 1:
            raise IOError("Broken sauce, everything is hosed!!!111one")
        else:
            return "Awesome sauce!"

instance = MyClass()

print instance.try_stuff('test', 10, 2000)
person Wesley Smith    schedule 23.10.2016