Get Raw Post Body in Python Flask Regardless of Content-Type Header

Get raw POST body in Python Flask regardless of Content-Type header

Use request.get_data() to get the raw data, regardless of content type. The data is cached and you can subsequently access request.data, request.json, request.form at will.

If you access request.data first, it will call get_data with an argument to parse form data first. If the request has a form content type (multipart/form-data, application/x-www-form-urlencoded, or application/x-url-encoded) then the raw data will be consumed. request.data and request.json will appear empty in this case.

Flask - How do I read the raw body in a POST request when the content type is application/x-www-form-urlencoded

You can get the post data via request.form.keys()[0] if content type is application/x-www-form-urlencoded.

request.form is a multidict, whose keys contain the parsed post data.

Get the data received in a Flask request

The docs describe the attributes available on the request object (from flask import request) during a request. In most common cases request.data will be empty because it's used as a fallback:

request.data Contains the incoming request data as string in case it came with a mimetype Flask does not handle.

  • request.args: the key/value pairs in the URL query string
  • request.form: the key/value pairs in the body, from a HTML post form, or JavaScript request that isn't JSON encoded
  • request.files: the files in the body, which Flask keeps separate from form. HTML forms must use enctype=multipart/form-data or files will not be uploaded.
  • request.values: combined args and form, preferring args if keys overlap
  • request.json: parsed JSON data. The request must have the application/json content type, or use request.get_json(force=True) to ignore the content type.

All of these are MultiDict instances (except for json). You can access values using:

  • request.form['name']: use indexing if you know the key exists
  • request.form.get('name'): use get if the key might not exist
  • request.form.getlist('name'): use getlist if the key is sent multiple times and you want a list of values. get only returns the first value.

How to get raw request payload in Flask/Connexion?

I'm not sure if there's an easier way, but this seems to do the trick:

import urllib.parse

form_data = request.form
request_data = '&'.join([k + '=' + urllib.parse.quote_plus(v) for k, v in form_data.items()])

Flask Upload with no Content-Type or Form Data at All

The solution is to use file streaming. After many days of searching I finally found this blog post which mentions the specific problem of using the Flask/Requests file call:

The trick seems to be that you shouldn’t use other request attributes like request.form or request.file because this will materialize the stream into memory/file. Flask by default saves files to disk if they exceed 500Kb, so don’t touch file.

Running the attached method immediately solved the issue of upload without multipart-form:

from flask import Flask
import requests
from flask import request

app = Flask(__name__)

# Upload file as stream to a file.
@app.route("/upload", methods=["POST"])
def upload():
with open("/tmp/output_file", "bw") as f:
chunk_size = 4096
while True:
chunk = request.stream.read(chunk_size)
if len(chunk) == 0:
return
f.write(chunk)
return 'created', 201

(Full credit to @izmailoff, but I added the final line or else there would be a timeout issue on the receivers side)



Related Topics



Leave a reply



Submit