When developing Flask applications, we often need to handle different configuration requirements. For example:
- Debug mode (DEBUG=True) should be enabled in development environments but disabled in production.
- Use SQLite for development but switch to MySQL or PostgreSQL in production.
- Sensitive information like keys (SECRET_KEY) and database passwords should not be hardcoded for security.
In such cases, configuration files and environment variables help manage configurations effectively, making code more flexible and secure.
一、Configuration Files: Centralize Non-Sensitive Configurations¶
1. Create a Configuration File¶
The most common approach is to create a Python file (e.g., config.py) to define configurations for different environments. Use classes to distinguish configurations for each environment:
# config.py
import os
class BaseConfig:
"""Base configuration (common to all environments)"""
SECRET_KEY = 'dev' # Temporary key for development (replace in production with environment variables)
DEBUG = False
SQLALCHEMY_DATABASE_URI = 'sqlite:///dev.db' # Default local database path
class DevelopmentConfig(BaseConfig):
"""Development environment configuration"""
DEBUG = True # Enable debug mode
# Simplified database config for development
class ProductionConfig(BaseConfig):
"""Production environment configuration"""
DEBUG = False # Disable debug mode
# Example: Use PostgreSQL in production (ensure database connection is correct)
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'postgresql://user:pass@localhost/prod.db'
2. Load Configuration in Flask App¶
In your main application file (e.g., app.py), load the appropriate configuration class using from_object:
# app.py
from flask import Flask
from config import DevelopmentConfig, ProductionConfig, BaseConfig
import os
# Select configuration based on environment variable (default to development)
env = os.environ.get('FLASK_ENV', 'development')
app = Flask(__name__)
# Load configuration based on environment
if env == 'development':
app.config.from_object(DevelopmentConfig)
elif env == 'production':
app.config.from_object(ProductionConfig)
else:
app.config.from_object(BaseConfig) # Fallback
@app.route('/')
def hello():
return f"Current environment: {env}, Debug mode: {app.config['DEBUG']}"
if __name__ == '__main__':
app.run()
二、Environment Variables: Secure Sensitive Configurations¶
Environment variables are system-level variables ideal for storing sensitive information (keys, passwords) that should not be exposed in code.
1. Set Environment Variables¶
Linux/Mac Terminal (Temporary):¶
# Set environment type and secret key (only valid for the current terminal)
export FLASK_ENV=development
export SECRET_KEY=your_secure_secret_key
# Verify variables
echo $FLASK_ENV # Output: development
echo $SECRET_KEY # Output: your_secure_secret_key
Windows CMD (Temporary):¶
# Set environment variables
set FLASK_ENV=development
set SECRET_KEY=your_secure_secret_key
# Verify variables
echo %FLASK_ENV% # Output: development
echo %SECRET_KEY% # Output: your_secure_secret_key
2. Read Environment Variables in Flask¶
Read environment variables using os.environ.get() (import os first):
# app.py (updated for environment variables)
from flask import Flask
from config import DevelopmentConfig, ProductionConfig, BaseConfig
import os
# Read SECRET_KEY from environment variable (use default if not set)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev')
# Select configuration based on environment
env = os.environ.get('FLASK_ENV', 'development')
if env == 'development':
app.config.from_object(DevelopmentConfig)
elif env == 'production':
app.config.from_object(ProductionConfig)
else:
app.config.from_object(BaseConfig)
@app.route('/')
def hello():
return f"Secret key: {app.config['SECRET_KEY']}"
if __name__ == '__main__':
app.run()
三、Simplify Development with .env Files¶
Manually setting system environment variables is cumbersome. Use a .env file with the python-dotenv library to auto-load variables during development, avoiding repeated terminal operations.
1. Install python-dotenv¶
pip install python-dotenv
2. Create .env File¶
In your project root, create a .env file:
FLASK_ENV=development
SECRET_KEY=your_dev_secret_key
DATABASE_URL=sqlite:///dev.db
3. Load .env in Code¶
Add this at the start of app.py:
from dotenv import load_dotenv
import os
# Load .env file into environment variables (must run before os.environ.get)
load_dotenv() # Automatically reads variables from .env
# Now read environment variables directly
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
env = os.environ.get('FLASK_ENV', 'development')
Now you can modify the .env file directly during development, without frequent terminal operations. Remember to add .env to .gitignore to avoid committing sensitive data.
四、Configuration Priority & Best Practices¶
-
Priority: Environment Variables > Configuration Files
If the same variable is set in both.envand a configuration file (e.g.,SECRET_KEY), the environment variable takes precedence. -
Separate Environments:
- Development: SetFLASK_ENV=developmentin.env, enableDEBUG, and use SQLite.
- Production: SetFLASK_ENV=productionvia server environment variables, disableDEBUG, and use environment variables for database connections. -
Use Environment Variables for Sensitive Info:
Keys, database passwords, etc., must never be in configuration files—always use environment variables or.env.
总结¶
- Configuration Files: Manage general settings (e.g., default database paths, base keys).
- Environment Variables: Securely store sensitive data (keys, passwords) and dynamic configs (e.g., production/development switching).
- .env + python-dotenv: Streamline development by auto-loading variables without manual terminal steps.
By using configuration files and environment variables effectively, your Flask app becomes more flexible, secure, and easier to deploy across environments!