當前位置:成語大全網 - 新華字典 - 從Flask到FastApi

從Flask到FastApi

上次我們已經拿到了FastApi體驗卡,並且搭建了壹個demo服務。說好的要開始學 FastApi ,那怎麽能從入門到放棄呢?

所以我稍稍看了壹下文檔,理了壹下他裏面的門路。所以這篇文章可以算是私貨吧,由官方文檔加上個人理解組成。我打算先完善比較重要的功能,剩下的到用到的時候再 切換 就行了。

為了方便大家能從Flask無縫切換到 FastApi ,我也經過壹定的實踐,結合自己的項目特意編寫了這篇文章,可能有些地方沒有考慮到,希望大家見諒。文章有點點長,可以不用壹口氣看完~留著後面啃也可以!

我們之前會給Flask的 app (pity)初始化壹個配置:

其實配置 還有 壹種用法,就是直接引入Config類,利用Config.字段去獲取配置項,所以我們在原項目裏面取配置的方法都要修改。

Flask 支持跨域 很簡單,引入CORS,將app套進去即可。

其實FastApi也不難,其中官網就有對應的例子:

通過引入FastApi自己封裝好的CORSMiddleware,即可達到壹樣的效果。

因為按照我們上壹篇的內容,我們通過 uvicorn 啟動了FastApi服務,但是由於我們是在終端(Terminal)運行的,所以其實打的 斷點 是無法起作用的,所以我們需要通過運行main.py來達到調試的目的,官網也有類似的教程。

首先導入uvicorn庫,然後通過uvicorn.run來運行對應的 app ,我經常提到的app,其實是壹個FastApi的實例的概念。雖然我給他取名叫 pity ,但是我有時候也會叫他 app ,希望不要給大家帶來困擾。

註意,我這邊run方法接受了4個參數,host和port就不多說了,dddd。

reload呢,就是熱更新的意思。

至於app='main:pity',main代表的是這個文件的名字: main.py,pity也就是app的名字。 main:pity 即代表當前要啟動的是main裏面的pity。

至於為什麽要這麽復雜,歸根結底還是這個 reload 參數,為了能熱更新,它需要這些信息,不然會報錯:

所以,都是被逼的。

其實這個不太屬於這塊內容,因為有的人甚至沒有用到這個模塊。

用sqlalchemy的同學可以跳過哦!

其實解決方法呢,就是換成sqlalchemy。所以我們需要按照sqlalchemy的格式去編寫ORM。

可以看到我這邊讀取鏈接URL,是通過Config來直接獲取的。

構造函數可不變,Use類繼承的對象就是models/ init .py裏面的Base類,需要註意的是: sqlalchemy需要 tablename 這樣壹個字段,所以我們需要給它加上, 它不會默認生成,不加就報錯 。其他地方基本上沒有差異。

以 註冊用戶 為例,改寫方法是去掉以前的 User.query.filter_by() ,改為 session.query(User).filter_by() ,其他的時候差距不大。

註意為什麽要用 with ,因為with執行完畢之後會自動調用 exit (),也就是會自動 關閉session 。

FastApi呢,和Pydantic進行了強強結合,雖然這壹塊我還摸得不是很清楚,不過我暫時可以用起來了。

先看下舊版本的, 人肉校驗器 :

新版本的話,等於說是把參數校驗和業務邏輯 解耦 了,參數校驗放到另外的地方去編寫,接口裏面只負責處理業務邏輯即可。

新版本接口:

壹切的核心都在於這個 UserDto

可以看到,我們為UserDto類指定了4個字段,因為都是 必填項 ,所以未加上默認值,如果我們需要email是 非必填 的,則要改成:

接著就是具體的校驗方法了,由於我們的校驗規則很簡單,所以對 所有字段 都是采取的壹個方法: field_not_empty

意思是字段不能為空字符串,否則拋出ParamsError,註意這個 ParamsError 是我自定義的錯誤類型,它繼承了ValueError。

但是這個字段呢,是pydantic幫忙校驗好的,所以我們需要添加這麽壹個方法:

這個方法是針對請求參數校驗失敗的處理,類似於壹個hook,只有請求參數校驗失敗了,才會走到這個步驟。雖然裏面錯誤信息多,但是我們只取第壹條錯誤信息,不然數據多了展示不方便。

接著我們定義了壹個錯誤字典,目前支持 missing , params (自己封裝的), not_allowed (參數類型不壹致)

這樣就完成了參數的校驗了!

在http請求裏,接口分類是很關鍵的事情,所以藍圖這塊我們不能跳過,我們粗略講壹下。其實flask裏面我們也只是用來給url分組,那我們這裏也完成壹樣的事情就好了。

APIRouter約等於Blueprint,創建壹個APIRouter實例,prefix即url的前綴。

編寫接口的時候從@app.route改為@router.post/get即可,變化不大。

由於我這裏只改造了user下的router,所以其他的未include進來。