Closed
Description
Expected Behaviour
My app has a custom serializer. I used enable_validation. A dict with Mongo ObjectId should have been serialized.
from bson import json_util
...
def custom_serializer(obj) -> str:
...
"""Your custom serializer function ApiGatewayResolver will use"""
return json_util.dumps(obj)
app = APIGatewayRestResolver(serializer=custom_serializer, enable_validation=True)
Current Behaviour
If we use enable_validation, the openapi modules uses its own encoders which cannot handle ObjectIds.
Traceback (most recent call last):
File "/var/task/aws_lambda_powertools/event_handler/openapi/encoders.py", line 265, in _dump_other
data = dict(obj)
TypeError: 'ObjectId' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/var/task/aws_lambda_powertools/event_handler/openapi/encoders.py", line 269, in _dump_other
data = vars(obj)
TypeError: vars() argument must have __dict__ attribute
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/var/task/aws_lambda_powertools/event_handler/api_gateway.py", line 1985, in _call_route
route(router_middlewares=self._router_middlewares, app=self, route_arguments=route_arguments),
File "/var/task/aws_lambda_powertools/event_handler/api_gateway.py", line 400, in __call__
return self._middleware_stack(app)
File "/var/task/aws_lambda_powertools/event_handler/api_gateway.py", line 1291, in __call__
return self.current_middleware(app, self.next_middleware)
File "/var/task/aws_lambda_powertools/event_handler/middlewares/base.py", line 121, in __call__
return self.handler(app, next_middleware)
File "/var/task/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py", line 121, in handler
return self._handle_response(route=route, response=response)
File "/var/task/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py", line 128, in _handle_response
response.body = self._serialize_response(
File "/var/task/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py", line 187, in _serialize_response
return jsonable_encoder(response_content)
File "/var/task/aws_lambda_powertools/event_handler/openapi/encoders.py", line 108, in jsonable_encoder
return _dump_dict(
File "/var/task/aws_lambda_powertools/event_handler/openapi/encoders.py", line 212, in _dump_dict
encoded_value = jsonable_encoder(
File "/var/task/aws_lambda_powertools/event_handler/openapi/encoders.py", line 138, in jsonable_encoder
return _dump_other(
File "/var/task/aws_lambda_powertools/event_handler/openapi/encoders.py", line 272, in _dump_other
raise ValueError(errors) from e
ValueError: [TypeError("'ObjectId' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')]
Code snippet
# Any object which contains a value of type Mongo ObjectId
ObjectId('666f6f2d6261722d71757578')
Possible Solution
My workaround is to monkey patch openapi encoder. Ideally openapi should reuse json encoder of APIGatewayRestResolver, or allow plugging in our own function.
from bson import ObjectId
from aws_lambda_powertools.event_handler.openapi.encoders import ENCODERS_BY_TYPE
ENCODERS_BY_TYPE[ObjectId] = lambda o: str(o)
Steps to Reproduce
Serialize an object which contains Mongo ObjectId
ObjectId('666f6f2d6261722d71757578')
Powertools for AWS Lambda (Python) version
latest
AWS Lambda function runtime
3.8
Packaging format used
PyPi
Debugging logs
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Shipped