Skip to content

[FlaskAPI] Getting POST body using request.data fails #286

Closed
@russoloph

Description

@russoloph

Hi,

I set up correctly an APM Agent in Flask, and now I'm facing an issue in another project that uses FlaskAPI.
As it is, the API returns an "Internal Server Error" because, when the agent retrieves the POST body, it crashes:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1816, in full_dispatch_request
    return self.finalize_request(rv)
  File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1834, in finalize_request
    request_finished.send(self, response=response)
  File "/usr/local/lib/python3.6/site-packages/blinker/base.py", line 267, in send
    for receiver in self.receivers_for(sender)]
  File "/usr/local/lib/python3.6/site-packages/blinker/base.py", line 267, in <listcomp>
    for receiver in self.receivers_for(sender)]
  File "/usr/local/lib/python3.6/site-packages/elasticapm/contrib/flask/__init__.py", line 145, in request_finished
    "request",
  File "/usr/local/lib/python3.6/site-packages/elasticapm/traces.py", line 333, in set_context
    data = data()
  File "/usr/local/lib/python3.6/site-packages/elasticapm/contrib/flask/__init__.py", line 143, in <lambda>
    request, capture_body=self.client.config.capture_body in ("transactions", "all")
  File "/usr/local/lib/python3.6/site-packages/elasticapm/contrib/flask/utils.py", line 29, in get_data_from_request
    body = request.data
  File "/usr/local/lib/python3.6/site-packages/werkzeug/local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/usr/local/lib/python3.6/site-packages/flask_api/request.py", line 24, in data
    self._parse()
  File "/usr/local/lib/python3.6/site-packages/flask_api/request.py", line 53, in _parse
    ret = parser.parse(self.stream, media_type, **options)
  File "/usr/local/lib/python3.6/site-packages/flask_api/parsers.py", line 32, in parse
    raise exceptions.ParseError(msg)
flask_api.exceptions.ParseError: JSON parse error - Expecting value: line 1 column 1 (char 0)

In this case, when /usr/local/lib/python3.6/site-packages/elasticapm/contrib/flask/utils.py (line 29) retrieves the body, it uses request.data.

Instead of using directly the data attribute, using request.get_data() makes it work and the json body is correctly retrieved and parsed. I tried it on the project in which there's only Flask and not FlaskAPI, and it works like a charm.
Another option would be to be less precise when catching potentiel exceptions, to make sure the request won't return an internal server error. For now, it's only ClientDisconnected.

I'm using:

  • python 3.7
  • Flask==1.0.2
  • Flask-API==1.0

Thanks in advance.
ph

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions