Flask - 環境變量與配置
目標
- 使用
python-dotenv
管理環境變量 - 配置開發、測試和生產環境
- 確保敏感信息(如數據庫 URI)不硬編碼
步驟
準備環境
- 繼續使用
flask_api/
項目結構,激活虛擬環境:1 2
# Windows: flask_api_env\Scripts\activate # macOS/Linux: source flask_api_env/bin/activate
- 安裝
python-dotenv
:1
pip install python-dotenv
- 繼續使用
創建環境變量文件
- 在項目根目錄下創建
.env
文件,存放敏感信息:1 2 3 4
# flask_api/.env FLASK_ENV=development SECRET_KEY=your-secret-key-here DATABASE_URL=sqlite:///todos.db
- 注意:
.env
不應提交到版本控制(後續會添加到.gitignore
)。
- 在項目根目錄下創建
更新配置
修改 app/config.py,支持多環境配置並從環境變量載入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
import os from dotenv import load_dotenv # 載入 .env 文件 load_dotenv() class Config: """基礎配置""" SECRET_KEY = os.getenv('SECRET_KEY', 'default-secret-key') SQLALCHEMY_TRACK_MODIFICATIONS = False class DevelopmentConfig(Config): """開發環境""" DEBUG = True SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL', 'sqlite:///todos_dev.db') class TestingConfig(Config): """測試環境""" TESTING = True SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL', 'sqlite:///todos_test.db') WTF_CSRF_ENABLED = False # 禁用 CSRF(測試用) class ProductionConfig(Config): """生產環境""" DEBUG = False SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL', 'sqlite:///todos_prod.db') # 環境映射 config_map = { 'development': DevelopmentConfig, 'testing': TestingConfig, 'production': ProductionConfig }
代碼解釋:
load_dotenv()
:從.env
載入環境變量。os.getenv()
:獲取環境變量,若無則使用默認值。- 三個配置類對應不同環境。
更新應用初始化
修改 app/init.py,根據環境變量選擇配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
from flask import Flask, jsonify from flask_sqlalchemy import SQLAlchemy from flask_marshmallow import Marshmallow from .routes.v1.todos import todos_bp as todos_v1_bp from .routes.v1.users import users_bp as users_v1_bp from .routes.v2.todos import todos_bp as todos_v2_bp from .config import config_map db = SQLAlchemy() ma = Marshmallow() def create_app(): app = Flask(__name__) # 根據 FLASK_ENV 選擇配置,默認為 development env = os.getenv('FLASK_ENV', 'development') app.config.from_object(config_map[env]) db.init_app(app) ma.init_app(app) app.register_blueprint(todos_v1_bp, url_prefix='/api/v1') app.register_blueprint(users_v1_bp, url_prefix='/api/v1') app.register_blueprint(todos_v2_bp, url_prefix='/api/v2') @app.errorhandler(404) def not_found(error): return jsonify({'error': 'Not Found', 'message': str(error)}), 404 @app.errorhandler(400) def bad_request(error): return jsonify({'error': 'Bad Request', 'message': str(error)}), 400 @app.errorhandler(500) def internal_error(error): return jsonify({'error': 'Internal Server Error', 'message': 'Something went wrong on our end'}), 500 with app.app_context(): db.create_all() return app
更新啟動腳本
修改 run.py,支持環境變量啟動:
1 2 3 4 5 6
from app import create_app app = create_app() if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) # 可選:允許外部訪問
測試不同環境
- 開發環境:
- 確保
.env
中FLASK_ENV=development
,運行:1
python run.py
- 檢查數據庫文件是否為
todos_dev.db
。
- 確保
- 生產環境:
- 修改
.env
為FLASK_ENV=production
,或在命令行設置:1 2 3
export FLASK_ENV=production # macOS/Linux set FLASK_ENV=production # Windows python run.py
- 確認
DEBUG=False
,數據庫為todos_prod.db
。
- 修改
- 測試環境:
- 設置
FLASK_ENV=testing
,運行並檢查todos_test.db
。
- 設置
- 開發環境:
保護敏感信息
- 創建或更新
.gitignore
,確保.env
不被提交:1 2 3 4 5
# flask_api/.gitignore *.db .env __pycache__/ *.pyc
- 創建或更新
作業
- 在
.env
中添加一個自定義變量(例如API_VERSION
),並在應用中顯示當前版本(提示:可在路由中返回)。 - 測試在沒有
.env
文件時,應用是否仍能使用默認配置運行。
- 在
測試 API
- POST /api/v1/users:
- Body:
{"username": "alice"}
- 確認數據存入正確的數據庫文件。
- Body:
- GET /api/v2/todos:
- 確保功能正常,且環境切換不影響行為。
注意事項
- 環境變量優先級:命令行 >
.env
> 代碼默認值。 - 生產環境應使用更安全的數據庫(如 PostgreSQL),這裡僅用 SQLite 示範。
本文章以 CC BY 4.0 授權