Timur Nurlygayanov
Timur Nurlygayanov

Reputation: 1245

Curl command to Python request - doesn't work

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

Answers (1)

Timur Nurlygayanov
Timur Nurlygayanov

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

Related Questions