Using boto to invoke lambda functions how do I do so asynchronously?
<p>SO I'm using boto to invoke my lambda functions and test my backend. I want to invoke them asynchronously. I have noted that "invoke_async" is deprecated  and should not be used. Instead you should use "invoke" with an InvocationType of "Event" to do the function asynchronously.  </p>

<p>I can't seem to figure out how to get the responses from the functions when they return though. I have tried the following: </p>

<pre><code>payload3=b"""{
"latitude": 39.5732160891,
"longitude": -119.672918997,
"radius": 100
}"""

client = boto3.client('lambda')
for x in range (0, 5):
    response = client.invoke(
        FunctionName="loadSpotsAroundPoint",
        InvocationType='Event',
        Payload=payload3
    )
    time.sleep(15)
    print(json.loads(response['Payload'].read()))
    print("\n")
</code></pre>

<p>Even though I tell the code to sleep for 15 seconds, the response variable is still empty when I try and print it. If I change the invokation InvokationType to "RequestResponse" it all works fine and response variable prints, but this is synchronous. Am I missing something easy? How do i execute some code, for example print out the result, when the async invokation returns??</p>

<p>Thanks.</p>

<p>There is a difference between an <em>'async AWS lambda invocation'</em> and <em>'async python code'</em>. When you set the <code>InvocationType</code> to <code>'Event'</code>, <a href="http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax" rel="nofollow">by definition</a>, it does not ever send back a response.</p>

<p>In your example, <code>invoke()</code> immediately returns <code>None</code>, and does not implicitly start up anything in the background to change that value at a later time (thank goodness!). So, when you look at the value of <code>response</code> 15 seconds later, it's still <code>None</code>.</p>

<p>It seems what you really want is the <code>RequestResponse</code> invocation type, with asynchronous Python code. You have a bunch of options to choose from, but my favorite is <a href="https://docs.python.org/3/library/concurrent.futures.html" rel="nofollow"><code>concurrent.futures</code></a>. Another is <a href="https://docs.python.org/3/library/threading.html" rel="nofollow"><code>threading</code></a>.</p>

<p>Here's an example using <code>concurrent.futures</code>:</p>

<p>(If you're using Python2 you'll need to <code>pip install futures</code>)</p>

<pre><code>from concurrent.futures import ThreadPoolExecutor
import json

payload = {...}

with ThreadPoolExecutor(max_workers=5) as executor:
    futs = []
    for x in xrange(0, 5):
        futs.append(
            executor.submit(client.invoke,
                FunctionName   = "loadSpotsAroundPoint",
                InvocationType = "RequestResponse",
                Payload        = bytes(json.dumps(payload))
            )
        )
    results = [ fut.result() for fut in futs ]

print results
</code></pre>

<p>Another pattern you might want to look into is to use the <code>Event</code> invocation type, and have your Lambda function push messages to SNS, which are then consumed by another Lambda function. You can check out a tutorial for SNS-triggered lambda functions <a href="http://docs.aws.amazon.com/lambda/latest/dg/with-sns-example.html" rel="nofollow">here</a>.</p>

python amazon-web-services boto aws-lambda