Bubble.io API Connector对接Lambda+Rekognition传图报KeyError问题
问题描述
尝试搭建 AWS Rekognition -> Lambda -> AWS API Gateway -> Bubble.io 调用链路,传入图片base64编码完成图像识别处理。
使用的Lambda代码如下:
import json import boto3 import base64 def lambda_handler(event, context): def detect_labels(): # 初始化Rekognition客户端 client=boto3.client('rekognition') image = base64.b64decode(event['face']) # 调用Rekognition接口 response = client.detect_labels( Image={ 'Bytes': image }, MaxLabels=20, ) # 返回识别结果 return response # 执行标签识别 response = detect_labels() # 返回结果给API网关 return { 'statusCode': 200, 'body': json.dumps(response) }
在Lambda控制台使用如下测试事件验证时,函数可正常运行返回结果:
{ "face": "<imgbase64codehere>" }
但在Bubble.io的API Connector中完成相同参数配置后调用失败,查看CloudWatch日志报错如下:
[ERROR] KeyError: 'face' Traceback (most recent call last): File "/var/task/lambda_function.py", line 30, in lambda_handler response = detect_labels() File "/var/task/lambda_function.py", line 14, in detect_labels image = base64.b64decode(event['face'])
已确认链路连通性正常(非JSON格式传参时调用可正常通行),需要排查配置错误。
故障原因
核心原因是Lambda控制台测试的事件结构,和API Gateway转发给Lambda的事件结构不一致:
- 控制台直接测试时,填写的JSON会直接作为
event对象传入Lambda处理函数,因此直接取event['face']可以正常拿到参数 - 当请求经过API Gateway(默认开启Lambda代理集成模式)时,所有请求参数、请求体都会被封装在
event对象的不同字段下,JSON格式的请求体是字符串形式存放在event['body']字段中,不会直接平铺在event根节点,因此直接取event['face']会触发键不存在的KeyError。
另外还有两个常见的隐藏坑:
- Bubble.io如果用form-data格式传参,参数会放在表单解析字段中,不会直接出现在事件根节点
- Bubble传的base64如果带
data:image/png;base64,这类Data URI前缀,直接解码会失败
修复方案
- 修改Lambda代码,兼容API Gateway代理集成和控制台测试两种场景,同时增加base64前缀清洗逻辑,修改后代码如下:
import json import boto3 import base64 import re def lambda_handler(event, context): def detect_labels(img_base64): # 初始化Rekognition客户端 client = boto3.client('rekognition') # 清洗base64可能带的Data URI前缀 clean_base64 = re.sub(r'^data:image/.+;base64,', '', img_base64) image = base64.b64decode(clean_base64) # 调用Rekognition接口 response = client.detect_labels( Image={ 'Bytes': image }, MaxLabels=20, ) return response # 兼容不同传参场景解析参数 if 'body' in event: # API Gateway代理集成场景,解析body中的JSON字符串 req_body = json.loads(event['body']) else: # 控制台直接测试场景 req_body = event # 从解析后的请求体中取face字段 response = detect_labels(req_body['face']) # 返回结果给API网关,添加CORS头适配前端调用 return { 'statusCode': 200, 'headers': { 'Access-Control-Allow-Origin': '*' }, 'body': json.dumps(response) }
- 检查Bubble.io API Connector配置:
- 请求方法设置为
POST - 请求头添加
Content-Type: application/json - 请求体选择JSON格式,根层级放置
face字段,不要使用form-data格式传参
- 请求方法设置为
- 确认API Gateway集成配置:如果未开启Lambda代理集成,需要在集成请求中配置对应映射模板,将请求体的
face字段映射到传给Lambda的事件结构中,推荐直接开启代理集成减少配置成本。
内容的提问来源于stack exchange,提问作者Harley
相关产品推荐
相关产品推荐

