【Sanic 框架 / 1】深入学习:从入门到进阶

news/2025/1/20 14:35:11/

文章目录

  • 一、基础知识学习(入门)
    • Sanic 简介
    • 什么是 Sanic 框架?
    • Sanic 的优势和适用场景
      • 1. 高性能
      • 2. 异步支持
      • 3. 简洁易用
      • 4. WebSocket 支持
      • 5. 灵活扩展
    • 环境搭建
      • 1. 安装 Python(3.7 及以上版本)
      • 2. 创建虚拟环境
      • 3. 安装 Sanic
    • 第一个 Sanic 应用
      • 1. 创建应用文件
      • 2. 理解 app.run() 的参数配置
      • 3. 启动应用
      • 4. 访问应用
  • 二、核心概念与 API 学习
    • 路由
      • 路由的定义和动态参数处理
      • 路由匹配规则和方法(`GET`、`POST`、`PUT`、`DELETE` 等)
    • 请求与响应
      • `request` 对象的属性(`args`、`form`、`json`、`headers` 等)
      • `response` 对象的生成方法(`json()`、`text()`、`html()` 等)
    • 中间件
      • 中间件的定义与应用(`request` 和 `response` 阶段)
      • 使用中间件进行日志记录或验证请求
    • 异步处理
      • Python 异步编程基础(`async`/`await` 的使用)
      • 异步任务的实现与调度
    • 蓝图(Blueprints)
      • 理解蓝图的概念和用途
      • 如何使用蓝图进行模块化开发
    • 异常处理
      • 捕获全局异常
      • 自定义异常处理方法
  • 三、进阶功能与性能优化
    • WebSocket 支持
      • 实现 WebSocket 通信的简单服务
      • 处理实时消息与广播功能
    • 文件上传与下载
      • 实现文件上传接口
      • 提供文件下载服务
    • 中间件
      • 中间件的定义与应用(`request` 和 `response` 阶段)
      • 使用中间件进行日志记录或验证请求
    • 异步处理
      • Python 异步编程基础(`async`/`await` 的使用)
      • 异步任务的实现与调度
    • 蓝图(Blueprints)
      • 理解蓝图的概念和用途
      • 如何使用蓝图进行模块化开发
    • 异常处理
      • 捕获全局异常
      • 自定义异常处理方法

一、基础知识学习(入门)

Sanic 简介

Sanic 是一个基于 Python 的异步 Web 框架,它使用 Python 的 asyncio 库实现高效的异步请求处理,适合高并发环境下的 Web 应用开发。Sanic 的设计理念是轻量级且高性能,特别适用于需要处理大量并发请求的应用,比如实时聊天、推送通知、API 服务等。

与传统的同步 Web 框架相比,Sanic 利用异步特性,通过 asyncawait 语法大幅提升了 Web 服务的响应能力,能够同时处理多个 I/O 密集型任务,而不会阻塞服务器的主线程。

什么是 Sanic 框架?

Sanic 是一个用 Python 编写的 Web 框架,专注于高性能和异步编程。它允许开发者通过异步的方式处理 HTTP 请求,从而提高并发性能。Sanic 完全支持 Python 3.7 及以上版本,并且支持 async/await 语法,使得编写高并发、实时通信和长连接等服务变得更加简单高效。

与其他 Web 框架(如 Flask 或 Django)相比,Sanic 的主要特点是其内置的异步支持,它可以在一个请求的生命周期内并行处理多个 I/O 操作。这使得 Sanic 在面对高并发或实时数据更新的场景时,比传统框架表现出更高的性能。

Sanic 的优势和适用场景

1. 高性能

Sanic 利用异步非阻塞 I/O 和 asyncio 协程,能够大幅提升并发请求的处理效率。相比于传统的同步框架,Sanic 能够在处理大量并发连接时,保持高效且稳定。

2. 异步支持

Sanic 本质上是异步的框架,使用 asyncawait 语法来处理请求和响应。对于网络请求、数据库操作和文件 I/O 等耗时操作,Sanic 能够高效并发执行,而不会阻塞主线程。

