Mayur Rokade
Mayur Rokade

Reputation: 512

How to send file and data using requests?

I am trying to send a python file and some json data to the server via python requests module. Below is the snippet of my code.

files = {'file': (FILE, open('test_hello.py', 'rb'), 'text/plain')}
job_data = dict(name='nice', interval=50, script_path="crap")
r = post(url=url, data=job_data, files=files)

r.status_code
400

r.text
u'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>400 Bad Request</title>\n<h1>Bad Request</h1>\n<p>The browser (or proxy) sent a request that this server could not understand.</p>\n'

I am getting status code 400. Can someone please point out what am I missing here ? Or share a correct code snippet ?

PS: I have seen similar questions on stackoverflow but they all give the same error code. I have tried them.

NOTE: I am using Flask 0.10 on server side

UPDATE: The client-side code was working fine. It was my server side Flask code which was bad. It even gave an error message saying "Bad Request"

r.text
400 Bad Request</title>\n<h1>Bad Request</h1>\n<p>The browser (or proxy) sent a request that this server could not understand.'

This error message made me think that client side code is not working as expected even though its looks good and is similar to other stackoverflow questions I have tried.

Thanks to all for responding to the question.

Upvotes: 1

Views: 3619

Answers (3)

Josh J
Josh J

Reputation: 6893

Your code works as written when I POST to httpbin. Whatever service you are sending data too is expecting something else though so without knowing what it is expecting, we cannot help further.

>>> import requests
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('test_hello.py', open('test_hello.py', 'rb'), 'text/plain')}
>>> job_data = dict(name='nice', interval=50, script_path="crap")
>>> r = requests.post(url=url, data=job_data, files=files)
>>> r.status_code
200
>>> r.json()
{u'files': {u'file': u"print 'hi'\n"}, u'origin': u'208.91.164.254', u'form': {u'script_path': u'crap', u'interval': u'50', u'name': u'nice'}, u'url': u'http://httpbin.org/post', u'args': {}, u'headers': {u'Content-Length': u'462', u'Accept-Encoding': u'gzip, deflate', u'Accept': u'*/*', u'User-Agent': u'python-requests/2.8.1', u'Host': u'httpbin.org', u'Content-Type': u'multipart/form-data; boundary=8064073dc3f1449cb3e46a7a6c5669a3'}, u'json': None, u'data': u''}

Upvotes: 2

tallus
tallus

Reputation: 168

Using data as a parameter sends it as a form-encoded data not as json unless suitable encoded. json.dumps(data) is typically used to encode python data as json but recent versions of Requests have json handling built in.

r = post(url=url, json=job_data, files=files)

will send job_data to the server as a json encoded string.

Upvotes: 0

Sentient07
Sentient07

Reputation: 1290

A 400 means that the request was malformed. The data stream sent by you to the server didn't follow the rules, it expects data of a certain type (say JSON) but the type of object that you're sending is a . They both are different and check out python's JSON module and use them in future while dealing with JSON objects

Upvotes: 1

Related Questions