How is Sanic, an asynchronous Web framework, better than Django Flask?

If I’m going to do web development in Python, I’m sure you’ll tell me to use Flask or Django or Tornado. Github is a fastapi. But, Your Majesty, times have changed. Dead!!

Speed first

If you haven’t already used asyncio and Python3.5’s new async/await syntax, then you are probably a real person.

There are many asynchronous Web frameworks based on async/await syntax at github. Which one should I choose? There is a github project dedicated to testing the speed of various Web frameworks in various languages, so let’s take a look at some simple data:

Language Framework Speed (64) Speed (256) Speed (512)
58 Python (3.9) falcon (2.0) 74 256.04 81 538.76 82 897.69
88 Python (3.9) pyramid (2.0) 51 298.30 56 850.32 57 128.55
100 Python (3.9) asgineer (0.8) 44 745.54 51 318.30 52 105.43
104 Python (3.9) bottle (0.12) 39 690.41 42 590.65 44 329.21
107 Python (3.9) emmett (2.2) 35 983.95 41 270.86 42 295.95
115 Python (3.9) apidaora (0.28) 34 119.60 38 263.87 38 707.73
116 Python (3.9) hug (2.6) 34 040.91 35 909.39 53 828.77
125 Python (3.9) blacksheep (1.0) 28 887.22 33 204.44 34 356.25
129 Python (3.9) index.py (0.16) 27 273.81 29 282.48 30 258.63
131 Python (3.9) starlette (0.14) 26 693.66 31 709.52 31 302.99
134 Python (3.9) responder (2.0) 26 092.65 31 092.58 32 175.53
135 Python (3.9) clastic (19.9) 25 651.88 28 936.99 28 781.05
136 Python (3.9) sanic (21.3) 25 446.08 28 833.98 29 194.50
145 Python (3.9) molten (1.0) 18 055.01 21 858.74 21 906.60
146 Python (3.9) aiohttp (3.7) 17, 837.07 23 359.98 24 128.26
149 Python (3.9) fastapi (0.63) 16 701.72 22 402.72 22 042.29
164 Python (3.9) flask (1.1) 12 901.82 16 427.23 16 521.94
176 Python (3.9) cherrypy (18.6) 9 328.09 9 396.33 8 832.55
177 Python (3.9) guillotina (6.2) 9 152.33 8 843.65 8 742.31
181 Python (3.9) quart (0.14) 7 571.28 7 501.08 6 888.88
183 Python (3.9) tonberry (0.2) 7 363.12 6 948.61 6 344.40
191 Python (3.9) django (3.1) 5 918.73 6 572.13 6 150.29
193 Python (3.9) tornado (6.1) 5 722.03 5 728.67 5 624.07
210 Python (3.9) masonite (3.0) 2, 485.30 2, 477.63 2, 477.29
217 Python (3.9) cyclone (1.3) 1, 597.57 1, 591.42 1, 577.40
218 Python (3.9) klein (20.6) 1, 501.11 1, 538.24 1, 513.71
220 Python (3.9) nameko (2.13) 1, 213.25 1, 164.90 1, 142.60
222 Python (3.9) django-ninja (0.11) 1, 065.37 1, 478.17 1, 496.42

This is all the Python Web framework speed tests. One might ask why they are not sorted from 1, since the project also includes 226 Web frameworks for Golang, Java, PHP, and many other languages. We’ll just use Python for comparison here.

It’s clear that legacy Python Web frameworks like Flask, Django, and Tornado are near the bottom of the heap.

Wow, that’s amazing speed. Maybe you are still wondering how to test this speed, let me give you a look at the test source:

  
# Disable all logging features
import logging

logging.disable()


from flask import Flask
from meinheld import patch

patch.patch_all()

app = Flask(__name__)


@app.route("/")
def index() :
    return ""


@app.route("/user/<int:id>", methods=["GET"])
def user_info(id) :
    return str(id)


@app.route("/user", methods=["POST"])
def user() :
    return ""
Copy the code
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt


def index(request) :
    return HttpResponse(status=200)


def get_user(request, id) :
    return HttpResponse(id)


@csrf_exempt
def create_user(request) :
    return HttpResponse(status=200)
Copy the code
# Disable all logging features
import logging

logging.disable()


import tornado.httpserver
import tornado.ioloop
import tornado.web


class MainHandler(tornado.web.RequestHandler) :
    def get(self) :
        pass


class UserHandler(tornado.web.RequestHandler) :
    def post(self) :
        pass


class UserInfoHandler(tornado.web.RequestHandler) :
    def get(self, id) :
        self.write(id)


app = tornado.web.Application(
    handlers=[
        (r"/", MainHandler),
        (r"/user", UserHandler),
        (r"/user/(\d+)", UserInfoHandler),
    ]
)
Copy the code
# Disable all logging features
import logging

logging.disable()

import multiprocessing

from sanic import Sanic
from sanic.response import text


app = Sanic("benchmark")


@app.route("/")
async def index(request) :
    return text("")


