1. 程式人生 > >python高效能web框架Sanic學習--url

python高效能web框架Sanic學習--url

本文基於sanic 官方文件解釋及自己閱讀後的感想.

首先什麼是sanic?

sanic是一款用python3.5+寫的web framework。它有一下幾個特點:

1.flask-like的語法風格,簡單易學

2.輕量

3.基於python3.5 async/await 及uvloop 它的效能非常好

4.支援websocket

…………

特性先不BB了。

讓我們切入正題, 首先建立一個簡單的http應用

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)

是不是很簡單!

首先我們匯入sanic庫的Sanic類以及sanic.response類中的text方法

接著通過@app.route裝飾器編寫我們的url地址

然後我們寫了一個test的api,這個方法定義了當有人訪問時返回一個hello world的字串

注意async關鍵字

玩py3.5的小夥伴肯定很熟悉了吧?沒錯這個介面是非同步呼叫。
至於非同步呼叫的好處 我這裡也就不再累述了。

接著我們開啟瀏覽器,輸入我們的主機ip+8000 我們就能看到hello world了

當然我們也可以在url中帶入我們需要的引數,例如:

from sanic.response import text

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

我們在原始url後面新增<>標記代表需要額外再url中傳遞的引數。這時當我們訪問ip/tag/1 的時候,瀏覽器會顯示出 Tag -1 的字樣。

如果剛才的例項我只想讓int型別的資料傳遞進來,有什麼方便的方法嗎? 答案是肯定的,我們把才的程式碼稍加修改一下,變成下面這樣:

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

沒錯 我只是加了個:int 就完成了這個功能。並且當傳參不是int型別時頁面將自動跳轉到404頁面。是不是很棒呢!這樣再也不需要在方法中去判斷限制了。

當然了我們還可以做其他的限制,比如用正則表示式限制該傳參必須是字母。

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

到現在為止我們都是基於get的操作請求,那我要用POST提交資料呢?這個也很簡單。只要在@app.route 裝飾器中新增 methods=[‘POST’]就可以了。
如以下程式碼:

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

有時候不想在每個方法上都寫一個url裝飾器,那怎麼辦?那我們可以這樣寫:

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

app.add_route(tag_handler, '/tag')

ok接下來介紹一個很有趣的東西. url_for

它能根據api的處理方法生成url。

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

當我訪問/ 首頁時 會自動跳轉到/post 還會自動在url中攜帶post_id=5的引數

最後我訪問/ 首頁時 獲得是 Post - 5 的資料資訊。

當然它擁有很多的傳參型別 下面的程式碼展示的就是不同型別下傳參的格式變化

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

最後介紹下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(feed, '/feed')

來使用不基於裝飾器的url規則編寫。

下一節,我將分享sanic如何接收資料處理後並返回資料。