如何在 Python 中从 AWS 中的 lambda 函数返回二进制数据?

新手上路,请多包涵

我无法让 python lambda 返回二进制数据。 缩略图的节点模板 工作正常,但我无法让 python lambda 工作。以下是我的 lambda 中的相关行。 print("image_data " + image_64_encode) 行将 base64 编码图像打印到日志中。

 def lambda_handler(event, context):
    img_base64 = event.get('base64Image')
    if img_base64 is None:
        return respond(True, "No base64Image key")

    img = base64.decodestring(img_base64)
    name = uuid.uuid4()
    path = '/tmp/{}.png'.format(name)

    print("path " + path)

    image_result = open(path, 'wb')
    image_result.write(img)
    image_result.close()

    process_image(path)

    image_processed_path = '/tmp/{}-processed.png'.format(name)
    print("image_processed_path " + image_processed_path)
    image_processed = open(image_processed_path, 'rb')
    image_processed_data = image_processed.read()
    image_processed.close()
    image_64_encode = base64.encodestring(image_processed_data)

    print("image_data " + image_64_encode)

    return respond(False, image_64_encode)

def respond(err, res):
    return {
        'statusCode': '400' if err else '200',
        'body': res,
        'headers': {
            'Content-Type': 'image/png',
        },
        'isBase64Encoded': 'true'
    }

任何指向我做错了什么的指示?

原文由 Horv 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 588
2 个回答

遵循上述所有步骤对我的情况不起作用,因为对 content-type = */* 的二进制支持会将所有响应转换为二进制。

我的情况:

  • 多个 lambda 函数返回 json(文本),只有一个 lambda 返回二进制文件。都启用了 lambda 代理

  • lambda 在 API 网关中

  • API 网关在 CloudFront 后面

提示: 我注意到 API 网关 -> 设置中的重要信息

二进制支持说明

报价:

API 网关将查看 Content-TypeAccept HTTP 标头来决定如何处理正文。

这意味着 Content-Type 响应标头必须匹配 Accept 请求标头

解决方案:

  1. 将 API 网关中的二进制媒体类型设置为您的 mime 类型:image/jpg

  2. 在您的 HTTP 请求集 Accept: image/jpg

  3. 在您的 HTTP 响应集中 Content-Type: image/jpg

>  {
>   "isBase64Encoded": True,
>   "statusCode": 200,
>   "headers": { "content-type": "image/jpg"},
>   "body":  base64.b64encode(content_bytes).decode("utf-8")
> }
>
> ```

1. 接下来,我们必须告诉 CloudFront 接受请求中的“接受”标头。因此,在 CloudFront 分发中,单击您的 API 网关实例(ID 是可单击的),一旦重定向到 CloudFront 实例,请转到“ **行为**”选项卡,选择您的 API 的路径模式(例如:/api/\*),然后单击“ **编辑**”按钮。

> [![路径模式示例](https://i.stack.imgur.com/RQLzd.png)](https://i.stack.imgur.com/RQLzd.png)

在新屏幕上,您必须将 **接受** 标头添加到白名单。

> [![白名单接受](https://i.stack.imgur.com/2Dce8.png)](https://i.stack.imgur.com/2Dce8.png)

注意1:如果你有多种文件类型,你必须将它们都添加到API网关设置中的 **Binary Media Types**

注意 2:对于那些来自 **无服务器** 并希望在部署 lambda 时设置二进制类型的人,请查看这篇文章: [为 API 网关设置二进制媒体类型](https://medium.com/nextfaze/binary-responses-with-serverless-framework-and-api-gateway-5fde91376b76)

plugins: - serverless-apigw-binary

custom: apigwBinary: types: - ‘image/jpeg’


cloudfront 的 serverless.yml 文件应包含:

resources: WebAppCloudFrontDistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: … CacheBehaviors: … - #API calls … ForwardedValues: … Headers: - Authorization - Accept

”`

原文由 C. Damoc 发布,翻译遵循 CC BY-SA 4.0 许可协议

我终于想通了。从 python lambda 返回二进制数据是可行的。

按照此处的说明进行操作: https ://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/

创建新方法时,请务必 _选中_“使用 Lambda 代理集成”。

还要确保您的 Python Lambda 响应返回 base64 编码的正文,将 isBase64Encoded 设置为 True ,以及适当的内容类型:

 import base64

def lambda_handler(event, context):
    # ...

    body = base64.b64encode(bin_data)

    return {'isBase64Encoded'   : True,
            'statusCode'        : 200,
            'headers'           : { 'Content-Type': content_type },
            'body'              : body }

然后:

对于您的每个路线/方法问题:

 apigateway update-integration-response --rest-api-id <api-id> --resource-id <res-id> --http-method POST --status-code 200 --patch-operations "[{\"op\" : \"replace\", \"path\" : \"/contentHandling\", \"value\" : \"CONVERT_TO_BINARY\"}]"

在 AWS 控制台中。和 可以在 API 网关的“面包屑”示例中看到:

 <api-id> = zdb7jsoey8
<res-id> = zy2b5g

那么:您需要“部署 API”。据我所知,它仅在部署 API 后才有效。

确保在部署之前设置“二进制媒体类型”。

提示:不错的 AWS shell 终端在这里: https ://github.com/awslabs/aws-shell

 pip install aws-shell

原文由 driedler 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题