18.1. JSON About

  • JavaScript Object Notation

  • The most popular format for data exchange

  • JSON format is similar to dict notation in Python

Python dict:

{
    'firstname': 'Mark',
    'lastname': 'Watney',
    'height': 180,
    'weight': 75.5,
    'is_staff': True,
    'is_superuser': False,
    'friends': None,
    'groups': ('users', 'staff', 'admins'),
    'project': {'id': 1, 'name': 'Ares3'}
}

JSON object:

{
    "firstname": "Mark",
    "lastname": "Watney",
    "height": 180,
    "weight": 75.5,
    "isStaff": true,
    "isSuperuser": false,
    "friends": null,
    "groups": ["users", "staff", "admins"],
    "project": {"id": 1, "name": "Ares3"}
}

18.1.1. Numbers

{'data1': 1, 'data2': 2.0}
{"data1": 1, "data2": 2.0}

18.1.2. Strings

  • Fields are always enclosed only by double quote " character

{'data1': 'Mark', "data2": "Watney"}
{"data1": "Mark", "data2": "Watney"}

18.1.3. Booleans

  • Instead of True there is true (lowercase)

  • Instead of False there is false (lowercase)

{'data1': True, 'data2': False}
{"data1": true, "data2": false}

18.1.4. None

  • Instead of None there is null

{'data': None}
{"data": null}

18.1.5. Sequences

  • list is known as array (despite the same syntax)

  • JSON has no tuple or set

  • Coma , is not allowed after the last element in list or object

  • Object of type tuple will serialize as list

  • Object of type set is not JSON serializable

{'data1': [1, 2, 3], 'data2': (1, 2, 3)}
{"data1": [1, 2, 3], "data2": [1, 2, 3]}

18.1.6. Mappings

  • dict is known as object (despite the same syntax)

  • Coma , is not allowed after the last element in list or object

{'data': {'a':1, 'b':2, 'c':3}}
{"data": {"a": 1, "b": 2, "c": 3}}

18.1.7. Identifiers

  • camelCase is convention, although snake_case is also valid

  • Fields are always enclosed only by double quote " character

{'is_superuser': True}
{"isSuperuser": true}

18.1.8. Unicode

  • Unicode characters are stored as unicode entities ("cze\\u015b\\u0107")

{'data': 'cześć'}
{"data": "cze\\u015b\\u0107"}

18.1.9. JSON or Python?

Python:

{"mission": "Ares 3",
 "launch_date": "2035-06-29T00:00:00",
 "destination": "Mars",
 "destination_landing": "2035-11-07T00:00:00",
 "destination_location": "Acidalia Planitia",
 "crew": [{"name": "Melissa Lewis", "birthdate": "1995-07-15"},
          {"name": "Rick Martinez", "birthdate": "1996-01-21"},
          {"name": "Alex Vogel", "birthdate": "1994-11-15"},
          {"name": "Chris Beck", "birthdate": "1999-08-02"},
          {"name": "Beth Johanssen", "birthdate": "2006-05-09"},
          {"name": "Mark Watney", "birthdate": "1994-10-12"}]}

JSON:

{"mission": "Ares 3",
 "launch_date": "2035-06-29T00:00:00",
 "destination": "Mars",
 "destination_landing": "2035-11-07T00:00:00",
 "destination_location": "Acidalia Planitia",
 "crew": [{"name": "Melissa Lewis", "birthdate": "1995-07-15"},
          {"name": "Rick Martinez", "birthdate": "1996-01-21"},
          {"name": "Alex Vogel", "birthdate": "1994-11-15"},
          {"name": "Chris Beck", "birthdate": "1999-08-02"},
          {"name": "Beth Johanssen", "birthdate": "2006-05-09"},
          {"name": "Mark Watney", "birthdate": "1994-10-12"}]}

Both are identical.

18.1.10. Pretty Printing JSON

  • JSON can be minified to save space for network transmission

  • Minified JSON is not human readable

  • Use python -m json.tool to prettify (humanize) output

Minified JSON file:

$ curl https://python3.info/_static/users.json
[{"_clsname": "User", "firstname": "Mark", "lastname": "Watney",
"groups": [{"_clsname": "Group", "gid": 1, "name": "users"}]},
{"_clsname": "User", "firstname": "Melissa", "lastname": "Lewis",
"groups": [{"_clsname": "Group", "gid": 1, "name": "users"},
{"_clsname": "Group", "gid": 2, "name": "admins"}]}, {"_clsname":
"User", "firstname": "Rick", "lastname": "Martinez", "groups": []}]

Pretty Printing JSON:

$ curl https://python3.info/_static/users.json |python -m json.tool
[
  {
    "_type": "User",
    "firstname": "Mark",
    "lastname": "Watney",
    "groups": [
      {
        "_type": "Group",
        "gid": 1,
        "name": "users"
      }
    ]
  },
  {
    "_type": "User",
    "firstname": "Melissa",
    "lastname": "Lewis",
    "groups": [
      {
        "_type": "Group",
        "gid": 1,
        "name": "users"
      },
      {
        "_type": "Group",
        "gid": 2,
        "name": "admins"
      }
    ]
  },
  {
    "_type": "User",
    "firstname": "Rick",
    "lastname": "Martinez",
    "groups": []
  }
]

json.tool checks JSON syntax validity:

$ echo '{"firstname": "Mark", "lastname": "Watney",}' | python -m json.tool
Illegal trailing comma before end of object: line 1 column 43 (char 42)

18.1.11. Use Case - 1

[
    {"firstname": "Mark", "lastname": "Watney", "groups": [
        {"gid": 1, "name": "staff"}]},

    {"firstname": "Melissa", "lastname": "Lewis", "groups": [
        {"gid": 1, "name": "staff"},
        {"gid": 2, "name": "admins"}]},

    {"firstname": "Rick", "lastname": "Martinez", "groups": []},
]

18.1.12. Use Case - 2

[{"firstname": "Mark", "lastname": "Watney", "addresses": [
    {"street": "2101 E NASA Pkwy", "city": "Houston", "post_code": 77058, "region": "Texas", "country": "USA"},
    {"street": "", "city": "Kennedy Space Center", "post_code": 32899, "region": "Florida", "country": "USA"}]},

 {"firstname": "Melissa", "lastname": "Lewis", "addresses": [
    {"street": "4800 Oak Grove Dr", "city": "Pasadena", "post_code": 91109, "region": "California", "country": "USA"},
    {"street": "2825 E Ave P", "city": "Palmdale", "post_code": 93550, "region": "California", "country": "USA"}]},

 {"firstname": "Rick", "lastname": "Martinez", "addresses": []},

 {"firstname": "Alex", "lastname": "Vogel", "addresses": [
    {"street": "Linder Hoehe", "city": "Cologne", "post_code": 51147, "region": "North Rhine-Westphalia", "country": "Germany"}]}]