Last active
June 21, 2017 22:13
-
-
Save iarp/249d4c69662f721fcd3a17a4e2e97a05 to your computer and use it in GitHub Desktop.
I needed requests.session to store various datatypes int, float, and datetime. JSON by default does not do that, it converts everything to string and during load it leaves them as strings. This class takes the data and converts the various datatypes into strings (prepended by another string defining its type). During load, it reconverts the data…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
from django.contrib.sessions.serializers import BaseJSONSerializer | |
import traceback | |
import datetime | |
class CustomJSONSerializer: | |
""" | |
value type to string format | |
""" | |
formats = { | |
'int': 'int|', | |
'float': 'float|', | |
'datetime': 'datetime|' | |
} | |
def dumps(self, obj): | |
""" Required by django """ | |
return json.dumps(self.recursive(obj, self.value_convert), separators=(',', ':')).encode('latin-1') | |
def loads(self, data): | |
""" Required by django """ | |
return self.recursive(json.loads(data.decode('latin-1')), self.value_deconvert) | |
def recursive(self, obj, method): | |
""" Recurse through the given dict (obt) to convert any needed data. | |
:param method: value_convert or value_deconvert depending on what is needed. | |
""" | |
new_obj = {} | |
for k, v in obj.items(): | |
new_obj[method('k', k)] = method('v', v) | |
return new_obj | |
def value_convert(self, key, value): | |
""" | |
Convert the value from it's original type into a string safe value. | |
:param key: nothing more than debugging reasons | |
:param value: the value to convert to string | |
:return: | |
""" | |
try: | |
if isinstance(value, dict): | |
return self.recursive(value, self.value_convert) | |
elif value is True or value is False: | |
# True/False is parsed as int in Python, need to catch it, JSON handles true/false by itself. | |
return value | |
elif isinstance(value, int): | |
return '{}{}'.format(self.formats['int'], value) | |
elif isinstance(value, float): | |
return '{}{}'.format(self.formats['float'], value) | |
elif isinstance(value, datetime.datetime): | |
return '{}{}'.format(self.formats['datetime'], value.timestamp()) | |
except: | |
print(traceback.format_exc()) | |
print(key, value) | |
return value | |
def value_deconvert(self, key, value): | |
""" | |
Convert from string into python object type. | |
:param key: nothing more than debugging reasons | |
:param value: the value to convert to python object | |
:return: | |
""" | |
try: | |
if isinstance(value, dict): | |
return self.recursive(value, self.value_deconvert) | |
elif isinstance(value, str): | |
if value.startswith(self.formats['int']): | |
return int(value.replace(self.formats['int'], '')) | |
elif value.startswith(self.formats['float']): | |
return float(value.replace(self.formats['float'], '')) | |
elif value.startswith(self.formats['datetime']): | |
return datetime.datetime.fromtimestamp(float(value.replace(self.formats['datetime'], ''))) | |
except: | |
print(traceback.format_exc()) | |
print(key, value) | |
return value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment