python 非同步Web框架sanic
阿新 • • 發佈:2020-04-27
我們繼續學習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