Search code examples
pythontornado

Asynchronous Function Call


I would like to learn how to call a function asynchronously in Python3. I think Tornado can do this. Currently, my code is returning nothing on the command line:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

async def count(end):
    """Print message when start equals end."""
    start = 0
    while True:
        if start == end:
            print('start = {0}, end = {1}'.format(start, end))
            break
        start = start + 1

def main():

    # Start counting.
    yield count(1000000000)

    # This should print while count is running.
    print('Count is running. Async!')

if __name__ == '__main__':
    main()

Thanks


Solution

  • To call an async function, you need to provide an event loop to handle it. If you have a Tornado app, it provides such a loop, which allows you to make your handlers asynchronous:

    from tornado.web import RequestHandler, url
    from tornado.httpserver import HTTPServer
    from tornado.ioloop import IOLoop
    
    
    async def do_something_asynchronous():
        # e.g. call another service, read from database etc
        return {'something': 'something'}
    
    
    class YourAsyncHandler(RequestHandler):
    
        async def get(self):
            payload = await do_something_asynchronous()
            self.write(payload)
    
    
    application = web.Application([
        url(r'/your_url', YourAsyncHandler, name='your_url')
    ])
    
    http_server = HTTPServer(application)
    http_server.listen(8000, address='0.0.0.0')
    IOLoop.instance().start()
    

    Outside of a Tornado app you can get the event loop from any number of providers, including the built-in asyncio library:

    import asyncio
    event_loop = asyncio.get_event_loop()
    try:
        event_loop.run_until_complete(do_something_asynchronous())
    finally:
        event_loop.close()