Skip to content

Instantly share code, notes, and snippets.

@iarp
Last active June 21, 2017 22:13
Show Gist options
  • Save iarp/249d4c69662f721fcd3a17a4e2e97a05 to your computer and use it in GitHub Desktop.
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…
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