13

I've been trying to figure out how to load JSON objects in Python.

   def do_POST(self):
    length = int(self.headers['Content-Length'])
    decData = str(self.rfile.read(length))
    print decData, type(decData)
    "{'name' : 'journal2'}" <type 'str'>
    postData = json.loads(decData)
    print postData, type(postData)
    #{'name' : 'journal2'} <type 'unicode'>
    postData = json.loads(postData)
    print postData, type(postData)
    # Error: Expecting property name enclosed in double quotes

Where am I going wrong?

Error Code (JScript):

var data = "{'name':'journal2'}";
var http_request = new XMLHttpRequest();
http_request.open( "post", url, true );
http_request.setRequestHeader('Content-Type', 'application/json');
http_request.send(data);

True Code (JScript):

var data = '{"name":"journal2"}';
var http_request = new XMLHttpRequest();
http_request.open( "post", url, true );
http_request.setRequestHeader('Content-Type', 'application/json');
http_request.send(JSON.stringify(data));

True Code (Python):

   def do_POST(self):
    length = int(self.headers['Content-Length'])
    decData = self.rfile.read(length)
    postData = json.loads(decData)
    postData = json.loads(postData)
fragilewindows
  • 1,394
  • 1
  • 15
  • 26
vinni_pux
  • 165
  • 1
  • 1
  • 7

3 Answers3

11

Your JSON data is enclosed in extra quotes making it a JSON string, and the data contained within that string is not JSON.

Print repr(decData) instead, you'll get:

'"{\'name\' : \'journal2\'}"'

and the JSON library is correctly interpreting that as one string with the literal contents {'name' : 'journal2'}. If you stripped the outer quotes, the contained characters are not valid JSON, because JSON strings must always be enclosed in double quotes.

For all the json module is concerned, decData could just as well have contained "This is not JSON" and postData would have been set to u'This is not JSON'.

>>> import json
>>> decData = '''"{'name' : 'journal2'}"'''
>>> json.loads(decData)
u"{'name' : 'journal2'}"
>>> json.loads(json.loads(decData))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 1 (char 1)

Fix whatever is producing this string, your view is fine, it's the input that is broken.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
5

To workaround the error 'Expecting property name enclosed in double quotes' you can do:

import json
data = "{'name' : 'journal2'}"
json.loads(json.dumps(data))
  • 6
    this is not right, `eval(data)` may get the right result – WeizhongTu Nov 24 '15 at 04:38
  • 1
    That's true but you shouldn't use eval() I think that is the idea of using json module. Use eval is considered a bad practice, I this is an interesting answer about it http://stackoverflow.com/a/1832957/2289246 – J.Serra Aug 18 '16 at 11:18
-3

You can also go with eval:

data = "{'name' : 'test'}"
eval(data)

It works and returns you a dict.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Manoj Jadhav
  • 1,270
  • 1
  • 15
  • 23
  • 1
    Judging from the accepted answer, you are starting at the wrong point (you'd need `data = '''"{'name' : 'journal2'}"'''` to accurately represent what the OP is given), which probably means the `eval` is less helpful. – Jonathan Leffler Feb 20 '17 at 07:42