1. 程式人生 > >python 非同步Web框架sanic

python 非同步Web框架sanic

我們繼續學習Python非同步程式設計,這裡將介紹非同步Web框架sanic,為什麼不是tornado?從框架的易用性來說,Flask要遠遠比tornado簡單,可惜flask不支援非同步,而sanic就是類似Flask語法的非同步框架。 github:https://github.com/huge-success/sanic 不過sanic對環境有要求: * macOS/linux * python 3.6+ > 不過,我在macOS上安裝 sanic 還是踩了坑。依賴庫`ujson`一直安裝失敗。最後不得不解除安裝官方python,安裝 miniconda(第三方Python安裝包,集成了一些額外的工具)。 安裝 sanic ```shell > pip3 install sanic ``` ## sanic 開發第一個例子 編寫官方的第一個例子`hello.py`: ```py 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/` ![](https://img2020.cnblogs.com/blog/311516/202004/311516-20200426233424199-1823572962.png) ## 請求堵塞 針對上面的例子,假設`test()` 檢視函式的處理需要5秒鐘,那麼請求就堵塞了。 ```py …… from time import sleep app = Sanic(name="pyapp") @app.route('/') async def test(request): sleep(5) return json({'hello': 'world'}) …… ```` 重啟服務,通過瀏覽器傳送請求,我們發現請求耗時5秒,這顯然對使用者就不能忍受的。 ![](https://img2020.cnblogs.com/blog/311516/202004/311516-20200426233507541-170828431.png) ## 非同步非堵塞 所以,我們要實現非同步呼叫,修改後的完整程式碼如下: ```py 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非同步的使用參考上一篇文章,重新啟動服務。這次前端就不在堵塞了。 ![](https://img2020.cnblogs.com/blog/311516/202004/311516-20200426233521445-112558328.png) 如果看 sanic 的執行日誌: ```shell [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()`檢視函式的響應。 > 思考:假如我的需求是:請求之後先告訴我已經處理了,然後默默的去處理,什麼時候處理來再主動把處理的結果告訴。那麼這就需要用到 websocke