【问题标题】:In Python, is it possible to use 'exponential backoff' per request for batched HTTP requests?在 Python 中,是否可以对批处理 HTTP 请求的每个请求使用“指数退避”?
【发布时间】:2017-12-17 15:34:12
【问题描述】:

所以,我在这里编写了一个将学生添加到课程中的脚本(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)

确实有效,但是,有时个别请求会返回:

“请求https://classroom.googleapis.com/v1/courses/[COURSE ID 时的HttpError 500]/students?alt=json 返回“内部错误””

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

目前,即使只有 1 个学生没有参加课程,我也必须重新运行整个脚本,这当然是一种资源浪费。

【问题讨论】:

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


    【解决方案1】:

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

    回调接受三个参数:

    • request_id:您决定识别要添加到批处理的请求的 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"))
    

    使用回调,您可以使用其 id 保存所有错误请求,并在稍后重试它们。有不同的方法可以做到这一点:您可以使用一个简单的列表并在运行批处理后检查它,或者您可以创建一个专用类并利用它提供的持久性。

    我建议你也看看官方文档here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多