Essential for Beginners: Configuring Flask Files and Environment Variables

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

  1. Priority: Environment Variables > Configuration Files
    If the same variable is set in both .env and a configuration file (e.g., SECRET_KEY), the environment variable takes precedence.

  2. Separate Environments:
    - Development: Set FLASK_ENV=development in .env, enable DEBUG, and use SQLite.
    - Production: Set FLASK_ENV=production via server environment variables, disable DEBUG, and use environment variables for database connections.

  3. 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!

Xiaoye