• 一文带你快速了解Python史上最快Web框架


    【作者主页】:吴秋霖
    【作者介绍】:Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作!
    【作者推荐】:对JS逆向感兴趣的朋友可以关注《爬虫JS逆向实战》,对分布式爬虫平台感兴趣的朋友可以关注《分布式爬虫平台搭建与开发实战》
    还有未来会持续更新的验证码突防、APP逆向、Python领域等一系列文章

    1. 写在前面

      在Python的Web开发领域内这些年框架也是层出不穷,早已不再局限于Django、Flask、Tornado甚至是后面的FastApi

    曾经的玄冥二老也慢慢退居幕后,新的时代都是年轻人天下!这个时代的年轻王者无疑是Sanic

    在网上有对Python所有的Web框架做过测试,可以看到曾经的老牌框架已经垫底:
    在这里插入图片描述

    官方地址:Sanic

    从Python3+后,各种异步很火,所以说相对于传统的同步框架在某些特定的场景下更加适应,因为同步与异步在并发、实时性上还是有很大差异的

    2. Sanic框架简介

    2.1 背景

      Sanic最早由ChannelCat团队开发,旨在提供一个高性能的异步Web框架。其灵感来自于Flask,并在异步编程的基础上进行了优化。Sanic利用Python3.5引入的async/await语法,使得开发者可以编写快速且高效的异步Web应用程序

    2.2 特征与优势

      江湖中的朋友们一直都称之为Python史上最强且最快的Web框架,并且流行度越来越广泛

    • 高性能:利用异步编程的优势,允许处理大量并发请求而不会阻塞线程,从而实现高性能和低延迟
    • 轻量级:核心设计非常简洁,不依赖大量的外部库,使得其体积小巧,易于部署和维护
    • 路由功能:提供了简单易用的路由功能,让开发者能够轻松地定义URL和处理请求的处理程序
    • 中间件支持:支持中间件,开发者可以在请求和响应处理过程中添加额外的逻辑
    • WebSocket支持:对WebSocket 提供了良好的支持,允许构建实时的双向通信应用程序

    3. Sanic框架实战

    3.1. 安装Sanic

      首先我们使用pip命令安装Sonic:

    pip3 install sanic
    
    • 1

    在这里插入图片描述

    3.2. Demo案例编写

    如下是一个简单的Sanic应用程序,实现了基本的路由与请求:

    # -*- coding: utf-8 -*-
    from sanic import Sanic
    from sanic import response
    
    app = Sanic("sanic_demo")
    
    @app.route("/")
    def run(request):
        return response.text("Hello World !")
    
    if __name__ == '__main__':
        app.run(host="0.0.0.0", port=8001, debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在终端中运行上面应用程序:

    在这里插入图片描述

    程序运行后我们在浏览器地址中访问http://127.0.0.1:8001就可以看到返回的信息了

    接下来我们编写一个稍微复杂的案例代码,这是一个简化的在线商店系统,包括用户注册、商品管理、购物车等功能。实际真实的商城会更加复杂

    # -*- coding: utf-8 -*-
    from sanic import Sanic, response
    from sanic.exceptions import NotFound, ServerError
    from sanic_jwt import Initialize, protected
    from sanic_session import Session, InMemorySessionInterface
    
    app = Sanic("OnlineStore")
    app.config.SECRET_KEY = "supersecretkey"
    
    Initialize(app, authenticate=None)
    
    Session(app, interface=InMemorySessionInterface())
    
    users_db = {}
    products_db = {}
    carts_db = {}
    
    # Routes
    @app.route("/")
    async def home(request):
        return response.text("欢迎来到爬虫商店!")
    
    @app.route("/register", methods=["POST"])
    async def register(request):
        data = request.json
        username = data.get("username")
        password = data.get("password")
    
        if username in users_db:
            return response.json({"message": "Username already exists"}, status=400)
    
        users_db[username] = password
        return response.json({"message": "Registration successful"})
    
    @app.route("/login", methods=["POST"])
    async def login(request):
        data = request.json
        username = data.get("username")
        password = data.get("password")
    
        if username not in users_db or users_db[username] != password:
            return response.json({"message": "Invalid credentials"}, status=401)
    
        token = app.auth.jwt_encode(request, {"username": username})
        return response.json({"token": token})
    
    @app.route("/products", methods=["GET"])
    @protected()
    async def get_products(request):
        return response.json({"products": products_db})
    
    @app.route("/add_to_cart", methods=["POST"])
    @protected()
    async def add_to_cart(request):
        data = request.json
        username = request.ctx.get("user").get("username")
        product_id = data.get("product_id")
        quantity = data.get("quantity", 1)
    
        if product_id not in products_db:
            return response.json({"message": "Product not found"}, status=404)
    
        if username not in carts_db:
            carts_db[username] = {}
    
        if product_id not in carts_db[username]:
            carts_db[username][product_id] = quantity
        else:
            carts_db[username][product_id] += quantity
    
        return response.json({"message": "Product added to cart"})
    
    @app.route("/view_cart", methods=["GET"])
    @protected()
    async def view_cart(request):
        username = request.ctx.get("user").get("username")
    
        if username not in carts_db:
            return response.json({"cart": {}}, status=200)
    
        return response.json({"cart": carts_db[username]})
    
    # Error Handlers
    @app.exception(NotFound)
    async def not_found(request, exception):
        return response.json({"message": "Not Found"}, status=404)
    
    @app.exception(ServerError)
    async def server_error(request, exception):
        return response.json({"message": "Internal Server Error"}, status=500)
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=8000, debug=True)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    在上面的代码中使用了Sanic框架处理用户注册、登录、商品管理、购物车等功能。同时,使用了Sanic JWT进行用户身份验证和会话管理

    最后总结一下:

    Sanic适用于需要高性能、实时性的应用,以及小型到中型项目

    Django适用于大型、全功能的Web应用程序,尤其是需要使用内置功能快速构建应用的场景

    Flask适用于对框架提供的功能有更大灵活性和控制需求,以及对轻量级框架的偏好

      好了,到这里又到了跟大家说再见的时候了。创作不易,帮忙点个赞再走吧。你的支持是我创作的动力,希望能带给大家更多优质的文章

  • 相关阅读:
    为UE和Unity开发者准备的Godot指南
    思维模型 协议
    Linux常见操作问题
    Oracle 19c RAC异机恢复到单机19c(包含PDB)
    黄金分割算法的一个简单实现
    VScode(1)之内网离线安装开发环境(VirtualBox+ubuntu+VScode)
    C# Windows 窗体控件中的边距和填充
    P1050 [NOIP2005 普及组] 循环 day16
    算法——排序
    LrC 13 & ACR 16:镜头模糊
  • 原文地址:https://blog.csdn.net/qiulin_wu/article/details/134506652