The difference is that json.dumps applies some minor pretty-printing by default but JSON.stringify does not.
To remove all whitespace, like JSON.stringify, you need to specify the separators.
json_mylist = json.dumps(mylist, separators=(',', ':'))
Answer from Mike Cluck on Stack OverflowLong story short, is I have a wrapper over an API that pulls in a JSON from a rest call. I use json.loads() to return the response in my Python wrapper. I then use the response to make a REST call using POST method.
My problem is that I'm getting true, false, and none values converted to True, False, and None. When I make my second REST call I need them to be in the form of 'true', 'false, and 'none'. Basically, I want to preserve my string, float, and integers while converted these other types to strings.
Any ideas?
Videos
The equivalent to Python's json.dumps() in JavaScript is JSON.stringify() as in:
var jsonstr = JSON.stringify(someVariable);
Valid JSON doesn't contain structures like u'something', only "something". If you really have a string like that, it's likely from Python via repr() or similar.
If you're trying to convert Python objects to JavaScript objects from within their respective environments, in Python you would convert them to a JSON encoded strings using json.dumps(), transfer the strings to the JavaScript environment, and then use JSON.parse() to convert them back into objects.
(Keep in mind that JSON doesn't understand anything beyond some basic types such as string, float, boolean, array, and key:value structures. For example, trying to transfer a Python datetime object is likely to get you string or a collection key:value pairs rather than an actual JavaScript Date object.)
The difference is that json.dumps applies some minor pretty-printing by default but JSON.stringify does not, you can see below for same.
Python:
>>> import json
>>> json.dumps({"candidate" : 5, "data": 1})
'{"candidate": 5, "data": 1}'
Javacript:
> JSON.stringify({"candidate" : 5, "data": 1})
'{"candidate":5,"data":1}'
But with some modification, we can have the same JSON string, and to verify both are the same JSON string in formatting as well, we can generate the hash for both JSON strings and compare. There are two ways for it:-
- Modifying
javascript JSON stringto make it equivalent to apython JSON string.
Python:
Javacript:>>> import json,hashlib >>> a = json.dumps({"candidate" : 5, "data": 1}, sort_keys=True) >>> hashlib.md5(a.encode("utf-8")).hexdigest() '12db79ee4a76db2f4fc48624140adc7e'> const Crypto = require("crypto-js") undefined > const a = JSON.stringify({"candidate" : 5, "data": 1}).replaceAll(":", ": ").replaceAll(",", ", ") undefined > Crypto.MD5(a).toString(Crypto.enc.Hex) '12db79ee4a76db2f4fc48624140adc7e' - Modifying
python JSON stringto make it equivalent to ajavascript JSON string.
Python:
Javacript:>>> import json,hashlib >>> a = json.dumps({"candidate" : 5, "data": 1}, separators=(',', ':')) >>> hashlib.md5(a.encode("utf-8")).hexdigest() '92e99f0a99ad2a3b5e02f717a2fb83c2'> const Crypto = require("crypto-js") undefined > const a = JSON.stringify({"candidate" : 5, "data": 1}) undefined > Crypto.MD5(a).toString(Crypto.enc.Hex) '92e99f0a99ad2a3b5e02f717a2fb83c2'Note:- To run javascript code, crypto-js npm pkg should be installed as same location where you started the node shell.
json.dumps() is much more than just making a string out of a Python object, it would always produce a valid JSON string (assuming everything inside the object is serializable) following the Type Conversion Table.
For instance, if one of the values is None, the str() would produce an invalid JSON which cannot be loaded:
>>> data = {'jsonKey': None}
>>> str(data)
"{'jsonKey': None}"
>>> json.loads(str(data))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/System/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 "/System/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 2 (char 1)
But the dumps() would convert None into null making a valid JSON string that can be loaded:
>>> import json
>>> data = {'jsonKey': None}
>>> json.dumps(data)
'{"jsonKey": null}'
>>> json.loads(json.dumps(data))
{u'jsonKey': None}
There are other differences. For instance, {'time': datetime.now()} cannot be serialized to JSON, but can be converted to string. You should use one of these tools depending on the purpose (i.e. will the result later be decoded).
Python has a built-in JSON parsing library. Adding import json provides basic JSON parsing functionality, which can be used as follows:
import json
personString = "{'{id:'E1',firstname:'Peter',... " # This would contain your JSON string
person = json.loads( personString ) # This will parse the string into a native Python dictionary, be sure to add some error handling should a parsing error occur
person['firstname'] # Yields 'Peter'
person['activities'] # Yields a list with the activities.
More information here: http://docs.python.org/2/library/json.html
Because you are using the wrong variable!
var jsonData = JSON.stringify(jsData);
..
$.ajax({
..,
contentType: "application/json", //Remember to set this.
data: jsData,
^^^^^^ => Shouldn't you be passing "jsonData" here?
When you pass a simple javascript dictionary, jQuery encodes the keys and values in the percentile-encoding format. That is the reason why you are seeing the inner dict as string.
What you have to do ideally (IMO), is pass the JSON string rather than partially percentile encoded string.
Note that you will probably have to change the way your server is reading the data. In this way there would no longer be HTTP/POST request parameters. Just a plain JSON string in the HTTP entity section.