0

I have spent an lot of time, but still with no luck.

My objective is to send an image to the AWS Lambda function and do some image processing there and return the modified image back.I am using API Gateway. So, the problem operation for me are:

  1. Sending the image data to Lambda server.
  2. Returning the image from Lambda.

I am using POST API. And since now we can work with binary data in API Gateway, I followed the API Gateway setting part from this official blog.

My Lambda function is like this :

def lambda_handler(event, context):
    # TODO implement
    image = event['base64Image']
    return {
        "isBase64Encoded": True,
        "statusCode": 200,
        "headers":{
                "content/type": "image/png",
        },
        "body": "any string"
    }

And my call to the API python code is this :

headers = {
    'Accept': 'image/png',
    'Content-Type': 'image/png',
}

data = open('random.jpg', 'rb').read()
response = requests.post(' https://xxxxxxx.execute-api.us-east-1.amazonaws.com/prod', headers=headers, data=data)
print(response.content)

According to the blog, in the Integration Request I added the Mapping template image/png and also the template

{
    "base64Image" : "$input.body"
}

And in the API > Settings in Binary Media Type I added image/png.

What is happening now is, I am able to receive the image base64 data properly in my event[base64Image] object.

But the response result that I am getting is not coming. As you can see I am just returning a simple string but I get '{"message": "Internal server error"}' error. In place of "any string" in the result body I tried sending base64 data also directly but get the same error.

So, the problem boils down to how to receive result in POST Request when we send image data as payload.

I also followed this answer and accordingly in my Integration Response I selected Convert to Binary (if needed) option. But that also didn't help.

If I am not wrong then the problem is something related to application/json and image/png but I tried all permutation combination everywhere but nothing seems to work.

I am attaching the screenshots of the API Gateway setup :

INTEGRATION REQUEST enter image description here

INTEGRATION RESPONSE

enter image description here

SETTINGS

enter image description here

The Lambda function in its own console is giving the output properly, so my problem right now boils down to receive any result from the lambda function using the POST API in this setup.

Edit : When I use a GET request to just send an image-> base64 output I am able to do without the changes mentioned in the blog. The Lambda function then is :

def lambda_handler(event, context):
    # TODO implement
    return {
        "isBase64Encoded": True,
        "statusCode": 200,
        "headers":{
                "content/type": "image/png",
        },
        "body": base64.b64encode(open('random.jpg','rb').read()).decode('utf-8')
    }

Here random.jpg is an image which is there in the Lambda zip folder only.

Correction : Its content-type and not content/type. (Error still there).

11
  • so, few things. 1. you have content/type as a header rather than content-type. 2. In the body of the POST lambda, you will need to send back the stringified json you want to respond (ie your image base64). Also, im confused why you are using mapping templates and responding with this payload. you are responding like you check that "lambda proxy request' in api gateway. you need to have a response template with a request template if you dont check that box. Commented Dec 10, 2018 at 13:46
  • having a response template in api-gateway that is application/json will trump the image/png from your lambda if you do not check the "use lambda as integration proxy" box. Commented Dec 10, 2018 at 13:54
  • @LostJon Thanks for having a look through this. So, for point 2, what you said, for the key body, I am passing a string object only. So, is it wrong there? Also, I haven't checked Lambda Proxy. Commented Dec 10, 2018 at 13:59
  • @LostJon I do have a request template as shown in the question (base64Image) but I don't have a response template. For this response output of mine, do I need to add a response template? Commented Dec 10, 2018 at 14:06
  • Hey @arqam, the way I always delineate between using lambda as integration proxy, is if you want lambda to handle all the mappings (meaning handing input payload/headers/etc and response payload/headers/etc) then check that box in api gateway; else, make a mapping template for request and response. Sounds like you are using a bit of a hybrid of both. Commented Dec 10, 2018 at 14:21

1 Answer 1

1

Set Accept Header content type to application/json, since data to be received is a string.

In the documentation it is clearly written :

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.