【问题标题】:Serverless Flask API crashes when trying to consume multipart/form-data尝试使用 multipart/form-data 时,无服务器 Flask API 崩溃
【发布时间】:2021-10-27 10:23:36
【问题描述】:

我有一个通过sam 的无服务器api,它由aws::serverless:function 组成,并使用flask-lambda 来消费请求。我已经能够处理正常的休息请求,但我有一个用例来接收 3 个属性值和多个文件,所以我很自然地考虑使用表单数据来执行此操作。

下面的示例 lambda:

from flask import request, jsonify
from flask_lambda import FlaskLambda

app = FlaskLambda(__name__)


@app.route('/kits', methods=['POST'])
def lambda_handler():
    print(request.form['title'])
    print(request.form['description'])
    print(request.form['kitType'])
    return jsonify("success"), 201

通过 sam local 建立无服务器 api 后,我通过邮递员访问了这个端点,当 Flask 尝试解析表单数据时出现以下错误:

Traceback (most recent call last):
  File "/var/task/flask/app.py", line 2070, in wsgi_app
    response = self.full_dispatch_request()
  File "/var/task/flask/app.py", line 1515, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/var/task/flask/app.py", line 1513, in full_dispatch_request
    rv = self.dispatch_request()
  File "/var/task/flask/app.py", line 1499, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/var/task/app.py", line 15, in kits_post
    print(request.form['title'])
  File "/var/task/werkzeug/utils.py", line 97, in __get__
    value = self.fget(obj)  # type: ignore
  File "/var/task/werkzeug/wrappers/request.py", line 447, in form
    self._load_form_data()
  File "/var/task/flask/wrappers.py", line 113, in _load_form_data
    RequestBase._load_form_data(self)
  File "/var/task/werkzeug/wrappers/request.py", line 285, in _load_form_data
    data = parser.parse(
  File "/var/task/werkzeug/formparser.py", line 265, in parse
    return parse_func(self, stream, mimetype, content_length, options)
  File "/var/task/werkzeug/formparser.py", line 142, in wrapper
    return f(self, stream, *args, **kwargs)
  File "/var/task/werkzeug/formparser.py", line 292, in _parse_multipart
    form, files = parser.parse(stream, boundary, content_length)
  File "/var/task/werkzeug/formparser.py", line 459, in parse
    parser.receive_data(data)
  File "/var/task/werkzeug/sansio/multipart.py", line 138, in receive_data
    self.buffer.extend(data)
TypeError: 'str' object cannot be interpreted as an integer

我无法判断我的 sam template.yaml 中是否存在错误配置,或者 flask-lambda 是否已经过时以至于每个人都会出现这种情况。

有谁知道为什么会发生这种情况以及我该如何解决这个问题?

注意:我确实在 API 网关配置中为 BinaryMediaTypes 设置了以下内容。

      BinaryMediaTypes:
        - '*~1*'  # converts to */* for any binary type
        - 'multipart/form-data'

【问题讨论】:

    标签: python flask aws-lambda aws-sam-cli


    【解决方案1】:

    Werkzeug/Flask 期望 environ['wsgi.input'] 的对象类型与 flask-lambda 提供的对象类型不同。

    我通过将flask-lambda 模块复制到我的项目中并进行更改来解决此问题:

    [...] import StringIO
    
    #  ...
    
    environ['wsgi.input'] = StringIO(event['body'] or '')
    

    import io
    
    #  ...
    
    environ['wsgi.input'] = io.BytesIO((event['body'] or '').encode())
    

    如果您使用的是原始 repo this is the relevant line

    我推荐this fork of a fork of flask-lambda,但它有the same flaw

    (我正在使用Python3.8Flask==2.0.2Werkzeug==2.0.3

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-31
      • 1970-01-01
      • 1970-01-01
      • 2019-01-06
      • 1970-01-01
      • 2015-12-23
      • 1970-01-01
      • 2015-09-19
      相关资源
      最近更新 更多