1

I am attempting to upload a CSV file to an API (which gives me very little error info) using python requests library.

(I'm running Python 3.5 and using requests version 2.18.4 on OS X 10.11.6)

This curl command in terminal works fine: curl -F 'file=@/path/to/file.csv' myurl.com/upload -H "Authorization: TOKEN sometoken"

A multipart/form-data POST request from Postman also works, but I can't seem to make it work with the python requests library.

I've tried many variations of this request:

import requests
headers = {'Authorization': 'TOKEN sometoken', 'Content-Type': 'multipart/form-data'}

with open(file_path, 'rb') as f:
    r = requests.post(myurl, headers=headers, data=f)

## I've also tried data={"file": f}

I get a status code of 200, but the response is {"success": "false"} (frustratingly unhelpful).

What am I missing in the python request compared to the curl request?

EDIT: it seems that the -F flag for the curl command emulates an HTML form that has been submitted...is there a way to do this with requests?

2 Answers 2

2

In your curl code you're using the -F parameter, which submits the data as a multipart message - in other words you're uploading a file.
With requests you can post files with the files parameter. An example:

import requests

headers = {'Authorization': 'TOKEN sometoken'}
data = {'file': open(file_path, 'rb')}
r = requests.post(myurl, headers=headers, files=data)

Note that requests creates the Content-Type header automatically, based on the submitted data.

Sign up to request clarification or add additional context in comments.

2 Comments

This worked, thanks! I noticed the files param in the docs, but they only mention it specifically for multiple file uploads at the same time, which threw me off.
That's the dvanced usage documentation (in case you want to upload multiple files with the same name), and it can be confusing. The example in quickstart in is much clearer.
1

The python open() function returns a file object. This is not what you want to send to the API.
Instead, you can use:

with open(file_path, 'rb') as f:
    r = requests.post(myurl, headers=headers, data=f.read())

Syntax taken from here.

1 Comment

Unfortunately, that didn't do the trick. I wish I could provide more info, but I have absolutely no error info to go on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.