Search code examples
pythonamazon-web-servicesrestamazon-sagemakerchalice

AWS Chalice, can't get image from POST request


I'm trying to invoke my sagemaker model using aws chalice, a lambda function, and an API Gateaway.

I'm attempting to send the image over POST request but I'm having problem receiving it on the lambda function.

My code looks like:

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)}

It's just returning

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

As I mentioned before, my end goal is to receive my image and make a sagemaker request with it. But I just can't seem to read the image.

My python test client looks like this:

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()

Please help me, I spent way to much time trying to figure this out


Solution

  • So I was able to figure it out with the help of an aws engineer (i got lucky I suppose). I'm including the complete lambda function. Nothing changed on the client.

    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}