跳到主要内容

读取应用配置

前言

应用配置一般写在外部文件或环境变量中,大型系统可能还会写到专门的配置中心。FastAPI 官方推荐通过环境变量读取配置,使用 Pydantic 解析并校验(pydantic-settings,见下文)。也可以根据实际情况选择 YAML 等文件方案。

FastAPI 构造参数

OpenAPI 元信息

可以自定义 Swagger 标题、描述、版本、联系方式、服务器地址等:

from fastapi import FastAPI

app = FastAPI(
title="FastAPI笔记",
description="FastAPI笔记之 helloworld",
version="0.0.1",
contact={
"name": "Rainux",
"url": "https://rainux.cn",
"email": "heruos@qq.com",
},
servers=[ # 请求 API 使用的 host 地址
{"url": "http://127.0.0.1:8000", "description": "Local Development"},
],
)

关闭 OpenAPI

生产环境开启 OpenAPI 会有安全隐患(暴露接口结构),如果没有身份认证、IP 白名单等措施,建议直接关闭:

app = FastAPI(
docs_url=None,
redoc_url=None,
openapi_url=None, # 直接关掉 openapi_url 即可,docs/redoc 也会随之禁用
)
提示

关闭 openapi_url/docs/redoc 会自动禁用,一般只需设置 docs_url=None

开启 debug 模式

debug 模式用于本地开发调试,生产环境慎开。如果定义了全局异常处理,debug 模式可能让全局异常处理失效:

app = FastAPI(debug=True)

基于文件的配置:YAML

安装依赖:

python -m pip install pyyaml

YAML 配置示例(conf/app.yaml):

database:
mysql:
host: "127.0.0.1"
port: 3306
user: "root"
password: "123456"
dbname: "test"
redis:
host:
- "192.168.0.10"
- "192.168.0.11"
port: 6379
password: "123456"
db: "5"

log:
directory: "logs"
level: "debug"
maxsize: 100
maxage: 30
maxbackups: 30
compress: true

读取代码:

import os

import yaml


def read_yaml(filename: str = "conf/app.yaml"):
if not os.path.exists(filename):
raise FileNotFoundError(f"File {filename} not found")
with open(filename, "r", encoding="utf-8") as f:
return yaml.safe_load(f.read())


if __name__ == "__main__":
config = read_yaml("conf/app.yaml")
print(type(config))
print(config)

输出结果:

<class 'dict'>
{'database': {'mysql': {'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': '123456', 'dbname': 'test'}, 'redis': {'host': ['192.168.0.10', '192.168.0.11'], 'port': 6379, 'password': '123456', 'db': '5'}}, 'log': {'directory': 'logs', 'level': 'debug', 'maxsize': 100, 'maxage': 30, 'maxbackups': 30, 'compress': True}}

基于 pydantic-settings 和环境变量

pydantic v2 起 BaseSettings 被拆分到独立的 pydantic-settings 包,旧版本则在 pydantic 中。

安装依赖:

python -m pip install pydantic-settings python-dotenv

编辑 .env 文件:

TITLE="My FastAPI App"
DESCRIPTION="This is a FastAPI app"
VERSION="0.0.1"
DEBUG=false

pkg/config.py

from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
# 字段名与 .env 中的变量名一致;也可以通过 alias 显式映射
title: str = Field(default="My FastAPI App", description="应用标题")
description: str = ""
version: str = "0.0.1"
debug: bool = False

model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
case_sensitive=True, # 是否区分环境变量大小写
)

@field_validator("title")
@classmethod
def title_must_be_set(cls, v: str) -> str:
if not v or not v.strip():
raise ValueError("title must be set")
return v.strip()


settings = Settings()

main.py 中使用:

from fastapi import FastAPI

from pkg.config import settings

app = FastAPI(
title=settings.title,
description=settings.description,
version=settings.version,
docs_url=None,
debug=settings.debug,
)
备注

写法对照:pydantic v1 使用 class Config: env_file = ".env"validator,已废弃;v2 使用 model_config = SettingsConfigDict(...)field_validator