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}
)