TypeError: unhashable type: 'dict'
robert-nix opened this issue · 4 comments
When using @cache(coder=CustomJsonCoder)
, where CustomJsonCoder
is a subclass of fastapi_cache.coder.JsonCoder
, returning a dict
from a handler causes TypeError: unhashable type: 'dict'
to raise from #112's hash generation.
e.g.
from fastapi.encoders import jsonable_encoder
from fastapi_cache.coder import JsonCoder
class CustomJsonCoder(JsonCoder):
@classmethod
def encode(cls, value):
return jsonable_encoder(value)
@classmethod
def decode(cls, value):
return value
@router.get("/v1/example")
@cache(expire=60, coder=CustomJsonCoder)
async def get_example():
return {'message': 'test'}
Also FWIW I'm not quite sure why we needed to use this custom coder, I'm just putting this issue in to document the unintended API breakage.
Thanks! Could you submit a PR?
This is entirely expected; jsonable_encoder()
doesn't encode to JSON. It is instead meant to be used as the default
hook in a JSON encoder. It doesn't return a string, but the Coder.encode()
method must return a string, so the fact that things then break further down the line is not suprising.
This works correctly and is probably what you intended to do:
class CustomJsonCoder(JsonCoder):
@classmethod
def encode(cls, value):
return json.dumps(value, default=jsonable_encoder)
@classmethod
def decode(cls, value):
return json.loads(value)
The next release changes Coders to work with bytes instead of strings, so the above would also need to have str.encode()
and bytes.decode()
calls.
Thanks! Could you submit a PR?
The Coder interface is now firmly handling bytes, only, though, so I'm not sure how a PR could help here. ;-)
I'm closing this issue now; the coder API can only handle bytes. If there was a specific use-case for returning something else, do let us know!