路由的意思就是,让开发者为不同的URL路径指定不同的处理函数,这些处理函数的输入就是我们前面讲到的Sanic请求数据,而输出就是Sanic的响应类的实例。这样我们的web服务器端就能对不同的URL访问路径实现不同的逻辑和功能。比如根路径"/"
的处理函数,登录路径"/login"
的处理函数等等。
路由基本形式
前面的实例中,我们已经见过路由的基本形式,就是下面这样,通过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'])

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。
***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***
说点什么吧...