Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not possible to set content-type to application/json using urllib2

This little baby:

import urllib2
import simplejson as json

opener = urllib2.build_opener()
opener.addheaders.append(('Content-Type', 'application/json'))
response = opener.open('http://localhost:8000',json.dumps({'a': 'b'}))

Produces the following request (as seen with ngrep):

sudo ngrep -q -d lo '^POST .* localhost:8000'

T 127.0.0.1:51668 -> 127.0.0.1:8000 [AP]
  POST / HTTP/1.1..Accept-Encoding: identity..Content-Length: 10..Host: localhost:8000..Content-Type: application/x-www-form-urlencoded..Connection: close..User-Agent:
   Python-urllib/2.7....{"a": "b"} 

I do not want that Content-Type: application/x-www-form-urlencoded. I am explicitely saying that I want ('Content-Type', 'application/json')

What's going on here?!

like image 857
blueFast Avatar asked Dec 17 '12 18:12

blueFast


People also ask

Is urllib2 deprecated?

urllib2 is deprecated in python 3. x. use urllib instaed.

Can I use urllib2 in python3?

NOTE: urllib2 is no longer available in Python 3 You can get more idea about urllib.

What does urllib2 do in Python?

Urllib package is the URL handling module for python. It is used to fetch URLs (Uniform Resource Locators). It uses the urlopen function and is able to fetch URLs using a variety of different protocols.

What does urllib2 Urlopen do?

urllib2 offers a very simple interface, in the form of the urlopen function. Just pass the URL to urlopen() to get a “file-like” handle to the remote data. like basic authentication, cookies, proxies and so on. These are provided by objects called handlers and openers.


2 Answers

I got hit by the same stuff and came up with this little gem:

import urllib2
import simplejson as json

class ChangeTypeProcessor(BaseHandler):
    def http_request(self, req):
        req.unredirected_hdrs["Content-type"] = "application/json"
        return req

opener = urllib2.build_opener()
self.opener.add_handler(ChangeTypeProcessor())
response = opener.open('http://localhost:8000',json.dumps({'a': 'b'}))

You just add a handler for HTTP requests that replaces the header that OpenerDirector previously added.

like image 91
Yajo Avatar answered Sep 18 '22 14:09

Yajo


If you want to set custom headers you should use a Request object:

import urllib2
import simplejson as json

opener = urllib2.build_opener()
req = urllib2.Request('http://localhost:8000', data=json.dumps({'a': 'b'}),
      headers={'Content-Type': 'application/json'})
response = opener.open(req)
like image 38
mata Avatar answered Sep 21 '22 14:09

mata