Можно ли в Python использовать «экспоненциальную отсрочку» для каждого запроса для пакетных HTTP-запросов?

Итак, здесь я написал скрипт, который добавляет студентов на курсы (Google Classroom API).

students = getStudents('Year10', '10A')  # VAR

for student in students:
    newStudent = {
        # Student Identifier
        'userId': student
    }
    batch1_1.add(service.courses().students().create(courseId=arCourseId, body=newStudent))
    batch1_1.add(service.courses().students().create(courseId=ciCourseId, body=newStudent))
    batch1_1.add(service.courses().students().create(courseId=dtCourseId, body=newStudent))
    batch1_1.add(service.courses().students().create(courseId=drCourseId, body=newStudent))
    batch1_1.add(service.courses().students().create(courseId=enCourseId, body=newStudent))
    batch1_2.add(service.courses().students().create(courseId=geCourseId, body=newStudent))
    batch1_2.add(service.courses().students().create(courseId=hiCourseId, body=newStudent))
    batch1_2.add(service.courses().students().create(courseId=icCourseId, body=newStudent))
    batch1_2.add(service.courses().students().create(courseId=laCourseId, body=newStudent))
    batch1_2.add(service.courses().students().create(courseId=maCourseId, body=newStudent))
    batch1_3.add(service.courses().students().create(courseId=muCourseId, body=newStudent))
    batch1_3.add(service.courses().students().create(courseId=peCourseId, body=newStudent))
    batch1_3.add(service.courses().students().create(courseId=reCourseId, body=newStudent))
    batch1_3.add(service.courses().students().create(courseId=scCourseId, body=newStudent))
batch1_1.execute()
time.sleep(1)
batch1_2.execute()
time.sleep(1)
batch1_3.execute()
time.sleep(1)

Это работает, однако иногда возвращаются отдельные запросы:

"HttpError 500 при запросе https://classroom.googleapis.com/v1/courses/[COURSE ID] / student? alt = json вернул "Внутреннюю ошибку" "

И для этих отдельных запросов я хотел бы написать код, чтобы он повторял индивидуальный неудавшийся запрос при получении ошибки 5xx. Однако я не уверен, как это реализовать.

В настоящий момент мне приходится повторно запускать весь сценарий, если хотя бы 1 студент не дошел до курса, что, конечно же, является пустой тратой ресурсов.


person Rowan Richards    schedule 17.12.2017    source источник


Ответы (1)


Когда вы создаете пакет, вы можете предоставить функцию обратного вызова, которая будет вызываться для каждого из запросов, которые вы добавляете в пакет.

Обратный вызов принимает три параметра:

  • request_id: идентификатор, который вы решаете идентифицировать запрос, который вы добавляете в пакет (вы передаете его, когда вызываете метод add () пакета
  • response: ответ на ваш единственный вызов API.
  • исключение: объект исключения, если запрос пакета вызвал ошибку

Ниже у вас есть псевдокод, объясняющий логику.

# sample callback function
def my_batch_callback(request_id, response, exception):
    if exception is not None:
        # Do something with the exception
        print(exception)
    else:
        # Do something with the response
        print("Request is successful: {}".format(response))
    pass

# creation of batch passing in the call back
batch = service.new_batch_http_request(callback=my_batch_callback)

# addition to batch with a specific id
batch.add(service.object().insert(name="test-1", request_id="id-1"))
batch.add(service.object().insert(name="test-2", request_id="id-2"))
batch.add(service.object().insert(name="test-3", request_id="id-3"))

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

Предлагаю вам также ознакомиться с официальной документацией здесь.

person Lorenzo Persichetti    schedule 22.12.2017