python 異步Web框架sanic

咱們繼續學習Python異步編程,這裏將介紹異步Web框架sanic,爲何不是tornado?從框架的易用性來講,Flask要遠遠比tornado簡單,惋惜flask不支持異步,而sanic就是相似Flask語法的異步框架。前端

github:https://github.com/huge-success/sanicpython

不過sanic對環境有要求:linux

  • macOS/linux
  • python 3.6+

不過,我在macOS上安裝 sanic 仍是踩了坑。依賴庫ujson一直安裝失敗。最後不得不卸載官方python,安裝 miniconda(第三方Python安裝包,集成了一些額外的工具)。git

安裝 sanicgithub

> pip3 install sanic

sanic 開發第一個例子

編寫官方的第一個例子hello.pyweb

from sanic import Sanic
from sanic.response import json
from sanic.exceptions import NotFound


app = Sanic(name="pyapp")

@app.route('/')
async def test(request):
    return json({'hello': 'world'})


if __name__ == '__main__':
    app.error_handler.add(
        NotFound,
        lambda r, e: sanic.response.empty(status=404)
    )
    app.run(host='0.0.0.0', port=8000)

運行上面的程序:shell

> python3 hello.py

[2020-04-21 23:12:02 +0800] [18487] [INFO] Goin Fast @ http://0.0.0.0:8000
[2020-04-21 23:12:02 +0800] [18487] [INFO] Starting worker [18487]

經過瀏覽器訪問:http://localhost:8000/編程

請求堵塞

針對上面的例子,假設test() 視圖函數的處理須要5秒鐘,那麼請求就堵塞了。json

……

from time import sleep

app = Sanic(name="pyapp")

@app.route('/')
async def test(request):
    sleep(5)
    return json({'hello': 'world'})

……

重啓服務,經過瀏覽器發送請求,咱們發現請求耗時5秒,這顯然對用戶就不能忍受的。flask

異步非堵塞

因此,咱們要實現異步調用,修改後的完整代碼以下:

import asyncio
from sanic import Sanic
from sanic.response import json
from sanic.exceptions import NotFound
from time import sleep, ctime

app = Sanic(name="pyapp")

async def task_sleep():
    print('sleep before', ctime())
    await asyncio.sleep(5)
    print('sleep after', ctime())


@app.route('/')
async def test(request):
    myLoop = request.app.loop
    myLoop.create_task(task_sleep())
    return json({'hello': 'world'})


if __name__ == '__main__':
    app.error_handler.add(
        NotFound,
        lambda r, e: sanic.response.empty(status=404)
    )
    app.run(host='0.0.0.0', port=8000)

關於python異步的使用參考上一篇文章,從新啓動服務。此次前端就不在堵塞了。

若是看 sanic 的運行日誌:

[2020-04-21 23:43:14 +0800] - (sanic.access)[INFO][127.0.0.1:57521]: GET http://localhost:8000/  200 17
sleep before Tue Apr 21 23:43:14 2020
sleep after Tue Apr 21 23:43:19 2020

他仍然在執行,但不會堵塞test()視圖函數的響應。

思考:假如個人需求是:請求以後先告訴我已經處理了,而後默默的去處理,何時處理來再主動把處理的結果告訴。那麼這就須要用到 websocket了。

相關文章
相關標籤/搜索