Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python HTTP Request Binary Data using Requests

The following code only works in curl. It would be nice if you could tell me why it isnt working in Python using Requests

curl 'http://cdcnepal.com/Modules/HOmeMoviesLists/WebService2.asmx/GetShowsByDate' \
 -H 'Content-Type: application/json; charset=UTF-8' \
 -d '{"portalId":"1","showDate":"26/05/2014","flag":0,"size":9}'

However in Python with the following code

import requests
import json
url = """http://cdcnepal.com/Modules/HOmeMoviesLists/WebService2.asmx/GetShowsByDate"""
headers = {"content-type":["application/json", "charset=UTF-8"]}
payload = {"portalId":"1","showDate":"26/05/2014","flag":0,"size":9}
r = requests.get(url, headers=headers, data=payload)
print r.text

Originally the curl request had other content, below, however I realised I could remove several. I'm not sure that is causing the error because the curl request is working. I'm not getting the same response from both the code.

This might be useful. A Curl Requests extracted from Chrome Dev Tools

curl 'http://cdcnepal.com/Modules/HOmeMoviesLists/WebService2.asmx/GetShowsByDate'
 -H 'Cookie: OriginalReferrer=https://www.google.com/;
     OriginalURL=http://cdcnepal.com/;
     ASP.NET_SessionId=i5lbnql5hpp0wm1ywyqbywtj;
     VisitCount=4' 
 -H 'Origin: http://cdcnepal.com' 
 -H 'Accept-Encoding: gzip,deflate,sdch' 
 -H 'Accept-Language: en-US,en;q=0.8,hi;q=0.6' 
 -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3)
     AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36' 
 -H 'Content-Type: application/json; charset=UTF-8' 
 -H 'Accept: application/json, text/javascript, */*; q=0.01' 
 -H 'Referer:http://cdcnepal.com/Home.aspx' 
 -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' 
 -H 'DNT: 1' 
 --data-binary '{"portalId":"1","showDate":"27/05/2014","flag":0,"size":9}' --compressed
like image 227
ShapNepal Avatar asked May 26 '14 15:05

ShapNepal


People also ask

How do you send binary data in Python?

To prepare binary data values for transmission, pack them into a buffer with struct. This client program encodes an integer, a string of two characters, and a floating point value into a sequence of bytes that can be passed to the socket for transmission.

Is binary data allowed in GET method?

When a GET method returns binary data, the Swagger document that is generated by IBM® Cúram Social Program Management specifies the Response Content type as anything other than application/json. This response indicates that binary content and not JSON content is provided in the response.

Can Python handle the binary files?

Python has tools for working with binary files. Binary files use strings of type bytes. This means when reading binary data from a file, an object of type bytes is returned. The binary file is opened using the open() function, whose mode parameter contains the character 'b'.

How do you post data requests in Python?

The post() method sends a POST request to the specified url. The post() method is used when you want to send some data to the server.


1 Answers

The curl -d switch sends a POST request, but you are using requests.get() instead, sending a GET request (whose body is ignored).

Make it a POST instead, by using request.post():

import requests
import json

url = "http://cdcnepal.com/Modules/HOmeMoviesLists/WebService2.asmx/GetShowsByDate"
headers = {"content-type": "application/json; charset=UTF-8"}
payload = {"portalId":"1","showDate":"26/05/2014","flag":0,"size":9}
r = requests.post(url, headers=headers, data=json.dumps(payload))
print r.text

You also need to:

  1. not use a list for the content-type header, there is no support for paramaters being specified separately.
  2. Encode your JSON data to a JSON string; requests doesn't do this for you. Instead, a dictionary passed to data is encoded as application/x-www-form-urlencoded data instead.

You can compare the curl command with requests more easily using http://httpbin.org/post:

$ curl http://httpbin.org/post \
>  -H 'Content-Type: application/json; charset=UTF-8' \
>  -d '{"portalId":"1","showDate":"26/05/2014","flag":0,"size":9}'

{
  "args": {},
  "data": "{\"portalId\":\"1\",\"showDate\":\"26/05/2014\",\"flag\":0,\"size\":9}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "*/*",
    "Connection": "close",
    "Content-Length": "58",
    "Content-Type": "application/json; charset=UTF-8",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.30.0",
    "X-Request-Id": "78d7bb7d-e29b-482b-908a-48d2395a050f"
  },
  "json": {
    "flag": 0,
    "portalId": "1",
    "showDate": "26/05/2014",
    "size": 9
  },
  "origin": "84.92.98.170",
  "url": "http://httpbin.org/post"
}

and

>>> import requests
>>> import json
>>> from pprint import pprint
>>> url = 'http://httpbin.org/post'
>>> headers = {"content-type":"application/json; charset=UTF-8"}
>>> payload = {"portalId":"1","showDate":"26/05/2014","flag":0,"size":9}
>>> r = requests.post(url, headers=headers, data=json.dumps(payload))
>>> pprint(r.json())
{u'args': {},
 u'data': u'{"portalId": "1", "flag": 0, "size": 9, "showDate": "26/05/2014"}',
 u'files': {},
 u'form': {},
 u'headers': {u'Accept': u'*/*',
              u'Accept-Encoding': u'gzip, deflate, compress',
              u'Connection': u'close',
              u'Content-Length': u'65',
              u'Content-Type': u'application/json; charset=UTF-8',
              u'Host': u'httpbin.org',
              u'User-Agent': u'python-requests/2.2.1 CPython/2.7.6 Darwin/13.1.0',
              u'X-Request-Id': u'06d6b542-c279-4898-8701-2c0d502aa36e'},
 u'json': {u'flag': 0,
           u'portalId': u'1',
           u'showDate': u'26/05/2014',
           u'size': 9},
 u'origin': u'84.92.98.170',
 u'url': u'http://httpbin.org/post'}

Both cases show the same json dictionary being returned.

If you are using requests version 2.4.2 or newer, you can also leave the JSON encoding to the library; it'll set the correct Content-Type header too, if you pass in the data to send as the json keyword argument:

import requests

url = "http://cdcnepal.com/Modules/HOmeMoviesLists/WebService2.asmx/GetShowsByDate"
payload = {"portalId":"1","showDate":"26/05/2014","flag":0,"size":9}
r = requests.post(url, json=payload)
print r.text
like image 172
Martijn Pieters Avatar answered Sep 19 '22 11:09

Martijn Pieters