Python Web框架Sanic 路由

发表时间:2020-02-18

路由的意思就是,让开发者为不同的URL路径指定不同的处理函数,这些处理函数的输入就是我们前面讲到的Sanic请求数据,而输出就是Sanic的响应类的实例。这样我们的web服务器端就能对不同的URL访问路径实现不同的逻辑和功能。比如根路径 "/" 的处理函数,登录路径 "/login" 的处理函数等等。

Sanic route 路由

路由基本形式

前面的实例中,我们已经见过路由的基本形式,就是下面这样,通过 Sanic 类的实例 app 的方法 @app.route() 来实现,这个方法是一个装饰器:

from sanic import Sanic
from sanic import response

app = Sanic()

@app.route('/')
async def home(request):
    return response.text('Welcome to 猿人学python')


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8888, debug=True)

运行这个程序,用浏览器访问 http://127.0.0.1:8888/ 时,路径 / 就会匹配到处理函数 home() ,并返回纯文本 Welcome to 猿人学python

Sanic 的处理函数必须要使用 async def 语法进行定义,因为它们是异步函数。

请求参数

Sanic的路由支持请求参数,其基本格式是用单书名号把参数引起来: <PARAM> 。请求参数会被当做关键字参数传递给路由处理函数:

@app.route('/user/<user_id>')
async def user_handler(request, user_id):
    return response.text('User ID: {}'.format(user_id))

请求参数可以被指定数据类型,在参数名字后面加 :type 实现。如果参数没有匹配指定的类型,Sanic就会抛出 NotFound 异常,并产生 404: Page not found 的错误。

from sanic.response import text

@app.route('/int/<arg_int:int>')
async def integer_handler(request, arg_int):
    return response.text('Integer - {}'.format(arg_int))

@app.route('/number/<arg_number:number>')
async def number_handler(request, arg_number):
    return response.text('Float - {}'.format(arg_number))

@app.route('/user/<name:[A-z]+>')
async def user_handler(request, name):
    return response.text('Person - {}'.format(name))

@app.route('/group/<group_id:[A-z0-9]{0,5}>')
async def group_handler(request, group_id):
    return response.text('Group - {}'.format(group_id))

如上面的代码所示, :type 中的 type 支持的形式有:

  • int – int 整数
  • number – float 浮点数
  • alpha – str 只含有大小写字母的字符串
  • path – str 匹配正则 r"[^/].*?" 的字符串
  • uuid – uuid.UUID
  • string – string 字符串,不指定 :type 时的默认类型
  • 任何形式的正则表达式

其实, :type type 就是通过正则表达式匹配的,具体可以看Sanic源码中的 router.py REGEX_TYPES 的定义:

REGEX_TYPES = {
    "string": (str, r"[^/]+"),
    "int": (int, r"\d+"),
    "number": (float, r"[0-9\\.]+"),
    "alpha": (str, r"[A-Za-z]+"),
    "path": (str, r"[^/].*?"),
    "uuid": (
        uuid.UUID,
        r"[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-"
        r"[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}",
    ),  
}

HTTP 请求类型

默认情况下,一个路由定义仅支持对URL的 GET 请求。但是,可以通过 @app.route 装饰器的 methods 参数让它支持任何形式的HTTP方法。参数 methods 是一个list,把需要路由函数支持的HTTP方法放到这个list即可:

@app.route('/post', methods=['POST'])
async def post_handler(request):
    return response.text('POST request: {}'.format(request.json))

@app.route('/many', methods=['GET', 'POST', 'DELETE'])
async def many_handler(request):
    return response.text('many request: {}'.format(request.json))

@app.route 还有一个可选参数 host ,它可以是字符串或列表。它限定了路由对应的host。如果还有不带host的路由,则该路由是默认的。

@app.route('/get', methods=['GET'], host='yuanrenxue.com')
async def get_handler(request):
    return text('GET request - {}'.format(request.args))


#如果header中的host不匹配yuanrenxue.com,该路由将被使用
@app.route('/get', methods=['GET'])
async def get_handler(request):
    return text('GET request in default - {}'.format(request.args))

当然也有简短的请求方法装饰器:

@app.post('/post')
async def post_handler(request):
    return text('POST request - {}'.format(request.json))

@app.get('/get')
async def get_handler(request):
    return text('GET request - {}'.format(request.args))

方法: app.add_route()

通常使用 @app.route 装饰器来定义路由。其实,,这个装饰器是对 app.add_route 的包装,它的使用方法如下:

from sanic.response import text

# Define the handler functions
async def handler1(request):
    return text('OK')

async def handler2(request, name):
    return text('Folder - {}'.format(name))

async def person_handler2(request, name):
    return text('Person - {}'.format(name))

# Add each handler function as a route
app.add_route(handler1, '/test')
app.add_route(handler2, '/folder/<name>')
app.add_route(person_handler2, '/person/<name:[A-z]>', methods=['GET'])

文章来源互联网,如有侵权,请联系管理员删除。邮箱:417803890@qq.com / QQ:417803890

微配音

Python Free

邮箱:417803890@qq.com
QQ:417803890

皖ICP备19001818号-4
© 2019 copyright www.pythonf.cn - All rights reserved

微信扫一扫关注公众号:

联系方式

Python Free