3. 简洁易用

Sanic 提供了简单直观的 API,开发者可以快速上手。无论是新手还是经验丰富的开发者,都能通过简洁的语法和易于理解的文档快速构建 Web 应用。

4. WebSocket 支持

Sanic 内置对 WebSocket 的支持,适合实时聊天、实时通知、推送等应用场景,能够处理持续的双向通信。

5. 灵活扩展

Sanic 提供了蓝图(Blueprint)和中间件支持,方便开发者模块化管理代码,并对请求生命周期进行控制。可以轻松集成数据库、缓存、日志等第三方服务,满足不同的业务需求。

适用场景:

  • 高并发 Web API 服务
  • 实时聊天应用
  • 推送通知系统
  • IoT(物联网)系统
  • 数据流和实时分析服务

环境搭建

在开始使用 Sanic 开发应用之前,首先需要搭建开发环境。

1. 安装 Python(3.7 及以上版本)

Sanic 支持 Python 3.7 及以上版本。如果尚未安装 Python,可以访问 Python 官网 下载并安装。

在终端中检查 Python 版本:

python --version

确保安装的是 Python 3.7 或更高版本。

2. 创建虚拟环境

为了避免与系统其他项目的依赖冲突,建议使用 Python 的虚拟环境管理工具(如 venvvirtualenv)来为项目创建一个独立的环境。

使用 venv 创建虚拟环境的步骤:

python -m venv sanic_env

激活虚拟环境:

  • 在 Linux/macOS 上:

    source sanic_env/bin/activate
    
  • 在 Windows 上:

    .\sanic_env\Scripts\activate
    

激活虚拟环境后,可以在这个环境中安装所有依赖,不会影响系统的其他 Python 项目。

3. 安装 Sanic

安装 Sanic 框架,只需要运行以下命令:

pip install sanic

安装完成后,可以在 Python 环境中通过 import sanic 测试是否安装成功。

第一个 Sanic 应用

现在,我们开始编写第一个简单的 Sanic 应用,它会在访问根路径时返回一条简单的 JSON 消息。

1. 创建应用文件

在项目目录下,创建一个新的 Python 文件,比如 app.py,然后添加以下代码:

python">from sanic import Sanic
from sanic.response import json# 创建一个 Sanic 实例
app = Sanic("HelloWorldApp")# 创建路由,处理根路径请求
@app.route("/")
async def hello(request):return json({"message": "Hello, Sanic!"})# 运行应用
if __name__ == "__main__":app.run(host="0.0.0.0", port=8000)

2. 理解 app.run() 的参数配置

app.run() 方法用于启动 Sanic 应用,它接受多个参数来配置应用的运行方式。常用参数如下:

  • host:指定应用的主机地址,默认为 127.0.0.1(即本机地址)。设置为 "0.0.0.0" 可以让应用对外开放,允许其他设备访问。
  • port:指定应用监听的端口号,默认为 8000。可以根据需要修改为其他端口。
  • debug:如果设置为 True,将在开发过程中启用调试模式,方便调试和查看错误信息。默认情况下,开发模式是启用的。

3. 启动应用

在终端中,进入 app.py 所在的目录,并运行以下命令启动应用:

python app.py

会看到类似如下的信息,表示应用已启动:

[2025-01-13 00:00:00 +0000] [1234] [INFO] Sanic: Sanic version 22.6.0
[2025-01-13 00:00:00 +0000] [1234] [INFO] Goin' Fast @ http://0.0.0.0:8000

4. 访问应用

打开浏览器,访问 http://127.0.0.1:8000/,会看到返回的 JSON 响应:

{"message": "Hello, Sanic!"
}

二、核心概念与 API 学习

路由

路由的定义和动态参数处理

在 Sanic 中,路由用于定义请求的 URL 路径和处理函数之间的映射关系。通过装饰器的形式,将函数与路由路径绑定,当访问指定路径时,Sanic 会调用相应的处理函数。

