Skip to content
Schlameel edited this page Jan 27, 2022 · 7 revisions

Members

Member identifies a Python class attribute that will be mapped to a JSON element. By default the attribute name will be mapped to the same JSON name. So JSON like:

{ "foo" : 1, "bar" : "baz" }

could be described with an object like:

class MyClass(JsonCls):
	foo = Member()
	bar = Member()

This will allow you to do the following:

>>> json_str = '{ "foo" : 1, "bar" : "baz" }'
>>> mc = MyClass().json(json_str)
>>> print mc.foo
1

Member is where much of the work takes place. You can specify options to define how JsonCls maps the JSON to your objects.

Parameters

cls and CustomMember

When a member is of a specific class, use CustomMember and the cls parameter to tell JsonCls what kind of object to map a JSON object to.

json_str = '{ "title" : "To Kill a Mockingbird", \
              "author" : { \
                "first" : "Harper", \
                "last" : "Lee" } \
             }'

class Author(JsonCls):
    first = Member()
    last = Member()

class Book(JsonCls):
    title = Member()
    author = CustomMember(cls=Author)

islist - For arrays

To accept a list of items, set islist to True

json_dct = { 'radians' : [ 1.2, 4.0, 5.5, 0.8 ] }

class Data(JsonCls):
    radians = Member(islist=True)

json_name and path - Defined mapping

By default, JsonCls will look for JSON elements with the same names as the Python attributes, or if a Mapper is defined with _mapper, JsonCls will follow the rules in the Mapper. By using the Member parameters json_name and path you can specify the name of the JSON element to map to the member, creating exceptions to the Mapper's rules. See Mapper for programmatic mapping.

json_dct = { 'id' : 'hux82ju', 'team' : { 'name' : 'Flyers' } }

class Team(JsonCls):
    team_id = Member(json_name='id')
    name = Member(path='team.name')

path details

The path parameter accepts a string and allows you to go beyond the first level of element names. The notation for path is:

  • element . element - Use . to indicate level.
  • element [] - Use [] to indicate a list of items. Note that this will require the use of islist.
  • element . * - Use * to create a dict with each JSON element a Python key and the values assigned accordingly. See all_keys for details

isprivate - Map into a private attribute

Keep the established mapping rules, but allow the Python attribute to have the prepended '_' to indicate private attributes.

json_str = "{ 'foo' : 'baz', 'bar' : 'qux' }"

class Mine(JsonCls):
    _foo = Member(isprivate=True)
    bar = Member()

enforce_type - Type checking

This option will check that the supplied JSON can be used to create the Python member and throw a TypeError when the types do not match.

all_keys - Consume all JSON elements

This bool option tells JsonCls to create a dict where each JSON key or name becomes a key in the dict. The JSON values are used to create create new objects in the case of a CustomMember or simply added as the value associated with the key.

json_str = '{ "thumbnails" : 
                { "large" : 
                    { "url" : "http://somewhere.com/image/l.jpg" },
                  "med" : 
                    { "url" : "http://somewhere.com/image/m.jpg" },
                  "small" : 
                    { "url" : "http://somewhere.com/image/s.jpg" }}}'

class Thumbnail(JsonCls):
    url = Member()

class Image(JsonCls):
    thumbnails = CustomMember(cls=Thumbnail, all_keys=True)
    
image = Image().json(json_str)
print image.thumnails['med'].url
Prints:
http://somewhere.com/image/m.jpg

cls_factory - Dynamic determination of the object type

When ingesting JSON, the type of the object to be created may not be known at compile time. cls_factory allows the specification of a function to determine the type.

response_1 = '{ "processingTime" : 101,
                "response" : 
                  {  "videoId" : "79ssh",
                     "title" : "A Long Weekend", 
                     "director" : "Brad Wilson" } }
response_2 = '{ "processingTime" : 101,
                "response" : 
                  {  "songId" : "us5mz",
                     "title" : "Dropping Out Of School",
                     "writer" : "Brad Sucks" } }

class Video(JsonCls):
    id = Member(json_name='videoId')
    title = Member()
    directory = Member()
    
class Song(JsonCls):
    id = Member(json_name='songId')
    title = Member()
    writer = Member()

def my_cls_factory(item):
    dct = json.loads(item)
    if 'songId' in dct.keys():
        return Song
    if 'videoId' in dct.keys():
        return Video

class Data(JsonCls):
    _mapper = CamelMapper()
    processing_time = Member()
    response = CustomMember(cls_factory=my_cls_factory)

Clone this wiki locally