python high-performance web framework Sanic learning -- url

This article is based on the official sanic documentation explanation and my own thoughts after reading it.

First of all what is sanic?

sanic is a web framework written in python3.5+. It has the following features:

1. Flask-like syntax style, easy to learn

2. Lightweight

3. Based on python3.5 async/await and uvloop, its performance is very good

4. Support websocket

…………

Features are not BB first.

Let's cut to the chase and first build a simple http application

from sanic import Sanic
from sanic.response import text

app = Sanic()

@app.route("/")
async def test(request):
    return text("hello world")

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

Is not it simple!

First we import the Sanic class of the sanic library and the text method in the sanic.response class

Then write our url address through the @app.route decorator

Then we wrote a test api, this method defines a string that returns a hello world when someone visits

Note the async keyword

Friends who play py3.5 must be familiar with it, right? Yes, this interface is an asynchronous call.
As for the benefits of asynchronous calls, I will not repeat them here.

Then we open the browser, enter our host ip+8000 and we can see hello world

Of course, we can also bring the parameters we need in the url, for example:

from sanic.response import text

@app.route('/tag/<tag>')
async def tag_handler(request, tag):
    return text('Tag - %s'%tag)

We add the <> tag after the original url to represent the parameters that need to be passed in the url. At this time, when we visit ip/tag/1, the browser will display the words Tag -1.

If I just want to pass the data of type int in the previous instance, is there any convenient way? The answer is yes, let's slightly modify the code to become the following:

@app.route('/tag/<tag:int>')
async def tag_handler(request, tag):
    return text('Tag - %s'%tag)

Yes, I just added a :int to complete this function. And when the passed parameter is not of int type, the page will automatically jump to the 404 page. Isn't it great! This eliminates the need to judge constraints in methods.

Of course, we can also do other restrictions, such as using regular expressions to restrict the parameters to be letters.

@app.route('/tag/<tag:[A-z]+>')
async def tag_handler(request, tag):
    return text('Tag - %s'%tag)

So far we are all based on get operation requests, so what if I use POST to submit data? This one is also very simple. Just add methods=['POST'] to the @app.route decorator.
Such as the following code:

@app.route('/tag/<tag:int>', methods=['POST'])
async def tag_handler(request, tag):
    return text('Tag - %s'%tag)

Sometimes I don't want to write a url decorator on every method, so what should I do? Then we can write:

async def tag_handler(request, tag):
    return text('Tag - %s'%tag)

app.add_route(tag_handler, '/tag')

ok then introduce a very interesting thing. url_for

It can generate url according to the processing method of api.

@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))

When I visit / homepage, it will automatically jump to /post and also automatically carry the parameter of post_id=5 in the url

Finally, when I visit / Home page, I get Post-5 data information.

Of course, it has a lot of parameter types. The following code shows the format changes of different types of parameters.

url = app.url_for('post_handler', post_id=5, arg_one='one', _anchor='anchor')
# /posts/5?arg_one=one#anchor

url = app.url_for('post_handler', post_id=5, arg_one='one', _external=True)
# //server/posts/5?arg_one=one
# _external requires passed argument _server or SERVER_NAME in app.config or url will be same as no _external

url = 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 one time
url = 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

Finally, the routing method of websocket is introduced

@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)

Is it also very simple?

Similarly we can also useapp.add_websocket_route(feed, '/feed')

to write using url rules that are not based on decorators.

In the next section, I will share how sanic receives data after processing and returns the data.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325896822&siteId=291194637