在 Sanic 端点​​中带有可选斜杠的正则表达式

Regex with optional slashes in Sanic endpoints

我想用 Sanic (https://github.com/huge-success/sanic) 做一个 API REST,但我受困于正则表达式。

我有这个端点:api/foo/<string_with_or_without_slashes>/bar/<string>/baz

我的python代码是:

from sanic import Sanic                                                                                                                                                                  
from sanic.response import json                                                                                                                                                          

app = Sanic()                                                                                                                                                                            

@app.route('/api/foo/<foo_id:[^/].*?>/baz')                                                                                                                                              
async def test1(request, foo_id):                                                                                                                                                        
    return json({'test1': foo_id})                                                                                                                                                       

@app.route('/api/foo/<foo_id:[^/].*?>/bar/<bar_id>/baz')                                                                                                                                 
async def test2(request, foo_id, bar_id):                                                                                                                                                 
    return json({'test2': f'{foo_id}:{bar_id}'})                                                                                                                                         

if __name__ == '__main__':                                                                                                                                                               
    app.run(host='0.0.0.0', port=8000)          

如果我这样做:

$ curl -i http://localhost:8000/api/foo/aa/bar/bb/baz
{"test1":"aa\/bar\/bb"} 

$ curl -i http://localhost:8000/api/foo/a/a/bar/bb/baz.

想调用test2函数时总是调用test1

你能帮帮我吗?非常感谢你! :)

两条路由都匹配您的测试请求,并且使用第一个匹配的路由(参见此issue on GitHub)执行test1

因为您的第一条路线比第二条路线更通用,您可以在 test1 之前定义 test2:

from sanic import Sanic
from sanic.response import json

app = Sanic()

@app.route('/api/foo/<foo_id:[^/].*?>/bar/<bar_id>/baz')
async def test2(request, foo_id, bar_id):
    return json({'test2': f'{foo_id}:{bar_id}'})

@app.route('/api/foo/<foo_id:[^/].*?>/baz')
async def test1(request, foo_id):
    return json({'test1': foo_id})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)