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 stringrequest.form
: the key/value pairs in the body, from a HTML post form, or JavaScript request that isn't JSON encodedrequest.files
: the files in the body, which Flask keeps separate fromform
. HTML forms must useenctype=multipart/form-data
or files will not be uploaded.request.values
: combinedargs
andform
, preferringargs
if keys overlaprequest.json
: parsed JSON data. The request must have theapplication/json
content type, or userequest.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 existsrequest.form.get('name')
: useget
if the key might not existrequest.form.getlist('name')
: usegetlist
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
Why Use Abstract Base Classes in Python
Can't Install New Packages for Python (Python 3.9.0, Windows 10)
What Does "Bound Method" Error Mean When I Call a Function
What's a Faster Operation, Re.Match/Search or Str.Find
Python How to Write to a Binary File
Python: Find_Element_By_Css_Selector
Pandas: Cast Column to String Does Not Work
Get Relative Path from Comparing Two Absolute Paths
Using Colormaps to Set Color of Line in Matplotlib
Python Beautifulsoup Extract Text Between Element
Popen with Conflicting Executable/Path
What Exactly Is Contained Within a Obj._Closure_
Automating Pydrive Verification Process
Run Child Processes as Different User from a Long Running Python Process
How to Do a Not Equal in Django Queryset Filtering