作者:麥克煎蛋 出處:https://www.cnblogs.com/mazhiyong/ 轉載請保留這段聲明,謝謝!
在許多情況下,我們的應用都需要一些外部的配置項,比如加密密鑰、數據庫賬號、郵件服務等等。
大部分這些設置項都是可變變量,比如數據庫地址等,因此通常情況下可以通過環境變量來提供這些設置項。
一、通過環境變量使用設置
1、直接使用環境變量
我們可以在終端里直接創建和使用環境變量。
➜ ~ export MY_NAME="Mike" ➜ ~ echo $MY_NAME Mike ➜ ~ echo "Hello $MY_NAME" Hello Mike
2、在Python中使用環境變量
我們可以在Python中直接使用環境變量。
➜ ~ python Python 2.7.15 (default, Jul 23 2018, 21:27:06) [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> name = os.getenv("MY_NAME", "World") >>> print("Hello %s from Python" % name) Hello Mike from Python
os.getenv()的第二個參數是缺省返回值。
我們也可以在Python文件(這里命名為main.py)中直接使用環境變量:
import os name = os.getenv("MY_NAME", "World") print("Hello %s from Python" % name)
然后在終端中調用Python文件:
➜ export MY_NAME="Mike" ➜ python main.py Hello Mike from Python ➜ export MY_NAME="Beijing" ➜ python main.py Hello Beijing from Python
以上聲明的變量對所有應用可見。我們也可以創建僅對特定應用可見的環境變量,並且僅存在於特定應用的運行期。
我們只需要在調用應用的時候聲明變量即可。
➜ MY_NAME="Jack" python main.py Hello Jack from Python ➜ python main.py Hello World from Python
二、Pydantic設置
Pydantic提供了強有力的工具來處理來自環境變量的設置項。
1、創建Settings對象
通過從Pydantic導入BaseSettings基類,然后創建這個基類的子類(如Settings),Pydantic就會讀取環境變量到這個子類的屬性中。
與Pydantic模型類似,我們可以在這個子類中聲明帶類型注解的屬性,同時也支持設置屬性的默認值。
我們可以利用與Pydantic模型同樣的數據校驗特性和通過Field()實現的其他校驗。
from pydantic import BaseSettings class Settings(BaseSettings): app_name: str = "Awesome API" admin_email: str items_per_user: int = 50 settings = Settings()
Pydantic讀取環境變量的時候是大小寫不敏感的,因此環境變量 APP_NAME 會被讀寫成屬性 app_name。
2、使用Settings對象
我們可以在應用中直接使用settings對象。
from fastapi import FastAPI
app = FastAPI() @app.get("/info") async def info(): return { "app_name": settings.app_name, "admin_email": settings.admin_email, "items_per_user": settings.items_per_user, }
我們可以在終端中運行並測試:
➜ ADMIN_EMAIL="test@qq.com" APP_NAME="settings" uvicorn settings:app --reload INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [7771] INFO: Started server process [7779] INFO: Waiting for application startup. INFO: Application startup complete.
頁面訪問結果:

3、在獨立模塊中保存Settings
我們可以在獨立的模塊文件中保存Settings,這里我們在config.py中保存。
from pydantic import BaseSettings class Settings(BaseSettings): app_name: str = "Awesome API" admin_email: str items_per_user: int = 50 settings = Settings()
然后我們在另一個文件中調用:
from fastapi import FastAPI from . import config app = FastAPI() @app.get("/info") async def info(): return { "app_name": config.settings.app_name, "admin_email": config.settings.admin_email, "items_per_user": config.settings.items_per_user, }
4、在依賴項中使用Settings
配置文件(config.py):
from pydantic import BaseSettings class Settings(BaseSettings): app_name: str = "Awesome API" admin_email: str items_per_user: int = 50
注意這里我們並沒有創建缺省的實例對象 settings = Settings()。
調用文件:
from functools import lru_cache from fastapi import Depends, FastAPI from . import config app = FastAPI() @lru_cache() def get_settings(): return config.Settings() @app.get("/info") async def info(settings: config.Settings = Depends(get_settings)): return { "app_name": settings.app_name, "admin_email": settings.admin_email, "items_per_user": settings.items_per_user, }
三、從.env文件中讀取設置
1、.env文件
ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp"
2、讀取.env文件
Pydantic需要安裝以下組件支持對.env文件的讀取。
pip install python-dotenv
同時我們需要更新配置文件(config.py):
from pydantic import BaseSettings class Settings(BaseSettings): app_name: str = "Awesome API" admin_email: str items_per_user: int = 50 class Config:
這里的env_file指定了我們所用的文件名稱。
Config類用來實現對Pydantic的配置,詳細信息可以參考 Pydantic Model Config
四、通過lru_cache優化讀取設置
讀取文件一般都會有所耗時,但每次我們執行
config.Settings()
都會創建一個新的Settings對象,並且會重新讀取硬盤文件。
但通過使用裝飾器@lru_cache(),Settings對象就只會在第一次訪問的時候創建一次,以后的訪問會直接返回已創建的對象。
@lru_cache() def get_settings(): return config.Settings()
如果函數的參數不同,則會重新創建新的對象。關於@lru_cache()的更多信息,可以參考Python docs for @lru_cache()
