Skip to content

Commit bf7ea3d

Browse files
kimnamuclaude
andcommitted
feat(event_handler): allow custom serializer on BedrockAgentResolver
BedrockAgentResolver did not expose the `serializer` parameter that its parent ApiGatewayResolver and its sibling BedrockAgentFunctionResolver already accept, so there was no way to override the default `ensure_ascii=True` serialization. Non-ASCII agent responses (e.g. Korean/Japanese/emoji) were therefore always \uXXXX-escaped in responseBody.body. Expose the existing parent `serializer` argument and pass it through to super().__init__, matching the sibling resolver. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 683ba5f commit bf7ea3d

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

aws_lambda_powertools/event_handler/bedrock_agent.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,17 @@ def lambda_handler(event, context):
9999

100100
current_event: BedrockAgentEvent
101101

102-
def __init__(self, debug: bool = False, enable_validation: bool = True):
102+
def __init__(
103+
self,
104+
debug: bool = False,
105+
enable_validation: bool = True,
106+
serializer: Callable[[dict], str] | None = None,
107+
):
103108
super().__init__(
104109
proxy_type=ProxyEventType.BedrockAgentEvent,
105110
cors=None,
106111
debug=debug,
107-
serializer=None,
112+
serializer=serializer,
108113
strip_prefixes=None,
109114
enable_validation=enable_validation,
110115
json_body_deserializer=None,

tests/functional/event_handler/_pydantic/test_bedrock_agent.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from functools import partial
23
from typing import Any, Dict, Optional
34

45
import pytest
@@ -383,3 +384,37 @@ def run_sql_query(query: Annotated[str, Query()]):
383384
# THEN the parameter with commas should be correctly passed to the handler
384385
body = json.loads(result["response"]["responseBody"]["application/json"]["body"])
385386
assert body["result"] == "SELECT a.source_name, b.thing FROM table"
387+
388+
389+
def test_bedrock_agent_with_default_serializer_escapes_non_ascii():
390+
# GIVEN a Bedrock Agent resolver using the default serializer
391+
app = BedrockAgentResolver()
392+
393+
@app.get("/claims", description="Gets claims")
394+
def claims() -> Dict[str, Any]:
395+
return {"output": "잔액은 1,000원입니다 💰"}
396+
397+
# WHEN calling the event handler
398+
result = app(load_event("bedrockAgentEvent.json"), {})
399+
400+
# THEN the body is valid JSON and non-ASCII characters are escaped (default json.dumps behavior)
401+
body = result["response"]["responseBody"]["application/json"]["body"]
402+
assert "\\uc794" in body # "잔" escaped
403+
assert json.loads(body) == {"output": "잔액은 1,000원입니다 💰"}
404+
405+
406+
def test_bedrock_agent_with_custom_serializer_preserves_non_ascii():
407+
# GIVEN a Bedrock Agent resolver initialized with a custom serializer that keeps non-ASCII characters
408+
app = BedrockAgentResolver(serializer=partial(json.dumps, ensure_ascii=False))
409+
410+
@app.get("/claims", description="Gets claims")
411+
def claims() -> Dict[str, Any]:
412+
return {"output": "잔액은 1,000원입니다 💰"}
413+
414+
# WHEN calling the event handler
415+
result = app(load_event("bedrockAgentEvent.json"), {})
416+
417+
# THEN the non-ASCII characters are preserved verbatim in the response body
418+
body = result["response"]["responseBody"]["application/json"]["body"]
419+
assert "잔액은 1,000원입니다 💰" in body
420+
assert json.loads(body) == {"output": "잔액은 1,000원입니다 💰"}

0 commit comments

Comments
 (0)