Home > OS >  Can't upload file from Python requests, while CURL is work fine
Can't upload file from Python requests, while CURL is work fine

Time:12-29

I am trying to upload file to some api with this function:

 def upload_avatar(cred, file):
     headers = {'accept': '*/*', 'Content-Type': 'multipart/form-data', 'Authorization': f'Bearer {cred}'}
     files = { 'UploadForm[avatar]': ('image1.jpg', open('image1.jpg', 'rb'), 'image/jpg')}
     signup_req = requests.post(api_enpoint   "/profile/avatar", headers=headers, files=files)
     signup_req.raise_for_status()

And get 422 Client Error: Unprocessable entity for url: https://api_endpoint/v1/profile/avatar

While CURL command works fine:

curl -v -X POST "https://api_endpoint/v1/profile/avatar" -H  "accept: */*" -H  "Content-Type: multipart/form-data" -H "Authorization: Bearer SAME_LONG_TOKEN" -F "UploadForm[avatar][email protected];type=image/jpeg"

What makes the difference?

CodePudding user response:

try this

import requests


def upload_avatar(cred, file):
    url = "https://api_endpoint/v1/profile/avatar"

    files = [
      (
          'UploadForm[avatar]',
          ('image1.jpg', open('image1.jpg', 'rb'),
           'application/octet-stream'))
    ]
    headers = {
      'accept': '*/*',
      'Authorization': 'Bearer SAME_LONG_TOKEN',
      'Content-Type': 'multipart/form-data',
      'Authorization': f'Bearer {cred}'
    }
    response = requests.request("POST", url, headers=headers, files=files)

    print(response.text)

CodePudding user response:

You can drop the headers:

  • Accept: */*
  • Content-Type: multipart/form-data

requests takes care of it on it's own when you use its json, data, files kwargs ... and if you specify them it seems to freak it out.

I used httpbin to compare the content of the curl and requests HTTP requests, it's a handy tool.

So for your example it would be:

headers = {'Authorization': f'Bearer {cred}'} 
files = {'UploadForm[avatar]': ('image1.jpg', open('image1.jpg', 'rb'), 'image/jpeg')} 
signup_req = requests.post('https://httpbin.org/post', headers=headers, files=files)
  • Related