jsonobject.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014-2016 OpenMarket Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. class JsonEncodedObject(object):
  16. """ A common base class for defining protocol units that are represented
  17. as JSON.
  18. Attributes:
  19. unrecognized_keys (dict): A dict containing all the key/value pairs we
  20. don't recognize.
  21. """
  22. valid_keys = [] # keys we will store
  23. """A list of strings that represent keys we know about
  24. and can handle. If we have values for these keys they will be
  25. included in the `dictionary` instance variable.
  26. """
  27. internal_keys = [] # keys to ignore while building dict
  28. """A list of strings that should *not* be encoded into JSON.
  29. """
  30. required_keys = []
  31. """A list of strings that we require to exist. If they are not given upon
  32. construction it raises an exception.
  33. """
  34. def __init__(self, **kwargs):
  35. """ Takes the dict of `kwargs` and loads all keys that are *valid*
  36. (i.e., are included in the `valid_keys` list) into the dictionary`
  37. instance variable.
  38. Any keys that aren't recognized are added to the `unrecognized_keys`
  39. attribute.
  40. Args:
  41. **kwargs: Attributes associated with this protocol unit.
  42. """
  43. for required_key in self.required_keys:
  44. if required_key not in kwargs:
  45. raise RuntimeError("Key %s is required" % required_key)
  46. self.unrecognized_keys = {} # Keys we were given not listed as valid
  47. for k, v in kwargs.items():
  48. if k in self.valid_keys or k in self.internal_keys:
  49. self.__dict__[k] = v
  50. else:
  51. self.unrecognized_keys[k] = v
  52. def get_dict(self):
  53. """ Converts this protocol unit into a :py:class:`dict`, ready to be
  54. encoded as JSON.
  55. The keys it encodes are: `valid_keys` - `internal_keys`
  56. Returns
  57. dict
  58. """
  59. d = {
  60. k: _encode(v) for (k, v) in self.__dict__.items()
  61. if k in self.valid_keys and k not in self.internal_keys
  62. }
  63. d.update(self.unrecognized_keys)
  64. return d
  65. def __str__(self):
  66. return "(%s, %s)" % (self.__class__.__name__, repr(self.__dict__))
  67. def _encode(obj):
  68. if type(obj) is list:
  69. return [_encode(o) for o in obj]
  70. if isinstance(obj, JsonEncodedObject):
  71. return obj.get_dict()
  72. return obj