FastApi 進階


前言

終於有了第一個使用 FastApi 編寫的線上服務, 在開發的過程中還是遇到了些問題, 這里記錄一下

正文

目錄結構

我們知道, FastApi 的啟動方式推薦使用 uvicorn, 其啟動方式大致為 uvicorn main:app, 實際上 main 為該文件的名字, app 為生成的 FastApi 對象, 那么, 對於一個比較大的項目, 我們應該怎樣去布局項目呢? 我們參考了 https://github.com/nsidnev/fastapi-realworld-example-app 他是在名為 app 的文件夾中的 main.py 文件存放最大的 app, 在 該文件夾下存放各種邏輯文件, 例如: 基礎的數據庫相關放在 db 文件夾中, 公共的邏輯放在 core 文件夾中, 接口相關放在 api 文件夾中等等...

因為 app 已經放置在app文件夾中的 main.py 文件中, 啟動時則是在根目錄輸入 uvicorn app.main:app

main.py

多級路由處理

類似於 Flask 的藍圖, FastApi 有更為簡單的寫法

這里以我們的項目為例, 我們有多層, 最頂級的 app 在 app 文件夾的 main.py 中, files 相關的 api 在 app > api > routers > files > api.py

我們從最里層的 api.py 看起, 最里層的 app > api > routers > files > api.py 大致是這樣的

在 FastApi 中, 多層路由的每一層都可以設置生成一個 APIRouter 對象

我們再看上一層, 也就是 app > api > routers > api.py

這個 api.py 作為 routers 的整個的 router, 同樣生成了 APIRouter 對象, 但是該對象因為並不是最下層的路由, 所以導入下層路由的 router 通過 router.include_router 注冊到這個上層路由中, prefix 是路由前綴

我們再看 app > main.py

在最外層, 我們就生成了需要使用 uvicorn 啟動的 app 對象, app 對象可以直接使用 include_router 注冊路由, 那么其實結構是 最底層的 router 直接面向邏輯, 而外層的一層都通過 include_router 注冊他, 同時在注冊時可以設置前綴等操作

啟動與結束事件

有時候, 我們希望在服務啟動時進行一些操作, 比如初始化數據庫連接池等操作, 原來我們可能是直接寫在生成 app 的時候, 而在服務關閉時關閉連接池則需要費些心思, FastApi提供了事件, 我們注冊到某個事件后其在指定的時候執行我們注冊的功能, 還拿 main.py 舉例

add_event_handler 代表添加事件, 參數1為事件的名字, 默認的有一些, 比如 startup, 參數二則是傳入我們自寫的函數邏輯, 注意接收一個參數為 app 對象

webSocket狀態捕捉

FastApi 同樣支持 webSocket, 其官方給的例子類似

其實這種如果客戶端主動斷開的話, 因服務端是 while 1 , 還在嘗試從一個已經關閉的wb里獲取數據, 所以會報錯, 體現在接口里就是500, 所以我們需要捕捉此異常

依賴注入

我們知道, 在 Flask 中有一個 g 對象, 他穿插在 Flask 的生命周期中, 我們可以給某些接口使用裝飾器來做一些通用的操作, 然后將數據依附在 g 中傳遞給具體的邏輯中方便使用, 那么在 FastApi 中也可以做到, 例如

我們在接收參數時, 可以指定某個參數是由 Depends 傳出, 這便意味着這個參數不是由請求傳遞的, 而是由我們指定的邏輯生成后傳入的, 比如上面的代碼, 我們接受參數 fs, 這個參數 fs 是 Depends 生成的, 那么此參數就是這個接口的 依賴, 請求進入時會執行 Depends 包裹的函數, 也就是 get_bucket 函數, 此函數是我們自己寫的, 目的是將數據庫連接生成, 然后作為參數 fs 傳入具體邏輯, 在里面使用

后台任務

比如我們有一個接口, 這個接口需要向某個郵箱發送郵件, 因為發送郵件這個動作可能持續幾秒, 我們不能讓這個請求在這邊夯住直到發送完成, 我們希望理想的效果是: 接口立即返回任務提交成功,由后台發送郵件, FastApi 的 background tasks 可以幫我們做到

如上圖, 我們在接收參數時加上一個 BackgroundTasks 類型的參數, 這個參數並不是由請求傳遞, 當我們希望將某個邏輯放到背后去執行時, 只需要 .add_task 即可, 他接受多個參數, 參數1為要執行的函數名, 后面是該函數的參數, 既可以使用順序傳參也可使用關鍵字傳參

當我們注冊后, FastApi 只是將其加入了 BackgroundTasks 中, 並不會立即執行, 而是在這個請求響應后才執行, 也就是在 return 后


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM