python lambdaでバイナリデータを返すことができません。サムネイル画像の node-template は正常に動作しますが、取得できません。 a python lambda to work。以下は、私のラムダからの関連する行です。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'
}
私が間違っていることへのポインタはありますか?
上記の手順をすべて実行しても、content-type = */*
はすべての応答をバイナリに変換します。
私の場合:
Json(テキスト)を返す複数のラムダ関数、バイナリファイルを返す単一のラムダ。すべてのlambdaプロキシが有効になっています。
ラムダはAPIゲートウェイにあります
API GatewayはCloudFrontの背後にあります
ヒント:API Gateway->設定に重要な情報があることに気づきました
引用:
API Gatewayは、Content-TypeおよびAcceptHTTPヘッダーを調べて、本文の処理方法を決定します。
これは、Content-Type応答ヘッダーがAccept要求ヘッダーと一致する必要があることを意味します
ソリューション:
APIゲートウェイのバイナリメディアタイプをMIMEタイプに設定します:image/jpg
HTTPリクエストセットAccept: image/jpg
HTTP応答セットContent-Type: image/jpg
{ "isBase64Encoded": True, "statusCode": 200, "headers": { "content-type": "image/jpg"}, "body": base64.b64encode(content_bytes).decode("utf-8") }
新しい画面で、ホワイトリストにAcceptヘッダーを追加する必要があります。
注1:複数のファイルタイプがある場合は、APIゲートウェイ設定のBinary Media Typesにすべて追加する必要があります
注2:serverlessから来て、ラムダをデプロイするときにバイナリタイプを設定したい場合は、この投稿を確認してください: APIゲートウェイのバイナリメディアタイプの設定 =
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
ようやくこれがわかりました。 pythonラムダからバイナリデータを返すことは可能です。
ここの指示に従ってください: https://aws.Amazon.com/blogs/compute/binary-support-for-api-integrations-with-Amazon-api-gateway/
新しいメソッドを作成する場合は、必ず「Use Lambda Proxy Integration」をcheckしてください。
また、python lambda応答が次のようになることを確認してください。
return {'isBase64Encoded' : True,
'statusCode' : 200,
'headers' : { 'Content-Type': content_type },
'body' : base64_encoded_binary_data}
その後:
ルート/メソッドの問題ごとに:
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
私が知る限り、これはPython 3.の場合も同様です。バイナリデータ(バイト)を返そうとしていますが、まったく機能しません。
また、base-64エンコーディングを使用しようとしましたが、成功しませんでした。
これは、APIゲートウェイおよびプロキシ統合との併用です。
[更新]
私はようやくこれを行う方法を実現しました。 I 有効なバイナリサポート タイプ*/*
そして、これを返しました:
return({
"isBase64Encoded": True,
"statusCode": 200,
"headers": {
"content-type": "image/jpg",
},
'body': base64.b64encode(open('image.jpg', 'rb').read()).decode('utf-8')
})
私は約6か月前に同じ問題に直面しました。 API Gatewayでバイナリサポート(およびJSの例)が現在ありますが、Python 2.7 Lambdaは有効なバイナリレスポンスをまだサポートしていません。Python = 3.6。
JSONラッピングのため、Base64エンコードされた応答に問題があります。クライアント側でカスタムJSONを記述して、このJSONからbase-64イメージを手動で取り出しましたが、これも不十分なソリューションでした。
結果を(CloudFrontの背後にある)S3にアップロードし、301をCloudFrontに返すことは、適切な回避策のようです。私に最適です。