Sanic框架路由用法实例分析


Posted in Python onJuly 16, 2018

本文实例讲述了Sanic框架路由用法。分享给大家供大家参考,具体如下:

前面一篇《Sanic框架安装与简单入门》简单介绍了Sanic框架的安装与基本用法,这里进一步学习Sanic框架的路由。

简介

Sanic是一个类似Flask的Python 3.5+ Web服务器,它的写入速度非常快。除了Flask之外,Sanic还支持异步请求处理程序。这意味着你可以使用Python 3.5中新的闪亮的异步/等待语法,使你的代码非阻塞和快速。

前言:Sanic最低支持Python 3.5,如果需要学习Sanic,请先下载版本不低于3.5的Python包

路由

路由允许用户为不同的URL端点指定不同的处理函数,我们取出上一篇《Sanic框架安装与简单入门》的路由为例:

from sanic.response import json
@app.route("/")
async def hello_sanic(request):
  data = json({"code":0})
  return data

当我们在浏览器输入http://localhost:5000/时,根据路由匹配到处理函数hello_sanic,最终返回JSON对象。Sanic处理函数必须使用语法async def来定义,因为它们是异步行数。

请求参数

Sanic处理函数带有一个支持请求的参数,即上面的request参数。如果需要制定一个参数,我们可以使用尖角括号将其括起来,如下所示:

from sanic.response import json
@app.route("/hello/<name>")
async def hello(request,name):
  return json({"name":name})

此时我们再浏览器输入:http://localhost:5000/hello/laowang时,Sanic将会根据路由匹配处理函数,从而返回数据。此时,我们需要对参数进行指定类型,可以在路由中的参数后面加上:type,假设传入一个age参数,为int类型,路由可以这么写:/hello/<age:int>。代码如下:

from sanic.response import json
@app.route("/hello/<age:int>")
async def hello_age(request,age):
  return json({"age":age})

此时就可以指定用户传入指定类型的参数了,如果类型不对,将报404错误。

请求类型

对于Sanic处理网络请求,也举了不少例子,可是这些都是GET请求,那我们该如何定义一个POST请求呢?与Flask相同,@app.route支持一个可选参数methodsmethods可传入一个列表类型,如此,它将允许处理函数使用列表中的任何HTTP方法。

from sanic.response import json
@app.route("/post/json_data",methods=["POST"])
async def post_json(request):
  """
  POST请求 json数据
  """
  return json(request.json)
@app.route("/post/form_data",methods=["POST"])
async def post_form(request):
  """
  POST请求 form表单数据
  """
  return json(request.form)
@app.route("/get/data",methods=["GET"])
async def get_data(request):
  """
  GET请求
  """
  return json(request.args)

因为GET请求时默认的,所以,如果需要定义一个GET请求,那么methods参数可以无需传递。@app.route还支持另一个可选参数host,这限制了一条到所提供的主机或主机的路由。

from sanic.response import text
@app.route("/hello/host",host="abc.com")
async def hello_host(request):
  return text("hello host")

在浏览器中访问此路由,如果主机头不匹配abc.com,那么将会报404错误。

路由的装饰器写法除了上面介绍的那种,还可以将其简写,如下所示:

from sanic.response import json
@app.get("/short/get")
async def short_get(request):
  return json(request.args)
@app.post("/short/post")
async def short_post(request):
  return json(request.json)

add_route方法

通常我们指定一个路由,都是通过@app.route装饰器,然而,这个装饰器实际上只是这个add_route方法的一个包装器,使用方法如下:

async def add_get_route(request):
  """
  添加GET请求
  """
  return json(request.args)
async def add_get_type_route(request,age):
  """
  添加带指定类型的参数的GET请求
  """
  return json({"age":age})
async def add_post_route(request):
  """
  添加POST请求
  """
  return json(request.json)
app.add_route(add_get_route,"/add_get_route")
app.add_route(add_get_type_route,"/add_get_type_route/<age:int>")
app.add_route(add_post_route,"/add_post_route",methods=["POST"])

重定向

Sanic提供了一个url_for基于处理程序方法名称生成URL的方法。如果你想要避免将URL路径硬编码到你的应用程序当中,这很有用。例如:

