趋近智
随着用于服务机器学习模型的FastAPI应用程序日趋完善,你会发现某些值不应直接硬编码到你的源文件中。模型路径、外部服务的API密钥、数据库连接字符串、日志级别以及其他特定于部署的参数,通常需要在开发、测试和生产环境之间变更,而无需修改代码。正确处理这些配置和敏感信息(常称为“秘密信息”)是构建可维护、灵活且安全的应用程序的根本。
将配置值直接硬编码到代码中会使其变得脆弱。想象一下需要更新重新训练的模型路径或更改数据库密码。你将不得不修改代码、重新测试并重新部署整个应用程序。此外,将API密钥或密码等敏感信息直接嵌入到源代码中并提交到Git等版本控制系统是一个重大的安全风险。本节将介绍在FastAPI中管理应用程序配置和秘密信息的常见且有效的方法。
通过环境变量为应用程序提供配置是一种广泛采用的标准做法。它们是在应用程序运行的操作系统环境中设置的键值对。大多数部署平台,包括Docker容器、PaaS提供商和传统服务器,都提供为应用程序进程设置环境变量的机制。
Python的标准库提供了 os 模块来访问环境变量:
import os
# 访问环境变量,如果未设置则提供默认值
model_path = os.environ.get("MODEL_PATH", "./models/default_model.joblib")
api_key = os.environ.get("EXTERNAL_API_KEY") # 如果未设置则返回 None
if api_key is None:
print("警告:EXTERNAL_API_KEY 环境变量未设置。")
# 妥善处理缺失项,可能抛出错误或禁用相关功能
print(f"使用的模型路径:{model_path}")
尽管直接,但仅依赖 os.environ.get 存在缺点。环境变量总是字符串,因此你需要手动进行类型转换(例如,对于端口号或布尔标志)和验证。随着配置参数数量的增加,单独管理它们可能会变得繁琐。
FastAPI 与 Pydantic 集成,Pydantic 通过其 BaseSettings 类提供了一项功能来管理应用程序设置。这种方法结合了环境变量的便利性与 Pydantic 模型的类型安全和验证能力。
首先,请确保你已安装 pydantic-settings,根据你的 Pydantic 版本可能需要此项(Pydantic v2 分离了此功能):
pip install pydantic-settings
现在,你可以定义一个设置类:
from pydantic_settings import BaseSettings, SettingsConfigDict
from typing import Optional
class AppSettings(BaseSettings):
# 使用类型提示定义你的配置变量
app_name: str = "ML 预测服务"
log_level: str = "INFO"
model_path: str
database_url: Optional[str] = None # 可选设置示例
external_api_key: str # 必需秘密信息示例
# Pydantic v2 配置(如果使用 pydantic-settings)
model_config = SettingsConfigDict(
# 如果存在 .env 文件,则从其中加载环境变量
# 需要安装 python-dotenv:pip install python-dotenv
env_file='.env',
env_file_encoding='utf-8',
# 使环境变量匹配不区分大小写
case_sensitive=False
)
# 实例化设置 - Pydantic 会自动从环境变量中读取
# 以及指定的 .env 文件
settings = AppSettings()
# 你现在可以安全地访问带类型提示的设置
print(f"应用程序名称: {settings.app_name}")
print(f"模型路径: {settings.model_path}")
print(f"API 密钥前几位: {settings.external_api_key[:4]}...") # 记录秘密信息时要小心!
Pydantic 的 BaseSettings 会自动尝试从环境变量中读取已定义字段的值。例如,它将寻找名为 MODEL_PATH 的环境变量(可以配置大小写不敏感)来填充 model_path 属性。如果指定并存在 .env 文件(对本地开发很有用),其中定义的变量也将被加载。Pydantic 会自动处理类型转换和验证。如果必需的变量(例如示例中的 model_path 或 external_api_key)在环境或 .env 文件中均未找到,Pydantic 在实例化时将引发验证错误,从而阻止应用程序在缺少配置的情况下启动。
你可以使用依赖注入将这些设置轻松集成到你的FastAPI应用程序中:
from fastapi import FastAPI, Depends
# 假设 AppSettings 已如上定义
settings = AppSettings()
app = FastAPI()
# 提供设置的依赖函数
def get_settings() -> AppSettings:
return settings
@app.get("/info")
async def info(current_settings: AppSettings = Depends(get_settings)):
return {
"app_name": current_settings.app_name,
"model_path": current_settings.model_path,
"log_level": current_settings.log_level
}
# 在应用程序其他部分的用法示例
def load_model(settings: AppSettings = Depends(get_settings)):
# 使用 settings.model_path 加载模型
print(f"从以下路径加载模型: {settings.model_path}")
# ... 加载逻辑 ...
pass
这种方法使你的配置集中化、经过验证且在整个应用程序中易于访问。
秘密信息是敏感的配置部分,例如API密钥、数据库密码或加密密钥。绝不要将秘密信息直接提交到你的版本控制系统(如 Git)。 即使仓库是私有的,这也是不良做法,并增加了意外泄露的风险。
使用环境变量(通过 Pydantic BaseSettings 或直接使用 os.environ 管理)是处理秘密信息的第一步。实际值在运行时注入到应用程序的环境中,使其不出现在代码库中。
对于本地开发,你可以使用 .env 文件来存储秘密信息,但请确保此 .env 文件已列在你的 .gitignore 文件中,以防止意外提交。
# .gitignore
.env
*.pyc
__pycache__/
在生产环境中,通过环境变量管理秘密信息是常见的做法,但更好的解决方案通常涉及专用的秘密管理系统。这些系统为秘密信息提供集中存储、访问控制、审计和轮换能力。示例包括:
这些工具通常在应用程序启动前将秘密信息注入到应用程序环境中(通常作为环境变量或挂载文件)。尽管实现这些系统超出了本节的范围,但随着你的部署需求变得更加复杂,了解它们是很重要的。其原则保持不变:将秘密信息与代码分离,并在运行时安全地注入它们。
配置和秘密信息在运行时流入 FastAPI 应用程序。
通过周密地管理配置和秘密信息,你可以创建在不同环境中更容易部署、更易于维护且更安全的应用程序。使用 Pydantic 的 BaseSettings 提供了一种便捷的方式来处理主要从环境变量加载的类型化配置,这与现代部署实践非常契合。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造