Few days ago while I was reading fullstackpython.com I came across new pythonic micro web framework based on asyncio – Sanic.
Coolest thing about Sanic is that it leverages asyncio providing better performance and more efficient hardware utilization. Although it’s not feature complete yet, there are people claimimg to be using it in production and handling few thousands requests per second without any problems.
Due to asyncio’s features, with Sanic we may easily implement websockets handling without need of setting up separate application just for that.
from sanic import Sanic from sanic.response import file app = Sanic(__name__) @app.route('/') async def index(request): return await file('websocket.html') @app.websocket('/feed') async def feed(request, ws): while True: data = 'hello!' print('Sending: ' + data) await ws.send(data) data = await ws.recv() print('Received: ' + data) if __name__ == '__main__': app.run()
Another quality is a dependence on uvloop – drop-in replacement for asyncio’s default event loop. In fact, it is a wrapper around libuv – the same event loop that powers node.js. According to uvloop’s README.md, it makes asyncio 2-4 times faster.
Last, but not least – Sanic’s API is inspired by Flask. Therefore, one may found many similarities and start coding in no time.
Before you get too excited, let’s answer the most important question regarding new shiny toys. Under what circumstances Sanic is a better choice than Django, Flask or other Python web framework without asyncio under the hood?
Well, if you need to request data from some external service using REST, by example, then your preforked web application (Django, Flask etc) is not able to process more requests than the number of workers it has. In a pessimistic scenario, when all requests to the external service timeout after 30 seconds and you have 8 workers in total, then 8 simultaneous requests to your application will paralyze it. With Sanic, you would still be able to serve clients, unless they are asking for the same blocked resource.