📜  Sanic Web 框架介绍 - Python

📅  最后修改于: 2022-05-13 01:54:50.970000             🧑  作者: Mango

Sanic Web 框架介绍 - Python

什么是SANIC?

Sanic 是一个用于Python 3.5+ 的异步 Web 框架和 Web 服务器,旨在快速运行。 Sanic 是在 MagicStack 开发的,基于他们的 uvloop 事件循环,它是Python asyncio 的默认事件循环的替代品,从而使 Sanic 速度极快。语法上 Sanic 类似于 Flask。
Sanic 可以用作 Django 或 Flask 的替代品,以构建高度可扩展、高效且性能极快的 Web 应用程序。

构建我们的第一个 SANIC 应用程序!

第1步:

最好在Python中使用虚拟环境来创建具有项目特定依赖项的隔离环境。由于 Sanic 19.6+ 版本不支持Python 3.5,我们将使用Python 3.6+。
要在我们的Python虚拟环境中安装 sanic,我们将执行以下命令 - pip3 install sanic

第2步:

让我们创建一个名为 sanic_demo 的目录并在其中创建一个名为main.py的文件,其中包含以下代码行 -

from sanic import Sanic
from sanic import response
  
app = Sanic("My First Sanic App")
  
  
# webapp path defined used route decorator
@app.route("/")
def run(request):
    return response.text("Hello World !")
  
  
# debug logs enabled with debug = True
app.run(host ="0.0.0.0", port = 8000, debug = True)

第 3 步:

我们可以从 IDE 运行main.py ,也可以通过执行以下命令从终端运行文件 - python3 main.py

Sanic 网络服务器在我们的 'localhost' 的 8000 端口上运行。

第4步:

从我们的 Web 浏览器导航到http://0.0.0.0:8000/会呈现“Hello World!”。

配置

Sanic 应用对象的config属性用于配置参数。可以为应用配置对象分配键值对,如下所示:

from sanic import Sanic
from sanic import response
  
app = Sanic("My First Sanic App")
  
app.config["SECURITY_TOKEN"] = [{"ApiKeyAuth": []}]

配置参数的完整列表可在官方文档页面 - Sanic Config

路由和蓝图

Sanic 支持路由装饰器将处理函数映射到 HTTP 请求。我们可以在 'route' 装饰器中使用名为methods的可选参数来处理列表中的任何 HTTP 方法。
蓝图是一个概念,用于将子路由从大型应用程序的子模块插入 Sanic 应用程序。蓝图必须注册到 Sanic 应用程序对象中。使用蓝图还可以避免在整个应用程序中传递 Sanic 应用程序对象。

让我们修改我们原来的main.py文件来演示路由和蓝图的用法——

# this is our 'main.py' file
from sanic import Sanic
from sanic import response
from sanic.log import logger
from controller import my_bp
  
app = Sanic("My First Sanic App")
  
# registering route defined by blueprint
app.blueprint(my_bp)
  
  
# webapp path defined used 'route' decorator
@app.route("/")
def run(request):
    return response.text("Hello World !")
  
  
@app.route("/post", methods =['POST'])
def on_post(request):
    try:
        return response.json({"content": request.json})
    except Exception as ex:
        import traceback
        logger.error(f"{traceback.format_exc()}")
  
  
app.run(host ="0.0.0.0", port = 8000, debug = True)

让我们创建一个名为controller.py的新文件来声明我们的蓝图——

# this is our 'controller.py' file
from sanic import response
from sanic import Blueprint
  
my_bp = Blueprint('my_blueprint')
  
@my_bp.route('/my_bp')
def my_bp_func(request):
    return response.text('My First Blueprint')

让我们运行main.py并在访问/my_bp端点时检查结果——

我们使用了一个名为“ Insomnia ”的网络客户端来演示我们的 POST 请求——

渲染内容

Sanic 路由可以提供 html 文件、json 内容、媒体文件等。要提供像图像、pdf、静态 html 文件等静态内容,我们需要使用app.static()方法,它将静态文件的路径映射到由指定的端点一条“路线”。

让我们修改我们的main.py文件来证明这一点——

# this is our 'main.py' file
from sanic import Sanic
from sanic import response
from sanic.log import logger
from controller import my_bp
  
app = Sanic("My First Sanic App")
  
# registering route defined by blueprint
app.blueprint(my_bp)
# configuring endpoint to serve an image downloaded from the web
app.static('/floral_image.jpg', 
           '/sanic_demo / ws_Beautiful_flowers_1920x1080.jpg')
  
  
