iT邦幫忙

2023 iThome 鐵人賽

DAY 20
0
Modern Web

FastAPI 入門30天系列 第 20

Day-20 SlowAPI 與 FastAPI

  • 分享至 

  • xImage
  •  

我們在實務上難免會遇到需要去限制端點的流量,那 FastAPI 本身並沒有提供這個功能,我們可以使用第三方套件來實作這件事。

而這次要介紹的是 SlowAPI 這個套件,名字剛好跟 FastAPI 相反,這個套件有以下幾個特色:

  • 一個端點可以套用一個或多個裝飾器來限制流量。
  • 可以使用 radis、memcached、或記憶體來追蹤流量限制。
  • 支援同步和非同步的端點。
  • 支援跨路由的流量限制。

安裝

pip install slowapi

我們直接用 pip 安裝到你的環境即可。

設定

安裝好之後,我們需要在程式碼中,將其載入到 FastAPI 的 app 物件中,所以我們可以直接修改在 main 中:

# main.py
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded

limiter = Limiter(key_func=get_remote_address)
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

這邊主要就是實體化一個 limiter,並將其指定給我們的 app.state.limiter,這樣 FastAPI 才知道用甚麼東西去限制流量。add_exception_handler 是告訴 FastAPI 說,發生 RateLimitExceeded 的錯誤時,要用哪個 handler 去處理。

使用

當我們設定好後我們就可以開始來使用這個限制器:

@app.get("/")
@limiter.limit("3/5 second")
def root(request: Request):
    """
    Root
    """
    return {"message": "Hello World"}

這裡有幾個點需要注意的:

  1. limiter 裝飾器需要放在 app 裝飾器下方。
  2. 聲明參數需要帶入一個 Request 物件。

有一個地方出錯便會導致 limiter 無法生效。

時間限制寫法

因為這個SlowAPI 的底層是 limit 這個套件,所以他的流量限制字串的解析方法也與 limit 相同:

[count] [per|/] [n (optional)] [second|minute|hour|day|month|year]

像是 5 秒 3 個流量你可以寫成 3/5 second 也可以寫成 3 per 5 second

成功畫面

https://ithelp.ithome.com.tw/upload/images/20230925/20152669aOe4fGjNze.png

我們在5秒內發了7次請求,可以看到只有前3次成功回傳,其他的請求都被拒絕,直到下一個循環開始才又能成功回傳。

https://ithelp.ithome.com.tw/upload/images/20230925/20152669qYfIVasqek.png

你也可以在 Response body 中看到詳細的錯誤訊息告訴你,這個端點只能允許5秒內有3個成功回應。

小結

今天只是提供一個解決方案,網路上也有其他更好的解法可以搭配 FastAPI,也不一定要把流量限制做在程式端,也可以做在伺服器層都可以。而對於 SlowAPI 想要了解更多進階應用可以看官方文件的範例講解,我們今天的介紹就到這邊。

參考資料

SlowApi Documentation

Quickstart - limits {3.5.0}


上一篇
Day-19 NoSQL 與 FastAPI
下一篇
Day-21 測試與FastAPI
系列文
FastAPI 入門30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言