JSON

JavaScript Object Notation (JSON) is a standard way of representing simple objects, such as lists and dicts, in the form of text strings. Although, it was originally developed for JavaScript, JSON is language independent and most languages can work with it. It's lightweight, yet flexible enough to handle a broad range of data. This makes it ideal for exchanging data over HTTP, and a large number of web APIs use this as their primary data format.

Encoding and decoding

We use the json module for working with JSON in Python. Let's create a JSON representation of a Python list by using the following commands:

>>> import json
>>> l = ['a', 'b', 'c']
>>> json.dumps(l)
'["a", "b", "c"]'

We use the json.dumps() function for converting an object to a JSON string. In this case, we can see that the JSON string appears to be identical to Python's own representation of a list, but note that this is a string. Confirm this by doing the following:

>>> s = json.dumps(['a', 'b', 'c'])
>>> type(s)
<class 'str'>
>>> s[0]
'['

Converting JSON to a Python object is also straightforward, as shown here:

>>> s = '["a", "b", "c"]'
>>> l = json.loads(s)
>>> l
['a', 'b', 'c']
>>> l[0]
'a'

We use the json.loads() function, and just pass it a JSON string. As we'll see, this is very powerful when interacting with web APIs. Typically, we will receive a JSON string as the body of an HTTP response, which can simply be decoded using json.loads() to provide immediately usable Python objects.

Using dicts with JSON

JSON natively supports a mapping-type object, which is equivalent to a Python dict. This means that we can work directly with dicts through JSON.

>>> json.dumps({'A':'Arthur', 'B':'Brian', 'C':'Colonel'})
'{"A": "Arthur", "C": "Colonel", "B": "Brian"}'

Also, it is useful to know how JSON handles nested objects.

>>> d = {
...     'Chapman': ['King Arthur', 'Brian'],
...     'Cleese': ['Sir Lancelot', 'The Black Knight'],
...     'Idle': ['Sir Robin', 'Loretta'],
... }
>>> json.dumps(d)
'{"Chapman": ["King Arthur", "Brian"], "Idle": ["Sir Robin", "Loretta"], "Cleese": ["Sir Lancelot", "The Black Knight"]}'

There is just one gotcha though: JSON dictionary keys can only be in the form of strings.

>>> json.dumps({1:10, 2:20, 3:30})
'{"1": 10, "2": 20, "3": 30}'

Notice, how the keys in the JSON dictionary become string representations of integers? To decode a JSON dictionary that uses numeric keys, we need to manually type-convert them if we want to work with them as numbers. Do the following to accomplish this:

>>> j = json.dumps({1:10, 2:20, 3:30})
>>> d_raw = json.loads(j)
>>> d_raw
{'1': 10, '2': 20, '3': 30}
>>> {int(key):val for key,val in d_raw.items()}
{1: 10, 2: 20, 3: 30}

We just use a dictionary comprehension to apply int() to the dictionary's keys.

Other object types

JSON cleanly handles only Python lists and dicts, for other object types json may attempt to cast the object type as one or the other, or fail completely. Try a tuple, as shown here:

>>> json.dumps(('a', 'b', 'c'))
'["a", "b", "c"]'

JSON doesn't have a tuple data type, so the json module will cast it to a list. If we convert it back:

>>> j = json.dumps(('a', 'b', 'c'))
>>> json.loads(j)
['a', 'b', 'c']

It will still remain a list. The json module doesn't support sets, so they also need to be recast as lists. Try the following commands:

>>> s = set(['a', 'b', 'c'])
>>> json.dumps(s)
...
TypeError: {'a', 'c', 'b'} is not JSON serializable
>>> json.dumps(list(s))
'["a", "b", "c"]'

This will cause problems similar to the ones caused by tuples. If we convert the JSON back to a Python object, then it will be a list and not a set.

We almost never encounter web APIs that need these kinds of specialist Python objects, and if we do, then the API should provide some kind of convention for handling it. But we do need to keep track of any conversions that we would need to apply to the outgoing or the incoming objects, if we were storing the data locally in any format other than that of lists or dicts.

Now that we have an understanding of JSON, let's see how it works in a web API.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.99.71