返回

Flask中YAML配置文件的标准引入方法

在Flask中引入config.yaml文件的标准做法,通过.env指定配置文件路径,支持环境变量替换和嵌套配置访问
2025-06-26
1914 字 · 约 5 分钟阅读

在实际开发中,Flask项目常需要灵活的配置管理,通过.env文件指定config.yaml路径,优势在于:

  • 支持环境变量替换,避免硬编码敏感信息
  • 支持多环境配置(开发、测试、生产),便于切换
  • 代码与配置分离,易于维护和部署

假设项目目录结构如下:

your-flask-app/
├── app.py
├── config/
│   ├── development.yaml
│   ├── production.yaml
│   └── testing.yaml
├── .env
├── .env.example
└── requirements.txt

构建一个 .env 文件来指定配置文件路径和其他环境变量:

FLASK_ENV=development
CONFIG_FILE=config/development.yaml
SECRET_KEY=your-secret-key
DATABASE_URL=sqlite:///app.db

同时,创建一个 config/development.yaml 文件作为示例配置:

app:
  name: "My Flask App"
  debug: true
  secret_key: "${SECRET_KEY}"

database:
  url: "${DATABASE_URL}"

实现Flask应用加载YAML配置文件的代码如下:

import os
import yaml
from flask import Flask
from dotenv import load_dotenv
import re

# 1. 加载.env文件
load_dotenv()

# 2. YAML配置加载类,支持环境变量替换
class Config:
    def __init__(self, config_file=None):
        self.config_file = config_file or os.getenv('CONFIG_FILE', 'config/development.yaml')
        self.config = self.load_config()
    
    def load_config(self):
        if not os.path.exists(self.config_file):
            raise FileNotFoundError(f"配置文件 {self.config_file} 不存在")
        with open(self.config_file, 'r', encoding='utf-8') as f:
            content = f.read()
            content = self.substitute_env_vars(content)
            return yaml.safe_load(content)
    
    def substitute_env_vars(self, content):
        def replace_env_var(match):
            var_name = match.group(1)
            return os.getenv(var_name, match.group(0))
        return re.sub(r'\$\{([^}]+)\}', replace_env_var, content)
    
    def get(self, key, default=None):
        keys = key.split('.')
        value = self.config
        for k in keys:
            if isinstance(value, dict) and k in value:
                value = value[k]
            else:
                return default
        return value

config = Config()

app = Flask(__name__)
app.config['SECRET_KEY'] = config.get('app.secret_key')
app.config['DEBUG'] = config.get('app.debug', False)

@app.route('/')
def home():
    return {
        'app_name': config.get('app.name'),
        'database_url': config.get('database.url'),
    }

if __name__ == '__main__':
    app.run(debug=app.config['DEBUG'])

通过这种方式可以轻松地管理不同环境下的配置,同时保持代码的整洁和可维护性

留言

发表留言