Sanic 路由

Sanic教程 2019-03-25 22:40:45 阅读(17300) 评论(0)

路由的意思就是,让开发者为不同的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时的默认类型
  • 任何形式的正则表达式

其实,:typetype就是通过正则表达式匹配的,具体可以看Sanic源码中的router.pyREGEX_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'])

猿人学banner宣传图

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。

***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***

说点什么吧...