Reputation: 713
I am trying to call a REST API async using asyncio but i keep getting the error "coroutine was never awaited
" which i understand. But i want this behavior, i want my function to end just by posting and not waiting for the result. Here is my code
async def callCoroutine:
#call a REST API
def lambda_handler(event, context):
loop = asyncio.get_event_loop()
task = loop.create_task(callCoroutine(data))
return
Can someone help?
Upvotes: 2
Views: 1288
Reputation: 818
In your case, the main thread is running synchronously. So you need to run the asyncio loop in another thread Using asyncio.run_coroutine_threadsafe.
import asyncio
import threading
# Run asyncio loop in other thread
loop = asyncio.new_event_loop()
threading.Thread(target=loop.run_forever).start()
async def call_coroutine(data):
# call a REST API
return
def lambda_handler(event, context):
# Run the coroutine on the loop of other thread
future = asyncio.run_coroutine_threadsafe(call_coroutine(data), loop)
# If need to get result:
result = future.result() # This will block the main thread
do_something_else()
return
# If need to stop the asyncio loop
loop.call_soon_threadsafe(loop.stop)
Upvotes: 1
Reputation: 6355
For the current example, you need to have running loop somewhere (e.g. if you have some web-server or worker - loop.run_forever()
)
import asyncio
async def callCoroutine(data):
print('This is data: %s' % data)
def lambda_handler(event, context):
loop = asyncio.get_event_loop()
task = loop.create_task(callCoroutine(context))
return
lambda_handler(None, {'a': 1})
loop = asyncio.get_event_loop()
loop.run_forever()
run_in_executor()
import asyncio
import requests
def call_rest_api(data):
print('Triggered REST API in background')
response = requests.get(data['url'])
print('Response: %s' % response)
async def main(loop):
print('Some operations here...')
data = {'url': 'http://example.com#some_rest_api'}
loop.run_in_executor(None, call_rest_api, data)
print('Continue work of main thread...')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
await
(if you need to call API syncronously)But it is not necessary to use asyncio if you want to write synchronous code.
import asyncio
import requests
def call_rest_api(data):
print('Triggered REST API in background')
response = requests.get(data['url'])
print('Response: %s' % response)
async def main(loop):
print('Some operations here...')
data = {'url': 'http://example.com#some_rest_api'}
await call_rest_api(data)
print('Continue work of main thread...')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
Can you provide more verbose example of what you have and what you want to achive?
Upvotes: 1
Reputation: 360
If you just need to call the API, disregarding the result, you can use an Executor in another thread, which will not block the main thread.
To run in an Executor, use AbstractEventLoop.run_in_executor() with an Executor from concurrent.futures.
Upvotes: 1