Python - Parsing multipart/form-data request on server side

python rest api multipart/form-data
python requests multipart/form-data set boundary
python requests multipart/form-data multiple files
python http request multipart form data
python flask multipart/form-data
python-requests content-type: multipart/form-data boundary
python requests post file content-type
python requests post file and data

Im trying to do a http 'POST' with multipart/form-data to a python GAE backend. My server side method is receiving the complete body but i have absolutely no idea how to parse the body content without going over it manually and splitting the text for values.

My request looks like this:

POST /android/v4/MyPostMethod HTTP/1.1
Accept: */*
Accept-Charset: *
Content-Length: 186808
Content-Type: multipart/form-data; boundary=*****; charset="utf-8"
Content_Length: 186808
Content_Type: multipart/form-data; boundary=*****
Host: myhost.appspot.com
User-Agent: Dalvik/1.6.0 (Linux; U; Android 4.1.2; GT-I9300 Build/XXXXX)
Via: HTTP/1.1 MSP-YV

--*****
Content-Disposition: form-data; name="value1"
Content-Type: text/plain; charset=UTF-8

f0ef73c5-54dd-40cf-9ee7-5c4cb764eb28
--*****
Content-Disposition: form-data; name="value2"
Content-Type: text/plain; charset=UTF-8

10d71e73-4d4d-4607-b271-f7efcfd0c59d
--*****
Content-Disposition: form-data; name="value3"
Content-Type: text/plain; charset=UTF-8

10d71e73-4d4d-4607-b271-f7efdfdfdfdf
--*****
Content-Disposition: form-data; name="logText"; filename="log.txt"
Content-Type: text/plain
Content-Transfer-Encoding: binary

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...
--*****--

I've searched around and couldn't find a good explanation of how to do this trivial thing. Appreciate if someone could help me here. Thanks.

For some reason cgi.FieldStorage() wasnt working for me, but only the deprecated method :

pdict = {'boundary':'*****'}
cgi.parse_multipart(self.request.body_file, pdict)

Dont know why but as long as its working im fine with that.

Handling multipart/form-data natively in Python, RFC7578 (who obsoletes RFC2388) defines the multipart/form-data type that is While you could decode an HTTP body request made with JSON natively with Python — thanks to same goes for the majority of Web server frameworks such as Django or Flask. import email.parser msg = email.parser. Handling multipart/form-data natively in Python. RFC7578 (who obsoletes RFC2388) defines the multipart/form-data type that is usually transported over HTTP when users submit forms on your Web page. Nowadays, it tends to be replaced by JSON encoded payloads; nevertheless, it is still widely used. While you could decode an HTTP body request made with JSON natively with Python — thanks to the json module — there is no such way to do that with multipart/form-data.

You want the .cgi python library.

Specifically something like this:

import cgi
form = cgi.FieldStorage() 
value1 = form.getfirst("value1", "")
value2 = form.getfirst("value2", "") 
value3 = form.getfirst("value3", "") 
logtext = form.getfirst("logText", "")

Post Multipart Form Data in Python with Requests: Flask File Upload , In this tutorial we'll demonstrate how to upload a file from a Python server to another server by sending a POST request with multipart/form-data  Since the previous answers were written, requests have changed. Have a look at the bug thread at Github for more detail and this comment for an example.. In short, the files parameter takes a dict with the key being the name of the form field and the value being either a string or a 2, 3 or 4-length tuple, as described in the section POST a Multipart-Encoded File in the requests quickstart:

If you want the uploaded files, you can do this

for upload in self.get_uploads():

If you want just a text field:

x = self.request.get('value1')

5511 (Streaming content of multipart/form-data requests server-side), #5511 enhancement new. Streaming content of multipart/form-data requests server-side Relatedly, the multipart/form-data parser on Python 3 is broken  $ python server.py Your Python server will be available from the 127.0.0.1:8080 address. If you select a file and upload it, you should have the file uploaded in the media folder of the django server. Conclusion. In this tutorial, you've seen how you can use Python and the requests library to upload a file from a server to another server.

Issue 3244: multipart/form-data encoding, This request really does need a patch+tests+doc changes - I don't know Did you test it against server-side form-data parser implementation? Here is the python snippet you need to upload one large single file as multipart formdata. With NodeJs Multer middleware running on the server side.

Python requests multipartform data multiple files, Jan 13, 2017 · How to extract multipart/form-data from POST request and I need to parse the stream in a Python Lambda function and store the XLS file in S3. On the server side, you can access the files through the key of files which is the  from requests_toolbelt import MultipartEncoder fields = { # your multipart form fields } m = MultipartEncoder (fields, boundary='my_super_custom_header') r = requests. post (url, headers= { 'Content-Type': m. content_type }, data=m. to_string ()) In this case you do want to set your own header because you're formatting the data.

Multipart Forms, MultipartFormHandler to handle the multipart/form-data media type. The request stream is only consumed along iteration over the body parts in a form, BodyPart is meant to be instantiated directly only by the MultipartForm parser. This object provides direct access to the server's data stream and is non-​seekable. A python module of Igor Afonov's multipart-parser-c. This module leverages the state machine written in C code to provide a multipart/form-data parser to python code. This module reads from any iterable object passed to it. It avoids the need to read the entire structure into memory by returning iterators.

Comments
  • This is not ideal for large files. From the documentation "This is easy to use but not much good if you are expecting megabytes to be uploaded — in that case, use the FieldStorage class instead which is much more flexible."