Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Requests module JSON format

I have a Django application with tastypie set up for REST.

I want to be able to update the database using the REST API.

I can issue a curl command on the command line to achive what I want, (as per the tastypie documentation).

curl --dump-header - -H "Content-Type: application/json" -X PATCH --data '{"comments": "comment1"}' http://127.0.0.1:8000/api/seq/loadedwith/12092/

HTTP/1.0 202 ACCEPTED
Date: Fri, 26 Oct 2012 11:06:58 GMT
Server: WSGIServer/0.1 Python/2.6.6
Content-Type: text/html; charset=utf-8

So now I am trying to achieve the same thing using the requests module. Get requests work from the python requests module, but I can't get patch or posts to work.

url='http://127.0.0.1:8000/api/seq/loadedwith/12092/'
headers={'content-type': 'application/json'}
payload={"comments":"comment2"}
requests.patch(url=url, params=json.dumps(payload),  headers=headers)

I get the error:

  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/requests-0.14.1-py2.7.egg/requests/api.py", line 120, in patch
      return request('patch', url,  data=data, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests-0.14.1-py2.7.egg/requests/safe_mode.py", line 39, in wrapped
      return function(method, url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests-0.14.1-py2.7.egg/requests/api.py", line 51, in request
      return session.request(method=method, url=url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/requests-0.14.1-py2.7.egg/requests/sessions.py", line 182, in request
    params=from_key_val_list(params),
  File "/usr/local/lib/python2.7/dist-packages/requests-0.14.1-py2.7.egg/requests/utils.py", line 135, in from_key_val_list
    raise ValueError('cannot encode objects that are not 2-tuples')
ValueError: cannot encode objects that are not 2-tuples

This seems to be coming when I add the json.dumps(payload) - I tried passing just the dictionary, but the payload gets added to the querysting in that case, and tastypie complains. I have tried formatting the dictionary as a tuple , but I am not sure what it expects exactly.

Can someone help, (or am I looking at the wrong place in the code)?

like image 990
wobbily_col Avatar asked Dec 08 '22 20:12

wobbily_col


1 Answers

params should always be a dict or a sequence of 2-value tuples, which are then encoded for you. You, however, want to upload an already encoded body, so you want the data keyword instead:

requests.patch(url, data=json.dumps(payload), headers=headers)

In fact, data is the second parameter, so you could even do:

requests.patch(url, json.dumps(payload), headers=headers)

as you normally only send opaque data with PATCH. The .post() and .put() methods behave in the same way, the second parameter is the data keyword.

like image 77
Martijn Pieters Avatar answered Dec 12 '22 13:12

Martijn Pieters