FastAPI 工程管理(二) 工程設置


作者:麥克煎蛋   出處: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()

 


免責聲明!

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



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