104 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
# -*- coding: utf-8 -*-
 | 
						|
# Copyright 2014-2016 OpenMarket Ltd
 | 
						|
#
 | 
						|
# Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
# you may not use this file except in compliance with the License.
 | 
						|
# You may obtain a copy of the License at
 | 
						|
#
 | 
						|
#     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing, software
 | 
						|
# distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
# See the License for the specific language governing permissions and
 | 
						|
# limitations under the License.
 | 
						|
 | 
						|
 | 
						|
class JsonEncodedObject(object):
 | 
						|
    """ A common base class for defining protocol units that are represented
 | 
						|
    as JSON.
 | 
						|
 | 
						|
    Attributes:
 | 
						|
        unrecognized_keys (dict): A dict containing all the key/value pairs we
 | 
						|
            don't recognize.
 | 
						|
    """
 | 
						|
 | 
						|
    valid_keys = []  # keys we will store
 | 
						|
    """A list of strings that represent keys we know about
 | 
						|
    and can handle. If we have values for these keys they will be
 | 
						|
    included in the `dictionary` instance variable.
 | 
						|
    """
 | 
						|
 | 
						|
    internal_keys = []  # keys to ignore while building dict
 | 
						|
    """A list of strings that should *not* be encoded into JSON.
 | 
						|
    """
 | 
						|
 | 
						|
    required_keys = []
 | 
						|
    """A list of strings that we require to exist. If they are not given upon
 | 
						|
    construction it raises an exception.
 | 
						|
    """
 | 
						|
 | 
						|
    def __init__(self, **kwargs):
 | 
						|
        """ Takes the dict of `kwargs` and loads all keys that are *valid*
 | 
						|
        (i.e., are included in the `valid_keys` list) into the dictionary`
 | 
						|
        instance variable.
 | 
						|
 | 
						|
        Any keys that aren't recognized are added to the `unrecognized_keys`
 | 
						|
        attribute.
 | 
						|
 | 
						|
        Args:
 | 
						|
            **kwargs: Attributes associated with this protocol unit.
 | 
						|
        """
 | 
						|
        for required_key in self.required_keys:
 | 
						|
            if required_key not in kwargs:
 | 
						|
                raise RuntimeError("Key %s is required" % required_key)
 | 
						|
 | 
						|
        self.unrecognized_keys = {}  # Keys we were given not listed as valid
 | 
						|
        for k, v in kwargs.items():
 | 
						|
            if k in self.valid_keys or k in self.internal_keys:
 | 
						|
                self.__dict__[k] = v
 | 
						|
            else:
 | 
						|
                self.unrecognized_keys[k] = v
 | 
						|
 | 
						|
    def get_dict(self):
 | 
						|
        """ Converts this protocol unit into a :py:class:`dict`, ready to be
 | 
						|
        encoded as JSON.
 | 
						|
 | 
						|
        The keys it encodes are: `valid_keys` - `internal_keys`
 | 
						|
 | 
						|
        Returns
 | 
						|
            dict
 | 
						|
        """
 | 
						|
        d = {
 | 
						|
            k: _encode(v)
 | 
						|
            for (k, v) in self.__dict__.items()
 | 
						|
            if k in self.valid_keys and k not in self.internal_keys
 | 
						|
        }
 | 
						|
        d.update(self.unrecognized_keys)
 | 
						|
        return d
 | 
						|
 | 
						|
    def get_internal_dict(self):
 | 
						|
        d = {
 | 
						|
            k: _encode(v, internal=True)
 | 
						|
            for (k, v) in self.__dict__.items()
 | 
						|
            if k in self.valid_keys
 | 
						|
        }
 | 
						|
        d.update(self.unrecognized_keys)
 | 
						|
        return d
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return "(%s, %s)" % (self.__class__.__name__, repr(self.__dict__))
 | 
						|
 | 
						|
 | 
						|
def _encode(obj, internal=False):
 | 
						|
    if type(obj) is list:
 | 
						|
        return [_encode(o, internal=internal) for o in obj]
 | 
						|
 | 
						|
    if isinstance(obj, JsonEncodedObject):
 | 
						|
        if internal:
 | 
						|
            return obj.get_internal_dict()
 | 
						|
        else:
 | 
						|
            return obj.get_dict()
 | 
						|
 | 
						|
    return obj
 |