0

I have a serverless api through sam that consists of aws::serverless:function's and using flask-lambda to consume requests. I have been able to consume normal rest requests but I have a use-case to take in 3 property values and multiple files so naturally I considered using form-data to do this.

Sample lambda below:

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

After standing up the serverless api through sam local, I hit this endpoint through postman and the below error occurs as Flask tries to parse the form-data:

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

I can't tell if there is misconfiguration in my sam template.yaml or if flask-lambda is just so out of date that this occurs for everyone.

Does anyone know why this is happening and how I can fix this?

NOTE: I do have the below set for BinaryMediaTypes on the API gateway configuration.

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

1 Answers1

0

Werkzeug/Flask expect a different type of object for environ['wsgi.input'] than what flask-lambda is providing.

I resolved this by copying the flask-lambda module into my project and changing:

[...] import StringIO

#  ...

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

to

import io

#  ...

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

If you're using the original repo this is the relevant line.

I recommend this fork of a fork of flask-lambda but it has the same flaw.

(I'm using Python3.8, Flask==2.0.2, Werkzeug==2.0.3)