最基础的路由定义方式如下:

python">@app.route("/hello")
async def hello(request):return json({"message": "Hello, Sanic!"})

此外,Sanic 支持动态路由参数,可以通过路径中的占位符定义动态参数。例如:

python">@app.route("/user/<user_id>")
async def get_user(request, user_id):return json({"user_id": user_id})

在上面的例子中,<user_id> 是动态参数,Sanic 会提取 URL 中的值并将其传递给路由处理函数。

路由匹配规则和方法(GETPOSTPUTDELETE 等)

Sanic 支持多种 HTTP 方法(如 GETPOSTPUTDELETE)的路由定义。默认情况下,路由会匹配 GET 请求,但可以显式地指定 HTTP 方法。

例如,定义 POST 请求路由:

python">@app.route("/login", methods=["POST"])
async def login(request):data = request.json  # 获取 JSON 数据return json({"status": "success", "data": data})

同样,也可以定义多个方法的路由:

python">@app.route("/user/<user_id>", methods=["GET", "PUT"])
async def user_info(request, user_id):if request.method == "GET":return json({"user_id": user_id, "action": "get"})elif request.method == "PUT":return json({"user_id": user_id, "action": "update"})

Sanic 会根据请求方法自动调用相应的路由处理函数。

请求与响应

request 对象的属性(argsformjsonheaders 等)

Sanic 的 request 对象提供了丰富的属性来获取请求中的各种数据:

  • args:获取查询参数。例如,/search?q=python 中,q 可以通过 request.args.get("q") 获取。
  • form:获取表单数据。对于 POST 请求中的表单数据,可以使用 request.form
  • json:如果请求体是 JSON 格式的数据,可以使用 request.json 来获取。
  • headers:访问请求头部信息。例如,request.headers["User-Agent"] 获取用户代理。
python">@app.route("/search", methods=["GET"])
async def search(request):query = request.args.get("q", "")return json({"query": query})@app.route("/login", methods=["POST"])
async def login(request):form_data = request.formreturn json({"status": "success", "data": form_data})

response 对象的生成方法(json()text()html() 等)

Sanic 的 response 对象提供了多种方法来生成不同类型的响应:

  • json():返回 JSON 格式的响应。
  • text():返回纯文本格式的响应。
  • html():返回 HTML 格式的响应。
python">@app.route("/json")
async def json_response(request):return json({"message": "This is a JSON response"})@app.route("/text")
async def text_response(request):return text("This is a plain text response")@app.route("/html")
async def html_response(request):return html("<h1>This is an HTML response</h1>")

这些方法会自动设置合适的 Content-Type 头,确保客户端能够正确解析响应数据。

中间件

中间件的定义与应用(requestresponse 阶段)

中间件是处理请求和响应的钩子函数,它们在请求到达路由之前和响应返回客户端之前执行。Sanic 支持两种类型的中间件:

  • 请求中间件:在请求被路由处理前执行。
  • 响应中间件:在响应返回客户端前执行。

定义中间件的方式如下:

python">from sanic import Sanic
from sanic.response import jsonapp = Sanic("MiddlewareExample")# 请求中间件
@app.middleware("request")
async def add_request_id(request):request["request_id"] = "12345"# 响应中间件
@app.middleware("response")
async def add_custom_header(request, response):response.headers["X-Custom-Header"] = "This is a custom header"return response@app.route("/")
async def index(request):return json({"message": "Hello with Middleware!"})if __name__ == "__main__":app.run(host="0.0.0.0", port=8000)

使用中间件进行日志记录或验证请求

中间件非常适合用于日志记录、请求验证、身份验证等任务。例如,可以在请求阶段记录日志,或者在响应阶段修改返回的内容:

python">@app.middleware("request")
async def log_request(request):print(f"Incoming request: {request.method} {request.path}")

异步处理

Python 异步编程基础(async/await 的使用)

