AWS Chalice,无法从 POST 请求中获取图像

AWS Chalice, can't get image from POST request

我正在尝试使用 aws chalice、lambda 函数和 API Gateaway 调用我的 sagemaker 模型。

我正在尝试通过 POST 请求发送图像,但我在使用 lambda 函数接收图像时遇到问题。

我的代码如下:

from chalice import Chalice
from chalice import BadRequestError
import base64
import os
import boto3
import ast
import json

app = Chalice(app_name='foo')
app.debug = True


@app.route('/', methods=['POST'], content_types=['application/json'])
def index():
    body = ''

    try:
        body = app.current_request.json_body # <- I suspect this is the problem
        return {'response': body}
    except Exception as e:
        return  {'error':  str(e)}

刚回来

<Response [200]> {'error': 'BadRequestError: Error Parsing JSON'}

正如我之前提到的,我的最终目标是接收我的图像并用它提出 sagemaker 请求。但我似乎无法阅读图像。

我的 python 测试客户端如下所示:

import base64, requests, json

def test():

    url = 'api_url_from_chalice'
    body = ''

    with open('b1.jpg', 'rb') as image:
        f = image.read()
        body = base64.b64encode(f)

    payload = {'data': body}
    headers = {'Content-Type': 'application/json'}

    r = requests.post(url, data=payload, headers=headers)
    print(r)
    r = r.json()
    # r = r['response']

    print(r)

test()

请帮助我,我花了很多时间试图解决这个问题

该错误消息是因为您没有将 JSON body 发送到您的 Chalice 应用程序。检查这一点的一种方法是使用 .raw_body 属性 来确认:

@app.route('/', methods=['POST'], content_types=['application/json'])
def index():
    body = ''

    try:
        #body = app.current_request.json_body # <- I suspect this is the problem
        return {'response': app.current_request.raw_body.decode()}
    except Exception as e:
        return  {'error':  str(e)}

您会看到 body 是 form-encoded 而不是 JSON。

$ python client.py
<Response [200]>
{'response': 'data=c2FkZmFzZGZhc2RmYQo%3D'}

要解决此问题,您可以在 requests.post() 调用中使用 json 参数:

    r = requests.post(url, json=payload, headers=headers)

然后我们可以确认我们在您的圣杯应用程序中获得 JSON body:

$ python client.py
<Response [200]>
{'response': '{"data": "c2FkZmFzZGZhc2RmYQo="}'}

所以我能够在 aws 工程师的帮助下解决这个问题(我想我很幸运)。我包括了完整的 lambda 函数。客户端没有任何变化。

from chalice import Chalice
from chalice import BadRequestError
import base64
import os
import boto3
import ast
import json
import sys


from chalice import Chalice
if sys.version_info[0] == 3:
    # Python 3 imports.
    from urllib.parse import urlparse, parse_qs
else:
    # Python 2 imports.
    from urlparse import urlparse, parse_qs

app = Chalice(app_name='app_name')
app.debug = True


@app.route('/', methods=['POST'])
def index():
    parsed = parse_qs(app.current_request.raw_body.decode())

    body = parsed['data'][0]
    print(type(body))

    try:
        body = base64.b64decode(body)
        body = bytearray(body)
    except e:
        return {'error': str(e)}


    endpoint = "object-detection-endpoint_name"
    runtime = boto3.Session().client(service_name='sagemaker-runtime', region_name='us-east-2')

    response = runtime.invoke_endpoint(EndpointName=endpoint, ContentType='image/jpeg', Body=body)

    print(response)
    results = response['Body'].read().decode("utf-8")
    results = results['predictions']

    results = json.loads(results)
    results = results['predictions']

    return {'result': results}