1 from __future__ import absolute_import

2 import json

3 import decimal

4 import datetime

5

6

7 from . import models

8

9

10 class JSONEncoder(json.JSONEncoder):

11

12 def default(self, value):

13 # The following types should simply be cast to strings

14 str_types = (

15 datetime.date,

16 datetime.datetime,

17 datetime.timedelta,

18 datetime.tzinfo,

19 decimal.Decimal,

20 )

21

22 dict_types = (

23 models.Balance,

24 models.Amount,

25 )

26

27 # Handle native types that should be converted to strings

28 if isinstance(value, str_types):

29 return str(value)

30

31 # Handling of the Transaction objects to include the actual

32 # transactions

33 elif isinstance(value, models.Transactions):

34 data = value.data.copy()

35 data['transactions'] = value.transactions

36 return data

37

38 # If an object has a `data` attribute, return that instead of the

39 # `__dict__` ro prevent loops

40 elif hasattr(value, 'data'):

41 return value.data

42

43 # Handle types that have a `__dict__` containing the data (doesn't work

44 # for classes using `__slots__` such as `datetime`)

45 elif isinstance(value, dict_types):

46 return value.__dict__

47

48 else: # pragma: no cover

49 return json.JSONEncoder.default(self, value)