54

I have a simple lambda function that returns a dict response and another lambda function invokes that function and prints the response.

lambda function A

def handler(event,context):
    params = event['list']
    return {"params" : params + ["abc"]}

lambda function B invoking A

a=[1,2,3]
x = {"list" : a}
invoke_response = lambda_client.invoke(FunctionName="monitor-workspaces-status",
                                       InvocationType='Event',
                                       Payload=json.dumps(x))
print (invoke_response)

invoke_response

{u'Payload': <botocore.response.StreamingBody object at 0x7f47c58a1e90>, 'ResponseMetadata': {'HTTPStatusCode': 202, 'RequestId': '9a6a6820-0841-11e6-ba22-ad11a929daea'}, u'StatusCode': 202}

Why is the response status 202? Also, how can I get the response data from invoke_response? I could not find a clear documentation of how to do it.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
user3089927
  • 3,575
  • 8
  • 25
  • 33

2 Answers2

97

A 202 response means Accepted. It is a successful response but is telling you that the action you have requested has been initiated but has not yet completed. The reason you are getting a 202 is because you invoked the Lambda function asynchronously. Your InvocationType parameter is set to Event. If you want to make a synchronous call, change this to RequestResponse.

Once you do that, you can get the returned data like this:

data = invoke_response['Payload'].read()
garnaat
  • 44,310
  • 7
  • 123
  • 103
  • 3
    made my day! Thanks a lot. Haven't found this anywhere in docs – Alexey Lysenko Dec 26 '16 at 22:47
  • 26
    `.read()` returns type `bytes` so if you were expecting a string, JSON, etc., you have to `.decode()` them. e.g. `response['Payload'].read().decode()` – Bruno Bronosky Feb 10 '17 at 00:31
  • 9
    And since `json.dumps(obj)` returns a quoted string, (**if you used that** for the `return` value of your `lambda_handler`) you are going to get a string if you do `json.loads(response['Payload'].read().decode())' and would have to wrap another `json.loads()` around that. So, don't explicitly convert to JSON in your lambda function. – Bruno Bronosky Feb 10 '17 at 00:31
  • 2
    Is there a way to get a callback after completion for invocation type Event? – 2ank3th Jun 14 '17 at 14:55
  • @2ank3th I had the same issue, and I looked up in the AWS documentation. It says, for `Event` type invocations, there is no response body: [open aws documentation](https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/API_Invoke.html#API_Invoke_ResponseSyntax) – jackxujh Sep 12 '18 at 11:47
  • A bit shorter construct would be: `json.loads(json.load(response['Payload']))`. – Denis The Menace Jul 19 '19 at 15:23
  • This works to me: responseFromChild = json.load(invoke_response['Payload']) print("responseFromChild", responseFromChild) – Gleidson Henrique Aug 02 '22 at 19:23
2

try: data = invoke_response['Payload'].read() read() because it is a StreamingBody object

<botocore.response.StreamingBody object at 0x110b91c50>

It is in the boto3 docs. You can find more details about this here: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html#actions