class CustomJSONResponse(JSONResponse):
media_type = "application/json"
def render(self, content: typing.Any) -> bytes:
return dumps(content)
With dumps being a custom function, managing datetime values specifically.
@router.post("/requests")
async def insert_user_request(request: Request):
return CustomJSONResponse(content={"timestamp": datetime.now()}, status_code=HTTP_201_CREATED)
Will work as expected but
@router.post("/requests", response_class=CustomJSONResponse, status_code=HTTP_201_CREATED)
async def insert_user_request(request: Request):
return {"timestamp": datetime.now()}
Will fail to use the custom dump function.
The cause is in https://github.com/tiangolo/fastapi/blob/master/fastapi/routing.py#L190 : serialize_response (which calls jsonable_encoder) is called before the response_class instantiation (https://github.com/tiangolo/fastapi/blob/master/fastapi/routing.py#L201) so datetime values are converted to str prematurely.
datetime encoder is coming from pydantic : https://github.com/samuelcolvin/pydantic/blob/master/pydantic/json.py#L20 i guess it's still possible to alter this one if we need custom encoder for datetime.
@TTRh : the explicit return of an CustomJSONResponse instance works fine without having to tweak pydantic. My point is that I wouldn't have expected a different behavior between the two syntaxes.
Have the same issue. Did you solve it?
Have the same issue. Did you solve it?
Only a PR would really solve it, provided it's considered as an issue, hence my "question" here.
Two possible workarounds:
pydantic.json.ENCODERS_BY_TYPE[datetime] = lambda dt: dt.replace(tzinfo=pytz.utc).isoformat()@kshilov also you can create a workaround with default=str and encode()
class CustomJSONResponse(JSONResponse):
media_type = "application/json"
def render(self, content: typing.Any) -> bytes:
return dumps(content, default=str).encode()
This will work however, I agree with @tangi75 it is a serious bug and should be handled by a PR.
Most helpful comment
Only a PR would really solve it, provided it's considered as an issue, hence my "question" here.
Two possible workarounds:
pydantic.json.ENCODERS_BY_TYPE[datetime] = lambda dt: dt.replace(tzinfo=pytz.utc).isoformat()