Files
fastapi-cache/fastapi_cache/coder.py

71 lines
1.8 KiB
Python
Raw Normal View History

import datetime
2020-08-26 18:04:57 +08:00
import json
import pickle # nosec:B403
from decimal import Decimal
2020-08-26 18:04:57 +08:00
from typing import Any
from fastapi.encoders import jsonable_encoder
2020-08-26 18:04:57 +08:00
import dateutil.parser
CONVERTERS = {
"date": dateutil.parser.parse,
"datetime": dateutil.parser.parse,
"decimal": Decimal,
}
class JsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
if obj.tzinfo:
return {"val": obj.strftime("%Y-%m-%d %H:%M:%S%z"), "_spec_type": "datetime"}
else:
return {"val": obj.strftime("%Y-%m-%d %H:%M:%S"), "_spec_type": "datetime"}
elif isinstance(obj, datetime.date):
return {"val": obj.strftime("%Y-%m-%d"), "_spec_type": "date"}
elif isinstance(obj, Decimal):
return {"val": str(obj), "_spec_type": "decimal"}
else:
return jsonable_encoder(obj)
def object_hook(obj):
_spec_type = obj.get("_spec_type")
if not _spec_type:
return obj
if _spec_type in CONVERTERS:
return CONVERTERS[_spec_type](obj["val"])
else:
raise TypeError("Unknown {}".format(_spec_type))
2020-08-26 18:04:57 +08:00
class Coder:
@classmethod
def encode(cls, value: Any):
raise NotImplementedError
@classmethod
def decode(cls, value: Any):
raise NotImplementedError
class JsonCoder(Coder):
@classmethod
def encode(cls, value: Any):
return json.dumps(value, cls=JsonEncoder)
2020-08-26 18:04:57 +08:00
@classmethod
def decode(cls, value: Any):
return json.loads(value, object_hook=object_hook)
2020-08-26 18:04:57 +08:00
class PickleCoder(Coder):
@classmethod
def encode(cls, value: Any):
return pickle.dumps(value)
@classmethod
def decode(cls, value: Any):
return pickle.loads(value) # nosec:B403