Flask结合Firebase Cloud Function访问request.json时出现超时循环问题
Flask + Google Cloud Functions 超时报错 ClientDisconnected 解决方法
问题现象
用Flask结合Google Cloud Functions开发JSON API时,POST请求到/events端点后,控制台显示Flask已返回<Response 41 bytes [201 CREATED]>响应,但Cloud Functions却触发60秒超时,最终抛出ClientDisconnected异常。尝试用request.get_data(as_text=True)替代request.json后问题依旧。
原代码示例
@app.route("/events",methods=['POST']) def post_event(): # new_event = request.get_data(as_text=True) new_event = request.json print(new_event) return {"message":"Event created successfully"}, 201 # Expose Flask app as a single Cloud Function: @https_fn.on_request(max_instances=10) def httpsflaskexample(req: https_fn.Request) -> https_fn.Response: with app.request_context(req.environ): flask_response = app.full_dispatch_request() print(flask_response) return flask_response
控制台输出
> WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. > * Running on http://127.0.0.1:8374 > Press CTRL+C to quit > <Response streamed [404 NOT FOUND]> > 127.0.0.1 - - [24/Sep/2023 20:51:58] "GET /__/health HTTP/1.1" 404 - i functions: Beginning execution of "us-central1-httpsflaskexample" > {'name': 'Add your name in the body'} > <Response 41 bytes [201 CREATED]> (*疑似无限循环或异常情况发生)
超时错误日志
i Your function timed out after ~60s. To configure this timeout, see https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation. i Request to function failed: Error: socket hang up > [2023-09-24 20:52:58,110] ERROR in app: Exception on /events [POST] > Traceback (most recent call last): > File "...\functions\venv\lib\site-packages\flask\app.py", line 2190, in wsgi_app > response = self.full_dispatch_request() > File "...\functions\venv\lib\site-packages\flask\app.py", line 1487, in full_dispatch_request > return self.finalize_request(rv) > File "...\functions\venv\lib\site-packages\flask\app.py", line 1508, in finalize_request > response = self.process_response(response) > File "...\functions\venv\lib\site-packages\flask\app.py", line 2002, in process_response > response = self.ensure_sync(func)(response) > File "...\functions\venv\lib\site-packages\functions_framework\__init__.py", line 302, in read_request > flask.request.get_data() > File "...\functions\venv\lib\site-packages\werkzeug\wrappers\request.py", line 423, in get_data > rv = self.stream.read() > File "...\functions\venv\lib\site-packages\werkzeug\wsgi.py", line 829, in readall > data = self.read(1024 * 64) > File "...\functions\venv\lib\site-packages\werkzeug\wsgi.py", line 814, in readinto > self.on_disconnect() > File "...\functions\venv\lib\site-packages\werkzeug\wsgi.py", line 751, in on_disconnect > raise ClientDisconnected() > werkzeug.exceptions.ClientDisconnected: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
解决方法
问题根源是直接将Flask的Response对象返回给Cloud Functions,两者响应处理机制不兼容,导致请求流读取异常。需提取Flask响应的内容、状态码和头部,构建成Cloud Functions兼容的https_fn.Response对象返回。
修改后的入口函数代码:
@https_fn.on_request(max_instances=10) def httpsflaskexample(req: https_fn.Request) -> https_fn.Response: with app.request_context(req.environ): flask_response = app.full_dispatch_request() print(flask_response) # 转换为Cloud Functions兼容的响应格式 return https_fn.Response( response=flask_response.get_data(), status=flask_response.status_code, headers=dict(flask_response.headers) )
关键说明
flask_response.get_data():读取Flask响应的原始字节内容flask_response.status_code:获取响应状态码dict(flask_response.headers):将Flask响应头部转为字典,适配Cloud Functions的Response要求
修改后即可避免超时和ClientDisconnected异常。
内容的提问来源于stack exchange,提问作者Kevin Cespedes Arancibia
相关产品推荐
相关产品推荐

