+1 I used Tornado in the past because it had an async event loop before it was native to Python. So much simpler than having to set up wsgi servers etc with the added benefit of easily-configured background tasks (like having cron jobs built in to your application). This is really good when you're building an application that you want other people to be able to install and run easily.
It seems that Tornado is now offering the choice of its own event loop or the asyncio event loop. I built something recently in aiohttp because it felt like it had been built on asyncio from the ground up but will explore Tornado again.
I used aiohttp for a small project recently and found that it to be very good.
Combined with aiohttp-json-rpc I had a very effective websocket-based JSON RPC backend service up and running in a very short time and with very little boilerplate. I'll be using this pattern again for sure.
What would have been the advantage of me using Sanic instead (I haven't RTFM for sanic yet but I'm about to...)?
It seems that Tornado is now offering the choice of its own event loop or the asyncio event loop. I built something recently in aiohttp because it felt like it had been built on asyncio from the ground up but will explore Tornado again.