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
Python Setup.Py Develop VS Install
How to Access "Static" Class Variables Within Methods in Python
Differences Between 'Input' and 'Raw_Input'
Reading an Excel File in Python Using Pandas
How to Run Pip from Different Versions of Python Using the Python Command
Iterate Over Model Instance Field Names and Values in Template
Python: Get Output of the Shell Command 'History'
Explaining the 'Self' Variable to a Beginner
Difference Between Exit() and Sys.Exit() in Python
Python:List Index Out of Range Error While Iteratively Popping Elements
Python's Equivalent of && (Logical-And) in an If-Statement
How to Split Elements of a List
Removing Item from List Causes the List to Become Nonetype
How to Check Whether a File Is Empty or Not
Python Matplotlib Update Scatter Plot from a Function
Logging Uncaught Exceptions in Python