# webapp path defined used 'route' decorator
@app.route("/")
def run(request):
    return response.text("Hello World !")
  
  
@app.route("/post", methods =['POST'])
def on_post(request):
    try:
        return response.json({"content": request.json})
    except Exception as ex:
        import traceback
        logger.error(f"{traceback.format_exc()}")
  
  
app.run(host ="0.0.0.0", port = 8000, debug = True)

运行main.py并访问http://0.0.0.0:8000/floral_image.jpg在浏览器上呈现图像。

让我们进一步修改main.py以访问一些 html 内容——

让我们创建一个示例index.html文件 -





    
    Render HTML on Sanic

  

Gotta go fast!


# this is our 'main.py' file
from sanic import Sanic
from sanic import response
from sanic.log import logger
from controller import my_bp
  
app = Sanic("My First Sanic App")
  
app.blueprint(my_bp)  # registering route defined by blueprint
  
app.static('/floral_image.jpg', 
           '/sanic_demo / ws_Beautiful_flowers_1920x1080.jpg')
  
  
# webapp path defined used 'route' decorator
@app.route("/")
def run(request):
    return response.text("Hello World !")
  
  
@app.route("/post", methods =['POST'])
def on_post(request):
    try:
        return response.json({"content": request.json})
    except Exception as ex:
        import traceback
        logger.error(f"{traceback.format_exc()}")
  
  
@app.route("/display")
def display(request):
    return response.file('/sanic_demo / index.html')
  
  
app.run(host ="0.0.0.0", port = 8000, debug = True)

运行main.py并访问http://0.0.0.0:8000/display在浏览器上呈现以下内容 -

异常处理

可以在 Sanic 请求处理程序中显式引发异常。异常将消息作为第一个参数,还可以包含状态代码。 @app.exception 装饰器可用于处理 Sanic 异常。让我们通过调整我们的main.py文件来演示——

# this is our 'main.py' file
  
from sanic import Sanic
from sanic import response
from sanic.log import logger
from controller import my_bp
from sanic.exceptions import ServerError, NotFound
  
  
app = Sanic("My First Sanic App")
  
app.blueprint(my_bp)  # registering route defined by blueprint
  
app.static('/floral_image.jpg', 
           '/sanic_demo / ws_Beautiful_flowers_1920x1080.jpg')
  
  
# raise Exception
@app.route('/timeout')
async def terminate(request):
    raise ServerError("Gateway Timeout error", status_code = 504)
  
  
@app.exception(NotFound)
async def ignore_5xx(request, exception):
    return response.text(f"Gateway is always up: {request.url}")
  
  
# webapp path defined used 'route' decorator
@app.route("/")
def run(request):
    return response.text("Hello World !")
  
  
@app.route("/post", methods =['POST'])
def on_post(request):
    try:
        return response.json({"content": request.json})
    except Exception as ex:
        import traceback
        logger.error(f"{traceback.format_exc()}")
  
  
@app.route("/display")
def display(request):
    return response.file('/sanic_demo / index.html')
  
  
app.run(host ="0.0.0.0", port = 8000, debug = True)

在浏览器上呈现异常 -

NotFound(当找不到路由的请求处理程序时抛出)和 ServerError(由于服务代码问题而抛出)是最常用的。

异步支持

Web 应用程序通常与外部资源(如数据库、队列、外部 API 等)对话,以检索处理请求所需的信息。 Sanic 是一个Python Web 框架,其中预置了Python 3.5+ 的 asyncio 库的 async/await 语法,是设计与许多连接一起工作的大型 I/O 绑定项目的理想选择。这使得 webapp 的请求能够以非阻塞和并发的方式处理。
Python 3.5 引入了 asyncio,这是一个使用 async/await 语法编写并发代码的库(来源:https: Python)。 asyncio 库提供了一个运行异步 I/O 函数的事件循环。 Sanic 提供对async/await语法的支持,从而使请求处理变得非阻塞且超快速。将async关键字添加到请求处理函数使函数异步处理代码,从而利用 Sanic 的性能优势。
Sanic 没有使用 asyncio 的事件循环,而是使用了 MagicStack 的专有uvloop ,它比 asyncio 的事件循环更快,从而实现了极快的速度。但是,在 Windows 操作系统上,由于 Windows 上的 uvloop 问题,Sanic 在后台恢复为 asyncio 的事件循环。

参考:Sanic 官方文档。