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

arqam
  • 3,582
  • 5
  • 34
  • 69
  • 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. – LostJon Dec 10 '18 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. – LostJon Dec 10 '18 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. – arqam Dec 10 '18 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? – arqam Dec 10 '18 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. – LostJon Dec 10 '18 at 14:21
  • @LostJon So, in POST if I am not using Lambda Proxy checkbox, then I just need integration response mapping?, or am I wrong in other places also? – arqam Dec 10 '18 at 14:25
  • Why don't you send your image as base64 encoded. This way the content type will remain application/json. – Abhishek Raj Dec 10 '18 at 14:26
  • give the response mapping template a try. i mentioned `content-type` being malformed, but other than that, you seem ok. – LostJon Dec 10 '18 at 14:26
  • @AbhishekRaj The Image I am sending to the Lambda function is base64 encoded, there I am nothaving any problem. But I am not able to receive any result where I am for testing just sending a simple string. – arqam Dec 10 '18 at 14:30
  • Send body as json object and not a string – Abhishek Raj Dec 10 '18 at 14:36
  • @AbhishekRaj Tried with `json.dumps(stringVal)` but same error comes. – arqam Dec 10 '18 at 14:39

1 Answers1

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

arqam
  • 3,582
  • 5
  • 34
  • 69
Abhishek Raj
  • 502
  • 3
  • 15