Sanic 的最大特点之一就是异步处理请求。可以在路由处理函数中使用 asyncawait,让函数变为异步执行,从而提高并发性能。

  • async:用于定义异步函数。
  • await:用于等待异步操作的结果。

例如,使用 asyncawait 来模拟一个耗时操作:

python">@app.route("/long_task")
async def long_task(request):await asyncio.sleep(5)  # 模拟耗时任务return json({"message": "Task completed"})

Sanic 会在等待 asyncio.sleep(5) 时不阻塞其他请求,充分利用异步特性。

异步任务的实现与调度

在 Sanic 中,可以使用 asyncio 来调度异步任务。例如,使用后台任务执行耗时操作:

python">import asyncio@app.route("/start_task")
async def start_task(request):asyncio.create_task(long_running_task())return json({"message": "Task started!"})async def long_running_task():await asyncio.sleep(10)print("Task finished")

蓝图(Blueprints)

理解蓝图的概念和用途

蓝图是 Sanic 中用于组织应用代码的工具,它允许将路由和视图函数分组,以便于模块化开发。通过蓝图,可以将一个大型应用拆分成多个小的模块。

例如,创建一个蓝图并在应用中注册:

python">from sanic import Blueprint# 创建蓝图
bp = Blueprint("user")@bp.route("/profile")
async def profile(request):return json({"message": "User Profile"})# 注册蓝图
app.blueprint(bp)

如何使用蓝图进行模块化开发

通过使用蓝图,可以将不同功能的路由分别放在不同的文件中,实现模块化管理。例如,将用户相关的路由放在 user.py 文件中,产品相关的路由放在 product.py 中。

python"># user.py
from sanic import Blueprintbp = Blueprint("user")@bp.route("/profile")
async def profile(request):return json({"message": "User Profile"})# main.py
from sanic import Sanic
from user import bpapp = Sanic("ModularApp")
app.blueprint(bp)if __name__ == "__main__":app.run(host="0.0.0.0", port=8000)

异常处理

捕获全局异常

Sanic 允许全局捕获异常并进行自定义处理。可以使用 @app.exception 装饰器来捕获全局异常:

python">@app.exception(Exception)
async def handle_exception(request, exception):return json({"error": str(exception)}, status=500)

自定义异常处理方法

也可以定义特定的异常处理函数,根据不同的错误类型做不同的处理。例如,处理 404 错误时返回自定义页面:

python">@app.exception(NotFound)
async def handle_not_found(request, exception):return html("<h1>Page Not Found</h1>", status=404)

三、进阶功能与性能优化

WebSocket 支持

实现 WebSocket 通信的简单服务

WebSocket 是一种在客户端和服务器之间建立全双工通信的协议,允许服务器和客户端之间实时双向传输数据。Sanic 提供了对 WebSocket 的原生支持,使用 @app.websocket() 装饰器可以轻松实现 WebSocket 服务。

以下是一个简单的 WebSocket 示例:

python">@app.websocket('/ws')
async def websocket_handler(request, ws):while True:message = await ws.recv()  # 接收消息print(f"Received message: {message}")await ws.send(f"Echo: {message}")  # 发送回显消息

在此代码中,客户端发送的消息会被服务器接收到,并通过 ws.send() 返回给客户端,实现了基本的 WebSocket 双向通信。

处理实时消息与广播功能

除了基本的回显功能,WebSocket 还可以用于实现实时消息推送或广播。例如,当一个客户端发送消息时,其他所有连接的客户端也能收到该消息:

python">sockets = []  # 存储 WebSocket 连接@app.websocket('/ws')
async def websocket_handler(request, ws):sockets.append(ws)try:while True:message = await ws.recv()for socket in sockets:if socket != ws:  # 不广播给发送者await socket.send(message)except:sockets.remove(ws)  # 断开连接时移除

在这个例子中,服务器会将每个客户端发送的消息广播给其他所有客户端,从而实现了实时通信功能。

文件上传与下载

实现文件上传接口

