有一個非常簡單的需求:編寫一個 HTTP接口,使用 POST 方式發送一個 JSON 字符串,接口里面讀取發送上來的參數,對其中某個參數進行處理,並返回。
如果我們使用 Flask 來開發這個接口,那么代碼是這樣的:
代碼看起來已經很簡潔了。我們用requests
發個請求看看效果,如下圖所示:
看起來沒什么問題。
現在,我搞點破壞,把age
字段改成字符串,再運行一下:
不出所料,報錯了。
現在我們把age
字段改回數字,但是直接移除name
字段:
又報錯了。
為了防止用戶不按規矩提交數據,我們必需在接口里面做好各種異常數據的判斷。於是增加判斷以后的代碼變得復雜了:
看來,用 Flask,雖然能讓你用很短的代碼寫出一個能工作的項目。但要寫成一個可以正常使用的項目,還是需要你自己寫更多代碼。
下面我們來看一下,現代化的 web 框架:FaskApi
能把這個工程簡化到什么程度:
我們還是使用 requests 發一條信息給 FastApi 開發的 HTTP接口。對於正常數據,正常使用:
現在我們把age
字段改成字符串:
返回友好的提示信息,告訴我類型錯誤:age 字段不是 integer
。
我們再試一試把name
字段去掉:
返回友好信息,提示值錯誤:name字段丟失
。
整個過程中,對類型的檢查全都由 FastApi 自己完成。我們省下來很多時間。
我用了 Flask 四年,但在使用了5分鍾 FastApi 以后,我決定以后不再使用 Flask 了。
回過頭來,我們好好介紹一下 FastApi。
使用pip
或者pipenv
即可安裝 FastApi:
安裝完成以后,我們來完成第一個 API:
這里的寫法跟 Flask 幾乎一致。只不過在 Flask 中,我們定義路由的裝飾器為@app.route('/')
。而這里寫為@app.get('/')
如下圖所示:
寫好代碼以后,我們需要使用uvicorn
來運行 FastApi。首先使用pip
或者pipenv
安裝uvicorn
:
然后執行命令:
其中main
表示我們的代碼文件為main.py
,app
表示我們初始化的FastApi 對象的名字。--reload
參數表示在修改了代碼以后立即生效,不需要重啟。
運行命令以后,我們訪問http://127.0.0.1:8000
可以看到接口已經正確返回了 JSON 格式的數據:
那么如何定義一個帶參數的 GET 方法呢?我們再寫一段代碼:
寫好代碼以后,我們直接在瀏覽器里面訪問新的地址,可以看到修改已經生效了,如下圖所示:
如果想限定uid 只能是數字,不能是字符串怎么辦呢?你只需要多加4個字符
:
對函數query
的參數使用類型標注,標注為 int 類型。現在我們再來訪問一下接口:
當 query 后面的參數不是整數時,正常報錯了。
我們再來看一下本文一開始的 POST 方法。在使用 Flask 的時候,我們需要手動驗證用戶 POST 提交上來的數據是什么格式的,字段對不對。
但使用 FastApi 的時候,我們只需要類型標注就能解決所有問題。首先我們導入from pydantic import BaseModel
,然后繼承BaseModel
實現我們允許 POST 方法提交上來的數據字段和格式:
People
這個類通過類型標注,指定了它里面的4個字段和他們的類型。現在,我們來實現 POST 方法:
insert
函數的參數people
通過類型標注指定為People
類型。
當我們使用 POST 方式提交數據時,FastApi 自動會以People
中定義的字段為基准來校驗數據,發現不對就返回報錯信息。
除了開發接口變得非常簡單外,FastApi 還會自動幫我們生成接口文檔。大家訪問http://127.0.0.1:8000/docs
,可以看到接口文檔已經自動生成好了:
這個接口不僅能看,而且直接就能在接口頁面修改樣例數據,發送請求,現場測試:
以上是對 FastApi 的極簡介紹。有興趣的同學可以查閱它的官方文檔
最后,告訴大家,FastApi 是一個異步 Web 框架,它的速度非常非常非常快。遠遠超過 Flask。
FastApi 是最快的幾個 Web 框架之一。速度可以匹敵 Golang寫的接口。詳細的對比可以看:one of the fastest Python frameworks available