Reputation: 1245
I'm trying to convert the following curl (which works fine) to Python code:
curl -X POST https://api.example.com/c \
-H 'Authorization: Bearer {token}' \
-H 'content-type: multipart/form-data' \
-F 'attachment[c_id]=1111' \
-F 'attachment[file]=@file.png'
I've tried two different options:
Option #1:
import requests
headers = {
'Authorization': 'Bearer {token}',
'content-type': 'multipart/form-data',
}
files = {
'attachment[c_id]': (None, '1111'),
'attachment[file]': ('file.png', open('file.png', 'rb')),
}
response = requests.post('https://api.example.com/c',
headers=headers, files=files)
Option #2:
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
headers = {
'Authorization': 'Bearer {token}',
'content-type': 'multipart/form-data',
}
multipart_data = MultipartEncoder(
fields=(
('attachment[file]', open('file.png', 'rb')),
('attachment[c_id]', '1111')
))
response = requests.post('https://api.example.com/c',
headers=headers, data=multipart_data)
Both options failed with the following error:
requests.exceptions.ConnectionError: ('Connection aborted.', BrokenPipeError(32, 'Broken pipe'))
So, it means that Python code works in a different way because curl works just fine.
I've tried https://curl.trillworks.com/ - it didn't help, unfortunately. How can I do the same on Python?
Upvotes: 1
Views: 470
Reputation: 1245
I've just found the solution - the problem was in the Content-Type headers.
Important: when we use the "files" parameter for request, we shouldn't use the Content-Type header, requests will set it on his own (the size of payload should be in this header, and requests library will add this information automatically).
The following code works just fine:
import requests
headers = {
'Authorization': 'Bearer {token}',
}
files = (
('attachment[c_id]', (None, '1111')),
('attachment[file]', ('file.png', open('file.png', 'rb')))
)
response = requests.post('https://api.example.com/c',
headers=headers, files=files)
Upvotes: 1