Is Sanic python web framework the new Flask?

Intro

The Facts

The Pros

Perfromance comparision between Flask and Sanic
  1. Fast learning curve since Sanic looks a lot like Flask, if you come from Flask background, it should be quite easy to work with Sanic, it even uses the same naming convention as Flask (e.g Blueprints)
  2. Sanic can handle requests Asynchronously. Flask Can’t yet.
  3. Although Sanic is fairly new, there is a lot of packages (middleware or extenstions) created to support Sanic.
  4. This is a little tip from me, for every language/framework there is a github repo as a collection of all of the awesome packages related to that language/framework. Awesome-python, awesome-django, awesome-flask .. etc. Luckily there is Awesome-Sanic and it contains all of the great extensions/middleware for sanic.
  5. Extenstions include (ORM/SQLAlchemy, Auth, Caching-Redis, Queues .. etc)
  6. It is quite easy to create a middlewares/extension for Sanic

The Cons

  1. I am not a big fan of the readthedocs type of documentation, it is 2020 already!, take a look at Django-documentation or FastAPI-documentation
  2. Like any new framework, I dont know how does it perform in production, Flask is battle tested.

Lets create a simple app using Sanic

Installing sanic

main.py

from sanic import Sanic
from sanic.response import json

app = Sanic(__name__)
@app.route("/")
async def test(request):
return json({"message": "Hello_world"})

if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)

Run it

Now lets add more endpoints


from sanic import Sanic
from sanic import response
from sanic.response import json

app = Sanic(__name__)


@app.route("/", methods=["GET"])
async def index(request):
return json({"message": "Hello_world"})


@app.route("/post", methods=["POST"])
async def post(request):
return json({"message": request.json})


@app.route("/empty", methods=["PUT"])
async def empty_response(request):
return response.empty()


if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)

Lets see how easy to create a middleware

from json import loads, dumps
from humps import camelize, decamelize


class Camelize:
def __init__(self, app):
@app.middleware("request")
async def request_to_snake_case(request):

if request.body:
request.body = bytes(dumps(decamelize(loads(request.body))), "utf-8")

@app.middleware("response")
async def response_to_camel(request, response):

if response.body:
response.body = bytes(dumps(camelize(loads(response.body))), "utf-8")
# -*- coding: utf-8 -*-
"""Sample main.py used for running tests for middleware

"""
from sanic import Sanic
from sanic import response
from sanic.response import json
from sanic_camelcase_middleware import Camelize

app = Sanic(__name__)

Camelize(app)


@app.route("/", methods=["GET"])
async def index(request):
return json({"is_camelcase": True, "message": "Hello_world"})


@app.route("/post", methods=["POST"])
async def post(request):
return json({"is_camelcase": True, "message": request.json})


@app.route("/empty", methods=["PUT"])
async def empty_response(request):
return response.empty()


if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
{"isCamelcase": true, "message": "Hello_world"}

Writing tests

import json
from humps import camelize
from main import app

def test_get_request():
"""test_get_request function tests get requests for middleware
The purpose of this test is to check if the middleware would work if the request
has no payload in case of "GET" requests.
However the respons should be camilized.
"""
request, response = app.test_client.get("/")
assert response.status == 200
assert response.json == {"isCamelcase": True, "message": "Hello_world"}

Running tests

Conclusion

--

--

--

Software Developer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to build a Trading bot with Python and SQlite.

BTC price plot

Throwback — Part 7 — THROWBACK-DC01, CORP-DC01, CORP-ADT01

Easy Speedup Wins With Numba

Leetcode 937. Reorder Data in Log Files

Container and System Monitoring with Docker, Telegraf, Influxdb, and Grafana on AWS

A Buffet of Specialized Data Types — Real Python

A Buffet of Specialized Data Types – Real Python

Django + Postgres: The Hunt for Long Running Queries

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ahmed Nafies

Ahmed Nafies

Software Developer

More from Medium

Customize keyboard shortcut keys using python

Python: A Quick Revision

Building GUI with Tkinter

16 the Best Python IDEs and Code Editors in 2022