Sanic 提供了 request.files 来处理文件上传。可以通过 POST 请求上传文件,并将其保存到服务器本地。

python">@app.route('/upload', methods=["POST"])
async def upload_file(request):file = request.files.get('file')  # 获取上传的文件if file:with open(f"./uploads/{file.name}", 'wb') as f:f.write(file.body)  # 将文件内容写入磁盘return json({"status": "success", "filename": file.name})return json({"status": "fail", "message": "No file uploaded"})

此代码将上传的文件保存到服务器的 uploads/ 文件夹,并返回上传文件的文件名。

提供文件下载服务

Sanic 通过 send_file() 方法支持文件下载。可以根据文件路径返回文件给客户端:

python">from sanic.response import send_file@app.route('/download/<filename>', methods=["GET"])
async def download_file(request, filename):file_path = f"./uploads/{filename}"return await send_file(file_path)

客户端可以访问 /download/<filename> 来下载指定的文件。send_file 会自动处理文件传输,支持流式传输,适合大文件下载。

中间件

中间件的定义与应用(requestresponse 阶段)

中间件是处理请求和响应的钩子函数,它们在请求到达路由之前和响应返回客户端之前执行。Sanic 支持两种类型的中间件:

  • 请求中间件:在请求被路由处理前执行。
  • 响应中间件:在响应返回客户端前执行。

定义中间件的方式如下:

python">from sanic import Sanic
from sanic.response import jsonapp = Sanic("MiddlewareExample")# 请求中间件
@app.middleware("request")
async def add_request_id(request):request["request_id"] = "12345"# 响应中间件
@app.middleware("response")
async def add_custom_header(request, response):response.headers["X-Custom-Header"] = "This is a custom header"return response@app.route("/")
async def index(request):return json({"message": "Hello with Middleware!"})if __name__ == "__main__":app.run(host="0.0.0.0", port=8000)

使用中间件进行日志记录或验证请求

中间件非常适合用于日志记录、请求验证、身份验证等任务。例如,可以在请求阶段记录日志,或者在响应阶段修改返回的内容:

python">@app.middleware("request")
async def log_request(request):print(f"Incoming request: {request.method} {request.path}")

异步处理

Python 异步编程基础(async/await 的使用)

Sanic 的最大特点之一就是异步处理请求。可以在路由处理函数中使用 asyncawait,让函数变为异步执行,从而提高并发性能。

  • async:用于定义异步函数。
  • await:用于等待异步操作的结果。

例如,使用 asyncawait 来模拟一个耗时操作:

python">@app.route("/long_task")
async def long_task(request):await asyncio.sleep(5)  # 模拟耗时任务return json({"message": "Task completed"})

Sanic 会在等待 asyncio.sleep(5) 时不阻塞其他请求,充分利用异步特性。

异步任务的实现与调度

在 Sanic 中,可以使用 asyncio 来调度异步任务。例如,使用后台任务执行耗时操作:

python">import asyncio@app.route("/start_task")
async def start_task(request):asyncio.create_task(long_running_task())return json({"message": "Task started!"})async def long_running_task():await asyncio.sleep(10)print("Task finished")

蓝图(Blueprints)

理解蓝图的概念和用途

蓝图是 Sanic 中用于组织应用代码的工具,它允许将路由和视图函数分组,以便于模块化开发。通过蓝图,可以将一个大型应用拆分成多个小的模块。

例如,创建一个蓝图并在应用中注册:

python">from sanic import Blueprint# 创建蓝图
bp = Blueprint("user")@bp.route("/profile")
async def profile(request):return json({"message": "User Profile"})# 注册蓝图
app.blueprint(bp)

如何使用蓝图进行模块化开发

通过使用蓝图,可以将不同功能的路由分别放在不同的文件中,实现模块化管理。例如,将用户相关的路由放在 user.py 文件中,产品相关的路由放在 product.py 中。

