在Python中,是否可以使用指数退避'每个请求批量HTTP请求?

时间:2017-12-17 15:34:13

标签: python google-api google-api-python-client exponential-backoff

所以,在这里,我编写了一个脚本,将学生添加到课程中(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] /学生?alt = json返回"内部错误""

对于这些单独的请求,我想编写代码,以便在收到5xx错误时重试单个失败的请求。我不确定如何实现这一点。

目前,即使只有一名学生没有参加课程,我也不得不重新编写整个剧本,这当然是浪费资源。

1 个答案:

答案 0 :(得分:1)

创建批处理时,您可以提供一个回调函数,该函数将为您添加到批处理中的每个请求调用。

回调有三个参数:

  • request_id :您决定识别要添加到批处理中的请求的ID(当您调用批处理的add()方法时将其传递
  • 响应:您对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"))

使用回调,您可以使用其ID保存所有错误请求,然后在第二时刻再次重试。有不同的方法可以执行此操作:您可以使用一个简单的列表并在运行批处理后进行检查,或者您可以创建一个专用的类并提前它提供的持久性。

我建议您也查看官方文档here