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

Hor*_*orv 11 python binary lambda image amazon-web-services

我无法让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'
    }
Run Code Online (Sandbox Code Playgroud)

什么指向我做错了什么?

use*_*323 11

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

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

创建新方法时,请务必检查 "使用Lambda代理集成".

还要确保你的python lambda响应如下:

return {'isBase64Encoded'   : True,
        'statusCode'        : 200,
        'headers'           : { 'Content-Type': content_type },
        'body'              : base64_encoded_binary_data}
Run Code Online (Sandbox Code Playgroud)

然后:

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

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\"}]"
Run Code Online (Sandbox Code Playgroud)

在AWS控制台中.这可以在API Gateway的"breadcrumbs"中找到:

<api-id> = zdb7jsoey8
<res-id> = zy2b5g
Run Code Online (Sandbox Code Playgroud)

那么:你需要'部署API'.从我发现的只是它只在部署API后才起作用.

确保在部署之前设置"二进制媒体类型".

提示:这里有一个很好的AWS shell终端:https://github.com/awslabs/aws-shell

pip install aws-shell
Run Code Online (Sandbox Code Playgroud)

  • `import base64``base64_encoded_binary_data = base64.b64encode(bin_data)` (3认同)
  • 谢谢@ user1495323!这很清楚.我认为我缺少的是"二进制媒体类型"实际上与客户端传入的`Accept`标题匹配,*不是*你传出的`Content-Type`标题,所以我需要在我的内容中添加`*/*`二进制媒体类型列表. (2认同)

C. *_*moc 8

执行上述所有步骤对我的情况不起作用,因为具有对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")
}
Run Code Online (Sandbox Code Playgroud)
  1. 接下来,我们必须告诉CloudFront接受请求中的“ Accept”标头。因此,在CloudFront分配中,单击您的API网关实例(可单击ID),然后将其重定向到CloudFront实例后,转到“ 行为”选项卡,选择API的路径模式(例如:/ api / *),然后单击“ 编辑”按钮。

路径模式示例

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

白名单接受

注意1:如果您有多种文件类型,则必须将它们全部添加到API网关设置的“ 二进制媒体类型”

注意2:对于那些来自无服务器的用户,想要在部署Lambda时设置二进制类型,请查看以下文章:为API网关设置二进制媒体类型

plugins:
  - serverless-apigw-binary

custom:
  apigwBinary:
    types:
- 'image/jpeg'
Run Code Online (Sandbox Code Playgroud)

Cloudfront的serverless.yml文件应包含:

resources:
    WebAppCloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          ...
          CacheBehaviors:
            ...
            - 
              #API calls
              ...
              ForwardedValues:
                ...
                Headers:
                  - Authorization
                  - Accept
Run Code Online (Sandbox Code Playgroud)


小智 5

据我所知,Python 3也是这种情况。我正在尝试返回一个二进制数据(字节)。它根本不起作用。

我也尝试使用base-64编码,但没有成功。

这是与API网关和代理集成在一起的。

[更新]

我终于意识到了该怎么做。我为类型启用了二进制支持*/*,然后返回了以下内容:

return({
        "isBase64Encoded": True,
        "statusCode": 200,
        "headers": {
                "content-type": "image/jpg",
        },  
        'body':  base64.b64encode(open('image.jpg', 'rb').read()).decode('utf-8')
})  
Run Code Online (Sandbox Code Playgroud)