from sanic.response import text,redirect
@app.route("/url_info")
async def url_info(request):
  url = app.url_for('post_handler',name="laozhang",arg_one="one",arg_two="two")
  print(url)
  return redirect(url)
@app.route("/post_handler/<name>")
async def post_handler(request,name):
  print(request.args)
  return text("name:{}".format(name))

url_for使用注意:第一个参数为重定向URL的路由名称(默认为函数名称),并非URL名称。另外我们可以将一些请求参数指派到url_for方法中,上面例子重定向后的url将会是:

/post_handler/laozhang?arg_one=one&arg_two=two

也可以传递多值参数:

app.url_for("post_handler",favorite=["football","bastketball"])
# /post_handler?favorite=football&favorite=bastketball

唯一URL

在Flask中,我们顶一个一个URL/get,此时我们访问/get将可以访问成功,如果输入/get/将会返回404错误,这就是唯一URL。在Sanic中同样拥有此功能,我们可以通过配置strict_slashes参数来实现:

from sanic.response import text
@app.route("/get",strict_slashes=True)
async def get(request):
  return text("it is ok!")

注意strict_slashes默认值为None,如果不设置的话,访问/get/get/都将可以访问成功,那么这就不是唯一URL了。在上面的例子中,我们将此值设置为True,此时我们输入/get/,将会返回一个404错误,这样就完成了一个唯一URL的实现。

如果我们需要将所有的URL都设置成为唯一URL,我们可以这样:

from sanic import Sanic
from sanic.response import text
app = Sanic(strict_slashes=True)
@app.route("/hello")
async def hello(request):
  return text("it is ok!")
@app.route("/world")
async def world(request):
  return text("it is ok!")

/helloworld都变成了唯一URL。

如果我们只需要部分URL设置成唯一URL,我们可以在@app.route装饰器中传入strict_slashes,并设置为Flase,那么此URL将不是唯一URL。或者我们也可以定义一个蓝图,如下:

from sanic import Blueprint
ss_bp = Blueprint("aaa",strict_slashes=False)
@ss_bp.route("/world")
async def world(request):
  return text("it is ok!")
app.blueprint(ss_bp)

即使你在app中传递了参数strict_slashes=True,那么也没有用,所有通过此蓝图定义的URL都将不是唯一URL。

自定义路由名称

通常一个路由的名称为程序处理方法名称,即函数.__name__生成的,用于可以传递一个name参数到装饰器中来修改它的名称,如下:

from sanic.response import text
@app.route("/get",name="get_info")
async def get(request):
  return text("it is ok!")

此时url_for中传递的将不是函数名称,而是name的值:

print(app.url_for("get_info"))   # /get

同样,也适用于蓝图:

from sanic import Blueprint
ss_bp = Blueprint("test_bp")
@ss_bp.route("/get",name="get_info")
async def get(request):
  return text("it is ok!")
app.blueprint(ss_bp)
print(app.url_for("test_bp.get_info"))

静态文件的URL

我们需要构建一个特定的URL来访问我们需要的HTML,此时我们可以这样:

from sanic import Sanic,Blueprint
app = Sanic()
app.static("/home","./static/home.html")

此时我们在访问/home就可以链接到我们指定的HTML中了,此方法同样适用于蓝图。

CompositionView

除了上面那几种定义路由的方法之外,Sanic还提供了CompositionView来动态添加路由:

from sanic.views import CompositionView
from sanic.response import text
async def post_handler(request):
  print(request.json)
  return text('it is ok!')
view = CompositionView()
view.add(["POST"],post_handler)
app.add_route(view,"/post_info")

如此,就构造了一个POST请求的接口

处理器装饰器

由于Sanic处理程序是简单的Python函数,因此可以用与Flask类似的修饰符应用于它们。一个典型的用例就是当一些代码想要在处理程序的代码执行之前执行:

from sanic.response import text
def is_authorized():
  return True
def authorized(func):
  async def wrapper(request,*args,**kwargs):
    is_auth = is_authorized()
    if is_auth:
      response = await func(request,*args,**kwargs)
      return response
    else:
      return text("it is not authorized")
  return wrapper
