Examples

In the examples below, we will try to learn how to model JSON with json2py‘. We will cover how to re-utilize models into bigger ones, like JSON support sub-documents. We will also learn how to model a list of JSON documents.

Modeling Github API

For the examples we will try to model Github’s public API (or at least a part of it). We will be model the user response from https://api.github.com/users/{user} using my user account, we will model this repo information on https://api.github.com/users/{user}/{repo_name} And with a bit more effort we will model the repo listing on https://api.github.com/users/{user}/repos. In this example, requests module will be used for simplicity, but the way of requesting remote resources is up to you.

Let’s begin!

User modelling

The user data used on this example will be extracted from https://api.github.com/users/wiston999

Let’s suppose we want to grab the user’s id, login, url, type and if user is admin. This task can be done with the following code.

We will map the type key into a field named user_type into our model.

models1.py
1
2
3
4
5
6
7
8
from json2py.models import *

class User(NestedField):
    login = TextField()
    id = IntegerField()
    url = TextField()
    user_type = TextField(name = 'type')
    site_admin = BooleanField()

And we are all done! Now let’s request the Github’s user info endpoint.

example1.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import requests
from models import User

response = requests.get('https://api.github.com/users/wiston999')
my_user = User(response.json())
print (my_user.login.value, "'s stats:")
print ("id:", my_user.id.value)
print ("login:", my_user.login.value)
print ("url:", my_user.url.value)
print ("type:", my_user.user_type.value)
print ("site_admin:", my_user.site_admin.value)

Output after executing this code is

Wiston999 's stats:
id: 1099504
login: Wiston999
url: https://api.github.com/users/Wiston999
type: User
site_admin: False

This is how modeling works, all you have to do is define class variables into the class inheriting from json2py.models.NestedField.

Repository modeling

The next step will be modeling a repository information from Github. We will use the information from this repository, https://api.github.com/repos/wiston999/json2py. We want to get the id, name, full_name, is_private, description, size, language, default_branch and the owner fields. One can notice that owner nested document looks familiar, as it shares several fields with the data on https://api.github.com/users/wiston999. We notice too that shared data is already modeled into the previous example, so, let’s use a bit of code re-utilization.

models2.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class User(NestedField):
    login = TextField()
    id = IntegerField()
    url = TextField()
    user_type = TextField(name = 'type')
    site_admin = BooleanField()

class Repo(NestedField):
    id = IntegerField()
    name = TextField()
    full_name = TextField()
    owner = User()
    is_private = BooleanField(name = 'private')
    description = TextField()
    size = IntegerField()
    language = TextField()
    default_branch = TextField()

Notice how the owner field is an instance of User class defined above.

Let’s try these models

example2.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import requests
from models import User, Repo

response = requests.get('https://api.github.com/repos/wiston999/json2py')
this_repo = Repo(response.json())
print (this_repo.name.value, "'s stats:")
print ("id:", this_repo.id.value)
print ("full_name:", this_repo.full_name.value)
print ("owner:", this_repo.owner.login.value)
print ("private:", this_repo.is_private.value)
print ("description:", this_repo.description.value)
print ("language:", this_repo.language.value)
print ("default_branch:", this_repo.default_branch.value)

Will output

json2py 's stats:
id: 54333024
full_name: Wiston999/json2py
owner: Wiston999
private: False
description: Convert JSON/dict to python object and viceversa
language: Python
default_branch: master

Repository list modeling

As a last example, lest loop the loop, we are going to model the data returned by https://api.github.com/users/Wiston999/repos request. We see that this is a list of repositories, which we have already modeled, so, this should be as simple as

models3.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class User(NestedField):
    login = TextField()
    id = IntegerField()
    url = TextField()
    user_type = TextField(name = 'type')
    site_admin = BooleanField()

class Repo(NestedField):
    id = IntegerField()
    name = TextField()
    full_name = TextField()
    owner = User()
    is_private = BooleanField(name = 'private')
    description = TextField()
    size = IntegerField()
    language = TextField()
    default_branch = TextField()

class RepoList(ListField):
    __model__ = Repo

Everything done! Let’s try it

example3.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import requests
from models import RepoList

response = requests.get('https://api.github.com/users/wiston999/repos')
user_repo_list = RepoList(response.json())
print ("wiston999's repositories:")
for repo in user_repo_list:
    print ("Repository name:", repo.name.value, "with id:", repo.id.value, "written in", repo.language.value)
    print ("Repository Owner:", repo.owner.login.value)
    print ('-'*70)

And the output

wiston999 repositories:
Repository name: BRTMT with id: 24468609 written in JavaScript
Repository Owner: Wiston999
----------------------------------------------------------------------
Repository name: cursoJS with id: 14053600 written in JavaScript
Repository Owner: Wiston999
----------------------------------------------------------------------
Repository name: DDSBox with id: 36035006 written in Java
Repository Owner: Wiston999
----------------------------------------------------------------------
Repository name: DSS with id: 20038644 written in Python
Repository Owner: Wiston999
----------------------------------------------------------------------
Repository name: ISIII with id: 3630135 written in None
Repository Owner: Wiston999
----------------------------------------------------------------------
Repository name: json2py with id: 54333024 written in Python
Repository Owner: Wiston999
----------------------------------------------------------------------
Repository name: Plataforma with id: 2506501 written in Python
Repository Owner: Wiston999
----------------------------------------------------------------------
Repository name: repos-git with id: 20038280 written in Python
Repository Owner: Wiston999
----------------------------------------------------------------------

Using Python’s reserved keywords

When the need of model JSON or dict keys that are Python’s keywords too (like from, in, for, etc.), one cannot do

class BadKeyword(NestedField):
    from = IntegerField()

as it raises SyntaxError. A workaround to solve this is use the name parameter declared in json2py.models.BaseField, so the previous can be solved with the following code

class BetterKeyword(NestedField):
    from_ = IntegerField(name = 'from')

Once name parameter is used, the name of variable can be anything distinct to Python’s keywords and previous variable names.