Send File Using Post from a Python Script

How to upload file with python requests?

If upload_file is meant to be the file, use:

files = {'upload_file': open('file.txt','rb')}
values = {'DB': 'photcat', 'OUT': 'csv', 'SHORT': 'short'}

r = requests.post(url, files=files, data=values)

and requests will send a multi-part form POST body with the upload_file field set to the contents of the file.txt file.

The filename will be included in the mime header for the specific field:

>>> import requests
>>> open('file.txt', 'wb') # create an empty demo file
<_io.BufferedWriter name='file.txt'>
>>> files = {'upload_file': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--c226ce13d09842658ffbd31e0563c6bd
Content-Disposition: form-data; name="upload_file"; filename="file.txt"

--c226ce13d09842658ffbd31e0563c6bd--

Note the filename="file.txt" parameter.

You can use a tuple for the files mapping value, with between 2 and 4 elements, if you need more control. The first element is the filename, followed by the contents, and an optional content-type header value and an optional mapping of additional headers:

files = {'upload_file': ('foobar.txt', open('file.txt','rb'), 'text/x-spam')}

This sets an alternative filename and content type, leaving out the optional headers.

If you are meaning the whole POST body to be taken from a file (with no other fields specified), then don't use the files parameter, just post the file directly as data. You then may want to set a Content-Type header too, as none will be set otherwise. See Python requests - POST data from a file.

Python requests post a file

Your curl request sends the file contents as form data, as opposed to an actual file! You probably want something like

with open('boot.txt', 'rb') as f:
r = requests.post(url, data={'pxeconfig': f.read()})

Performing file upload post request

The js code is doing a multipart/form-data post request.

I do not believe urllib supports multipart/form-data, you can use request instead.

import requests 
with open('README.md', 'rb') as f:
files = {"file": f}
upload_credentials = {
"descr": "testing",
"title": "READMEE.md",
"contentType": "text",
"editor": username,
}
r = requests.post("http://httpbin.org/post", files=files, data=upload_credentials)
print(r.status_code)
print(r.text)

Upload file via POST multipart form-data using Python

Just post it without stream bytes and header magic:

file = {'BackupFile': open(file_name, 'rb')}
response = requests.post(url, files=file)

all the rest will make requests: will send a multi-part form POST body with the BackupFile field set to the contents of the file.txt file.
Also the filename will be included in the mime header for the specific field.

example:

>>> files = {'BackupFile': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--0c249de0e6243e92307003732e49ffe9
Content-Disposition: form-data; name="BackupFile"; filename="file.txt"
--0c249de0e6243e92307003732e49ffe9--

How to upload large files using POST method in Python?

When you pass files arg then requests lib makes a multipart form upload. i.e. it is like submitting a form, where the file is passed as a named field (file in your example)

I suspect the problem you saw is because when you pass a file object as data arg, as suggested in the docs here https://requests.readthedocs.io/en/latest/user/advanced/#streaming-uploads then it does a streaming upload but the file content is used as the whole http post body.

So I think the server at the other end is expecting a form with a file field, but we're just sending the binary content of the file by itself.

What we need is some way to wrap the content of the file with the right "envelope" as we send it to the server, so that it can recognise the data we are sending.

See this issue where others have noted the same problem: https://github.com/psf/requests/issues/1584

I think the best suggestion from there is to use this additional lib, which provides streaming multipart form file upload: https://github.com/requests/toolbelt#multipartform-data-encoder

For example:

from requests_toolbelt import MultipartEncoder
import requests

encoder = MultipartEncoder(
fields={'file': ('myfilename.xyz', open(path, 'rb'), 'text/plain')}
)
response = requests.post(
url, data=encoder, headers={'Content-Type': encoder.content_type}
)

Send file using POST from a Python

You are using the wrong field name:

file_ = {'file': ('video.mp4', open('video.mp4', 'rb'))}

That names the field file while your form uses video_file:

<input type="file" name="video_file" />

Using the right field name is important, correct your parameters:

file_ = {'video_file': ('video.mp4', open('video.mp4', 'rb'))}


Related Topics



Leave a reply



Submit