@app.route("/get_user_info")
@authorized
async def get_user_info(request):
  return text("get_user_info")

更多关于Python相关内容可查看本站专题:《Python入门与进阶经典教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
windows下wxPython开发环境安装与配置方法
Jun 28 Python
python运行其他程序的实现方法
Jul 14 Python
python中的字典操作及字典函数
Jan 03 Python
python使用magic模块进行文件类型识别方法
Dec 08 Python
详解Python给照片换底色(蓝底换红底)
Mar 22 Python
python 一个figure上显示多个图像的实例
Jul 08 Python
python障碍式期权定价公式
Jul 19 Python
python获取全国城市pm2.5、臭氧等空气质量过程解析
Oct 12 Python
python numpy 矩阵堆叠实例
Jan 17 Python
Python Pandas list列表数据列拆分成多行的方法实现
Dec 14 Python
python使用Windows的wmic命令监控文件运行状况,如有异常发送邮件报警
Jan 30 Python
Python使用Turtle模块绘制国旗的方法示例
Feb 28 Python
Sanic框架安装与简单入门示例
Jul 16 #Python
python 除法保留两位小数点的方法
Jul 16 #Python
Python自定义装饰器原理与用法实例分析
Jul 16 #Python
python 正确保留多位小数的实例
Jul 16 #Python
浅谈Python里面小数点精度的控制
Jul 16 #Python
详解Django中间件执行顺序
Jul 16 #Python
转换科学计数法的数值字符串为decimal类型的方法
Jul 16 #Python
You might like
PHP5.5在windows安装使用memcached服务端的方法
2014/04/16 PHP
PHP中使用curl入门教程
2015/07/02 PHP
thinkPHP中分页用法实例分析
2015/12/26 PHP
PHP 极验验证码实例讲解
2016/09/29 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
2019/04/03 PHP
ThinkPHP3.2.3框架邮件发送功能图文实例详解
2019/04/23 PHP
网站如何做到完全不需要jQuery也可以满足简单需求
2013/06/27 Javascript
js实现省市联动效果的简单实例
2014/02/10 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
2015/11/24 Javascript
js实现C#的StringBuilder效果完整实例
2015/12/22 Javascript
JavaScript设计模式之单例模式简单实例教程
2018/07/02 Javascript
详解Vue开发微信H5微信分享签名失败问题解决方案
2018/08/09 Javascript
vue结合element-ui使用示例
2019/01/24 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
2019/05/07 Javascript
javaScript实现一个队列的方法
2020/07/14 Javascript
js实现随机圆与矩形功能
2020/10/29 Javascript
Python编码类型转换方法详解
2016/07/01 Python
python selenium 获取标签的属性值、内容、状态方法
2018/06/22 Python
python爬虫开发之Beautiful Soup模块从安装到详细使用方法与实例
2020/03/09 Python
python实现猜数游戏(保存游戏记录)
2020/06/22 Python
Python爬虫进阶之爬取某视频并下载的实现
2020/12/08 Python
python 基于opencv 实现一个鼠标绘图小程序
2020/12/11 Python
Python3利用openpyxl读写Excel文件的方法实例
2021/02/03 Python
检测用户浏览器是否支持CSS3的方法
2009/08/29 HTML / CSS
利用CSS3 动画 绘画 圆形动态时钟
2018/03/20 HTML / CSS
一波HTML5 Canvas基础绘图实例代码集合
2016/02/28 HTML / CSS
浅谈amaze-ui中datepicker和datetimepicker注意的几点
2020/08/21 HTML / CSS
阿里旅行:飞猪
2017/01/05 全球购物
实习自荐信
2013/10/13 职场文书
班长竞选演讲稿
2014/04/24 职场文书
美术社团活动总结
2014/06/27 职场文书
人事主管岗位职责说明书
2014/07/30 职场文书
2015年推广普通话演讲稿
2015/03/20 职场文书
大学生就业意向书
2015/05/11 职场文书
导游词之天下银坑景区
2019/11/21 职场文书
详解Python 3.10 中的新功能和变化
2021/04/28 Python