python"># user.py
from sanic import Blueprintbp = Blueprint("user")@bp.route("/profile")
async def profile(request):return json({"message": "User Profile"})# main.py
from sanic import Sanic
from user import bpapp = Sanic("ModularApp")
app.blueprint(bp)if __name__ == "__main__":app.run(host="0.0.0.0", port=8000)

异常处理

捕获全局异常

Sanic 允许全局捕获异常并进行自定义处理。可以使用 @app.exception 装饰器来捕获全局异常:

python">@app.exception(Exception)
async def handle_exception(request, exception):return json({"error": str(exception)}, status=500)

自定义异常处理方法

也可以定义特定的异常处理函数,根据不同的错误类型做不同的处理。例如,处理 404 错误时返回自定义页面:

python">@app.exception(NotFound)
async def handle_not_found(request, exception):return html("<h1>Page Not Found</h1>", status=404)


http://www.ppmy.cn/news/1564676.html

相关文章

Java调用C/C++那些事(JNI)

一、引言 Java开发中&#xff0c;可能会遇到一些需要复用、移植C/C库的场景。 比如说&#xff0c;对于某些特定功能&#xff0c;C/C已有代码实现&#xff0c;但是Java没有。为了可以让Java成功使用该功能&#xff0c;有几种方式&#xff1a; 优势劣势将C/C代码翻译成Java代码…

基于 K-Means 聚类分析实现人脸照片的快速分类

注:本文在创作过程中得到了 ChatGPT、DeepSeek、Kimi 的智能辅助支持,由作者本人完成最终审阅。 在 “视频是不能 P 的” 系列文章中,博主曾先后分享过人脸检测、人脸识别等相关主题的内容。今天,博主想和大家讨论的是人脸分类问题。你是否曾在人群中认错人,或是盯着熟人的…

【氮化镓】香港科技大学陈Kevin-单片集成GaN比较器

一、引言(Introduction) GaN HEMT的重要性 文章开篇便强调了氮化镓(GaN)高电子迁移率晶体管(HEMT)在下一代功率转换系统中的巨大潜力。GaN HEMT具备高开关频率、低导通电阻、高击穿电压以及宽工作温度范围等优势,使其成为功率电子领域的热门研究对象。这些特性使得GaN…

2025.1.18——1300

2025.1.18——1300 A 1300 There are n n n cities located on the number line, the i i i-th city is in the point a i a_i ai​. The coordinates of the cities are given in ascending order, so a 1 < a 2 < ⋯ < a n a_1 < a_2 < \dots < a_n a…

浅谈 JVM

JVM 内存划分 JVM 内存划分为 四个区域&#xff0c;分别为 程序计数器、元数据区、栈、堆 程序计数器是记录当前指令执行到哪个地址 元数据区存储存储的是当前类加载好的数据&#xff0c;包括常量池和类对象的信息&#xff0c;.java 编译之后产生 .class 文件&#xff0c;运…

【springboot 集成 mybatis-plus】

springboot 集成 mybatis-plus 前言实战代码生成器自动填充字段 前言 正如MyBatis-Plus官网所说&#xff0c;MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;提供了强大的CRUD操作&#xff0c;支持主键自动生成&#xff0c;代码生成器&#xff0c;自动填充字段等等&#…

【ComfyUI专栏】ComfyUI的环境配置

对于常规的用户来说,我们碰到需要非常注意的问题,就是我们的ComfyUI的各个节点可能会有不兼容的情况,因此我们最好建立独立的Python虚拟环境。如何建立虚拟的环境呢?其实非常简单。 执行的命令如下: Python -m venv venv #创建Venv名称的虚拟环境 cd venv #进入到Venv …

InVideo AI技术浅析(四):机器学习

一、视频剪辑与合成 1. 工作原理 视频剪辑与合成是视频编辑中的核心任务,旨在将多个视频片段、音频和字幕等元素组合成一个连贯且富有吸引力的视频。InVideo AI 使用机器学习技术自动化这一过程,通过分析视频内容、识别重要片段并进行智能剪辑和合成。其核心目标是提升观众…