@app.route("/user/<id:int>", methods=["GET"])
async def user_info(request, id) :
    return text(str(id))


@app.route("/user", methods=["POST"])
async def user(request) :
    return text("")


if __name__ == "__main__":
    workers = multiprocessing.cpu_count()
    app.run(host="0.0.0.0", port=3000, workers=workers, debug=False, access_log=False)
Copy the code

It simply returns a response without doing anything, and while this does not make any practical sense, it is impossible to do nothing in a normal production environment, but if all frameworks test this way, it is to some extent on the same starting line.

OK, that’s it, you should know who I want to talk about the asynchronous framework, yes, our hero today is Sanic.

Why an asynchronous Web framework?

This is probably the first question many friends think of, right? Why use an asynchronous Web framework when I use Django and Flask well enough to do normal tasks?

Having said that, let me start by asking you a question: Who do you think is our biggest enemy in Web development? Think about it for 5 seconds, and then read my answers:

Our biggest enemy in Web development is not users, it’s blocking!

Yes, and asynchrony can effectively solve network I/O blocking, file I/O blocking. Specific blocking related articles are recommended for viewing an in-depth understanding of Python asynchronous programming. Because asynchrony improves efficiency, asynchrony is one of the best ways to improve performance for Python. This is why asynchronous Web frameworks are chosen.

The ecological environment

Some people might say, why don’t you recommend Falcon instead of Sanic? Obviously it is very fast, much faster than Sanic, then you take a look at the following code:

from wsgiref.simple_server import make_server
import falcon


class ThingsResource:
    def on_get(self, req, resp) :
        """Handles GET requests"""
        resp.status = falcon.HTTP_200  # This is the default status
        resp.content_type = falcon.MEDIA_TEXT  # Default is JSON, so override
        resp.text = ('\nTwo things awe me most, the starry sky '
                     'above me and the moral law within me.\n'
                     '\n'
                     ' ~ Immanuel Kant\n\n')
                     
app = falcon.App()

things = ThingsResource()

app.add_route('/things', things)

if __name__ == '__main__':
    with make_server(' '.8000, app) as httpd:
        print('Serving on port 8000... ')

        httpd.serve_forever()
Copy the code

A status code to define and fill in their own framework, I think its speed is worthy of affirmation, but for developers, and how much practical value? So we’re not choosing the fastest framework, but the one that’s fast and easy to use.

Most frameworks don’t have such an ecosystem, which is why most Python Web developers prefer Django, Flask, and Tornado. Just because their ecology is so much richer than other frameworks.

Now, however, things are different. Sanic framework, from May 2016 began to release the first version of the asynchronous Web framework prototype, so far has gone through 5 years, these 5 years, after continuous technical accumulation, Sanic has been a stumbling small framework into a robust stable framework.

In the awesome-Sanic project, a large number of third-party libraries are documented, and you can find any common tools: From API to Authentication, from Development to Frontend, from Monitoring to ORM, from Caching to Queue… Only you can think of, there is no third party expansion it does not have.

The production environment

In the past, I have seen some friends in the Chinese community asking whether Sanic will be ready for production in 2020.

The answer is yes, as I can attest, we have been using Sanic in production environments since the end of nineteen nineteen. At that time, Sanic was 19.9. I experienced all the Sanic versions from Sanic 19.9 to 21.3, and saw the ecological environment of Sanic becoming better and better.

Another thing you may not know is that Sanic was created with the goal of creating a Web framework that could be used in production environments. Some frameworks may explicitly state that the built-in Run method is only used in the test environment and should not be used in the deployment environment. But what Sanic has created is not just an application for a test environment, but an application that can be used directly in a production environment. Eliminates the need to deploy unicorn!

documentation

The first framework that most Python Web developers will learn is Flask or Django, especially in the Django documentation. Because the old version has Chinese, but the new version, especially the new features, has no Chinese documentation at all !!!! This can be a pain in the neck for those of you who are interested in Django development but are not strong in English.

However, Sanic has a complete Chinese user guide and API documentation, which are officially recognized documents initiated by contributors, translated and contributed by translators, and published by the OFFICIAL Sanic team. Flask has a complete Chinese document, but that’s on a different site, and all of the documents are published by Sanic. Sanic also continues to support Korean, Portuguese and other languages.

The community guide

Unlike other frameworks, you may be able to find forums, channels, etc., on Baidu, but these are localized and Chinese, run by non-official operators, and loaded with advertisements. Obviously, if it was officially run it would not be allowed to happen.

Unlike other communities, Sanic’s forums and channels are run entirely by the government, where you can ask questions to the core developers, and the official release manager at Sanic is happy to answer them. You can also share your experience with like-minded users. This is a completely open environment….

Sanic currently uses forums, Discord, Github Issues, Twitter, and Stackoverflow

You can pay attention to the development of Sanic and seek help from the community in the above ways.

What are you waiting for? Why don’t you give it a try? Finally, we end with Sanic’s vision: Build Faster, Run Faster!