• Sanic官翻-路由


    路由

    路由允许用户为不同的URL端点指定处理程序功能。

    基本路线如下所示,其中app是Sanic类的实例:

    from sanic.response import json
    
    @app.route("/")
    async def test(request):
        return json({ "hello": "world" })
    

    当访问URL http://server.url/(服务器的基本URL)时,路由器将最后一个/与处理程序函数test匹配,然后返回JSON对象。

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

    请求参数

    Sanic带有支持请求参数的基本路由器。

    要指定参数,请用诸如此类的斜杠引起来:<PARAM>。请求参数将作为关键字参数传递给路由处理程序函数。

    from sanic.response import text
    
    @app.route('/tag/<tag>')
    async def tag_handler(request, tag):
        return text('Tag - {}'.format(tag))
    

    要为参数指定类型,请在参数名称后的引号内添加:type。如果参数与指定的类型不匹配,Sanic将抛出NotFound异常,从而导致URL上出现404: Page not found error on the URL

    支持的类型

    • string
    "Bob"
    "python 3"
    
    • int
    10
    20
    30
    -10
    (No floats work here)
    
    • number
    1
    1.5
    10
    -10
    
    • alpha
    "Bob"
    "python"
    (If it contains a symbol or a non alphanumeric character it will fail)
    
    • path
    “hello”
    “hello.text”
    “hello world”
    
    • uuid
    123a123a-a12a-1a1a-a1a1-1a12a1a12345 (UUIDv4 Support)
    
    • 正则表达式

    如果未设置任何类型,则应为字符串。赋予函数的参数将始终是字符串,与类型无关。

    from sanic.response import text@app.route('/string/<string_arg:string>')async def string_handler(request, string_arg):    return text('String - {}'.format(string_arg))@app.route('/int/<integer_arg:int>')async def integer_handler(request, integer_arg):    return text('Integer - {}'.format(integer_arg))@app.route('/number/<number_arg:number>')async def number_handler(request, number_arg):    return text('Number - {}'.format(number_arg))@app.route('/alpha/<alpha_arg:alpha>')async def number_handler(request, alpha_arg):    return text('Alpha - {}'.format(alpha_arg))@app.route('/path/<path_arg:path>')async def number_handler(request, path_arg):    return text('Path - {}'.format(path_arg))@app.route('/uuid/<uuid_arg:uuid>')async def number_handler(request, uuid_arg):    return text('Uuid - {}'.format(uuid_arg))@app.route('/person/<name:[A-z]+>')async def person_handler(request, name):    return text('Person - {}'.format(name))@app.route('/folder/<folder_id:[A-z0-9]{0,4}>')async def folder_handler(request, folder_id):    return text('Folder - {}'.format(folder_id))
    

    警告

    str不是有效的类型标记。如果要str识别,则必须使用字符串

    HTTP请求类型

    默认情况下,URL上定义的路由仅可用于对该URL的GET请求。但是,@ app.route装饰器接受一个可选参数methods,它允许处理程序函数与列表中的任何HTTP方法一起使用。

    from sanic.response import text@app.route('/post', methods=['POST'])async def post_handler(request):    return text('POST request - {}'.format(request.json))@app.route('/get', methods=['GET'])async def get_handler(request):    return text('GET request - {}'.format(request.args))
    

    还有一个可选的host参数(可以是列表或字符串)。这限制了到提供的一个或多个主机的路由。如果还有一条没有主机的路由,它将是默认路由。

    @app.route('/get', methods=['GET'], host='example.com')async def get_handler(request):    return text('GET request - {}'.format(request.args))# if the host header doesn't match example.com, this route will be used@app.route('/get', methods=['GET'])async def get_handler(request):    return text('GET request in default - {}'.format(request.args))
    

    还有快捷方法修饰符

    from sanic.response import text@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))
    

    add_route方法

    如我们所见,路由通常使用@app.route装饰器指定。但是,此装饰器实际上只是app.add_route方法的包装,其用法如下

    from sanic.response import text# Define the handler functionsasync 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 routeapp.add_route(handler1, '/test')app.add_route(handler2, '/folder/<name>')app.add_route(person_handler2, '/person/<name:[A-z]>', methods=['GET'])
    

    使用url_for创建URL

    Sanic提供了url_for方法,用于根据处理程序方法名称生成URL。如果您要避免将url路径硬编码到应用程序中,这将很有用;相反,您可以仅引用处理程序名称。例如

    from sanic.response import redirect@app.route('/')async def index(request):    # generate a URL for the endpoint `post_handler`    url = app.url_for('post_handler', post_id=5)    # the URL is `/posts/5`, redirect to it    return redirect(url)@app.route('/posts/<post_id>')async def post_handler(request, post_id):    return text('Post - {}'.format(post_id))
    

    使用url_for时要记住的其他事项

    • 传递给url_for的关键字参数若不是请求参数的,将包含在URL的查询字符串中。
    url = app.url_for('post_handler', post_id=5, arg_one='one', arg_two='two')# /posts/5?arg_one=one&arg_two=two
    
    • 可以将多值参数传递给url_for
    url = app.url_for('post_handler', post_id=5, arg_one=['one', 'two'])# /posts/5?arg_one=one&arg_one=two
    
    • 另外,传递给url_for的某些特殊参数(_anchor, _external, _scheme, _method, _server)将具有特殊的url构建(现在不支持_method,将被忽略)。
    url = app.url_for('post_handler', post_id=5, arg_one='one', _anchor='anchor')# /posts/5?arg_one=one#anchorurl = app.url_for('post_handler', post_id=5, arg_one='one', _external=True)# //server/posts/5?arg_one=one# _external requires you to pass an argument _server or set SERVER_NAME in app.config if not url will be same as no _externalurl = app.url_for('post_handler', post_id=5, arg_one='one', _scheme='http', _external=True)# http://server/posts/5?arg_one=one# when specifying _scheme, _external must be True# you can pass all special arguments at onceurl = app.url_for('post_handler', post_id=5, arg_one=['one', 'two'], arg_two=2, _anchor='anchor', _scheme='http', _external=True, _server='another_server:8888')# http://another_server:8888/posts/5?arg_one=one&arg_one=two&arg_two=2#anchor
    
    • 必须将所有有效参数传递给url_for以构建URL。如果未提供参数,或者参数与指定的类型不匹配,则将引发URLBuildError

    WebScoket路由

    可以使用@app.websocket装饰器定义WebSocket协议的路由

    @app.websocket('/feed')async def feed(request, ws):    while True:        data = 'hello!'        print('Sending: ' + data)        await ws.send(data)        data = await ws.recv()        print('Received: ' + data)
    

    或者,可以使用app.add_websocket_route方法代替装饰器

    async def feed(request, ws):    passapp.add_websocket_route(my_websocket_handler, '/feed')
    

    调用请求的第一个参数调用WebSocket路由的处理程序,第二个参数调用WebSocket协议对象。协议对象具有send和recv方法,分别用于发送和接收数据。

    WebSocket支持需要Aymeric Augustin的 websockets软件包。

    关于strict_slashes

    您可以将路由设置为严格禁止尾随斜线,也可以对其进行配置。

    # provide default strict_slashes value for all routesapp = Sanic('test_route_strict_slash', strict_slashes=True)# you can also overwrite strict_slashes value for specific route@app.get('/get', strict_slashes=False)def handler(request):    return text('OK')# It also works for blueprintsbp = Blueprint('test_bp_strict_slash', strict_slashes=True)@bp.get('/bp/get', strict_slashes=False)def handler(request):    return text('OK')app.blueprint(bp)
    

    strict_slashes标志如何遵循已定义的层次结构的行为,该层次结构决定特定的路由是否属于strict_slashes行为。

    Route/├──Blueprint/	├──Application/
    

    上面的层次结构定义了strict_slashes标志的行为。以上述顺序找到的strict_slashes的第一个非None值将应用于有问题的路由。

    from sanic import Sanic, Blueprintfrom sanic.response import textapp = Sanic("sample_strict_slashes", strict_slashes=True)@app.get("/r1")def r1(request):    return text("strict_slashes is applicable from App level")@app.get("/r2", strict_slashes=False)def r2(request):    return text("strict_slashes is not applicable due to  False value set in route level")bp = Blueprint("bp", strict_slashes=False)@bp.get("/r3", strict_slashes=True)def r3(request):    return text("strict_slashes applicable from blueprint route level")bp1 = Blueprint("bp1", strict_slashes=True)@bp.get("/r4")def r3(request):    return text("strict_slashes applicable from blueprint level")
    

    自定义路由名字

    可以通过在注册路由时传递名称参数来使用自定义路由名称,该参数将覆盖使用handler.__ name__属性生成的默认路由名称。

    app = Sanic('test_named_route')@app.get('/get', name='get_handler')def handler(request):    return text('OK')# then you need use `app.url_for('get_handler')`# instead of # `app.url_for('handler')`# It also works for blueprintsbp = Blueprint('test_named_bp')@bp.get('/bp/get', name='get_handler')def handler(request):    return text('OK')app.blueprint(bp)# then you need use `app.url_for('test_named_bp.get_handler')`# instead of `app.url_for('test_named_bp.handler')`# different names can be used for same url with different methods@app.get('/test', name='route_test')def handler(request):    return text('OK')@app.post('/test', name='route_post')def handler2(request):    return text('OK POST')@app.put('/test', name='route_put')def handler3(request):    return text('OK PUT')# below url are the same, you can use any of them# '/test'app.url_for('route_test')# app.url_for('route_post')# app.url_for('route_put')# for same handler name with different methods# you need specify the name (it's url_for issue)@app.get('/get')def handler(request):    return text('OK')@app.post('/post', name='post_handler')def handler(request):    return text('OK')# then# app.url_for('handler') == '/get'# app.url_for('post_handler') == '/post'
    

    静态文件路由

    Sanic支持使用url_for方法构建静态文件url。如果静态url指向目录,则可以忽略url_for的filename参数。

    app = Sanic('test_static')app.static('/static', './static')app.static('/uploads', './uploads', name='uploads')app.static('/the_best.png', '/home/ubuntu/test.png', name='best_png')bp = Blueprint('bp', url_prefix='bp')bp.static('/static', './static')bp.static('/uploads', './uploads', name='uploads')bp.static('/the_best.png', '/home/ubuntu/test.png', name='best_png')app.blueprint(bp)# then build the urlapp.url_for('static', filename='file.txt') == '/static/file.txt'app.url_for('static', name='static', filename='file.txt') == '/static/file.txt'app.url_for('static', name='uploads', filename='file.txt') == '/uploads/file.txt'app.url_for('static', name='best_png') == '/the_best.png'# blueprint url buildingapp.url_for('static', name='bp.static', filename='file.txt') == '/bp/static/file.txt'app.url_for('static', name='bp.uploads', filename='file.txt') == '/bp/uploads/file.txt'app.url_for('static', name='bp.best_png') == '/bp/static/the_best.png'
    
  • 相关阅读:
    吴裕雄--天生自然 R语言开发学习:广义线性模型(续一)
    吴裕雄--天生自然 R语言开发学习:广义线性模型
    吴裕雄--天生自然 R语言开发学习:重抽样与自助法(续一)
    吴裕雄--天生自然 R语言开发学习:重抽样与自助法
    吴裕雄--天生自然 R语言开发学习:中级绘图(续二)
    吴裕雄--天生自然 R语言开发学习:中级绘图(续一)
    吴裕雄--天生自然 R语言开发学习:中级绘图
    吴裕雄--天生自然 R语言开发学习:功效分析(续一)
    吴裕雄--天生自然 R语言开发学习:功效分析
    吴裕雄--天生自然 R语言开发学习:方差分析(续二)
  • 原文地址:https://www.cnblogs.com/fhkankan/p/14763526.html
Copyright © 2020-2023  润新知