Loading IconFastLaunchAPI
Features

Configuration Management

Comprehensive guide to managing application settings, environment variables, and configuration in FastLaunchAPI

Configuration Management

FastLaunchAPI uses a centralized configuration system that manages all application settings through environment variables and a singleton Settings class. This approach ensures secure, scalable, and environment-specific configuration management.

Overview

The configuration system is built around the Settings class in app/config/settings.py, which loads environment variables using python-dotenv and provides typed access to all configuration values throughout the application.

All configuration values are loaded once at application startup and cached in the app_settings singleton instance for optimal performance.

Configuration Architecture

settings.py
.env
.env.sample

Settings Class Structure

The Settings class centralizes all configuration management:

app/config/settings.py
import os
from dotenv import load_dotenv

class Settings:
    def __init__(self):
        load_dotenv()

        # Core Application Settings
        self.SECRET_KEY: str = os.getenv("SECRET_KEY")
        self.FRONTEND_URL: str = os.getenv("FRONTEND_URL")
        self.BACKEND_URL: str = os.getenv("BACKEND_URL")
        self.REDIS_DSN: str = os.getenv("REDIS_DSN")

        # Security Configuration
        self.CORS_ORIGINS: list[str] = ["*"]
        self.ACCESS_TOKEN_EXPIRATION_DAYS: int = 7
        self.REFRESH_TOKEN_EXPIRATION_DAYS: int = 14

        # OAuth Configuration
        self.GOOGLE_CLIENT_ID: str = os.getenv("GOOGLE_CLIENT_ID")
        self.GOOGLE_CLIENT_SECRET: str = os.getenv("GOOGLE_CLIENT_SECRET")
        self.GOOGLE_REDIRECT_URI: str = os.getenv("GOOGLE_REDIRECT_URI")

        # Email Configuration
        self.SENDGRID_API_KEY: str = os.getenv("SENDGRID_API_KEY")

# Singleton instance
app_settings = Settings()

Environment Variables

Required Variables

These environment variables are required for the application to function properly. Missing values will cause startup failures.

VariableDescriptionExample
SECRET_KEYJWT signing key and general encryptionyour-super-secret-key-here
DATABASE_URLPostgreSQL connection stringpostgresql://user:pass@localhost:5432/dbname
FRONTEND_URLFrontend application URLhttp://localhost:3000
BACKEND_URLBackend API URLhttp://localhost:8000

Optional Variables (Still important for fully functionality)

VariableDescriptionDefaultExample
REDIS_DSNRedis connection stringredis://localhost:6379redis://localhost:6379/0
CORS_ORIGINSAllowed CORS origins["*"]["http://localhost:3000"]

OAuth Configuration

For OAuth providers, configure the following variables:

.env
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=http://localhost:8000/auth/callback/google
.env
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_REDIRECT_URI=http://localhost:8000/auth/callback/github

Email Configuration

Configure email service providers:

.env
SENDGRID_API_KEY=your-sendgrid-api-key
SENDGRID_FROM_EMAIL=noreply@yourdomain.com

Environment Setup

Create Environment File

Copy the sample environment file and customize it:

cp .env.sample .env

Configure Basic Settings

Update the .env file with your specific values:

.env
# Core Settings
SECRET_KEY=your-super-secret-key-here
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/fastlaunchapi
FRONTEND_URL=http://localhost:3000
BACKEND_URL=http://localhost:8000

# Redis (optional)
REDIS_DSN=redis://localhost:6379/0

# OAuth (optional)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=http://localhost:8000/auth/callback/google

# Email (optional)
SENDGRID_API_KEY=your-sendgrid-api-key

Validate Configuration

The application will validate critical configuration on startup. Missing required variables will cause startup failures with clear error messages.

Using Configuration in Your Code

Importing Settings

Import the settings singleton in your modules:

from app.config.settings import app_settings

# Use configuration values
token_expiration = app_settings.ACCESS_TOKEN_EXPIRATION_DAYS
frontend_url = app_settings.FRONTEND_URL

Example Usage in Routes

Here's how configuration is used in authentication routes:

app/routers/auth/routes.py
from app.config.settings import app_settings

@router.post("/token")
async def login_for_access_token(db: db_dependency, form_data: OAuth2PasswordRequestForm):
    user = authenticate_user(form_data.username, form_data.password, db)

    # Using configuration for token expiration
    access_token = create_access_token(
        user.username,
        user.id,
        timedelta(days=app_settings.ACCESS_TOKEN_EXPIRATION_DAYS)
    )

    # Using configuration for redirect URL
    return RedirectResponse(f"{app_settings.FRONTEND_URL}/dashboard")

Configuration Categories

Core Application Settings

🔧 Core Settings

Essential application configuration

  • SECRET_KEY: Used for JWT signing and encryption
  • FRONTEND_URL: Frontend application URL for redirects
  • BACKEND_URL: Backend API URL for internal references
  • REDIS_DSN: Redis connection for caching and task queues

Security Configuration

🔒 Security Settings

Authentication and security parameters

  • ACCESS_TOKEN_EXPIRATION_DAYS: JWT access token lifetime (default: 7 days)
  • REFRESH_TOKEN_EXPIRATION_DAYS: JWT refresh token lifetime (default: 14 days)
  • CORS_ORIGINS: Allowed cross-origin request sources

OAuth Provider Settings

🔐 OAuth Configuration

Third-party authentication provider settings

  • GOOGLE_CLIENT_ID: Google OAuth client identifier
  • GOOGLE_CLIENT_SECRET: Google OAuth client secret
  • GOOGLE_REDIRECT_URI: OAuth callback URL

Email Service Configuration

📧 Email Settings

Email service provider configuration

  • SENDGRID_API_KEY: SendGrid API key for email sending
  • SENDGRID_FROM_EMAIL: Default sender email address

Environment-Specific Configuration

Development Environment

.env.development
SECRET_KEY=development-secret-key
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/fastlaunchapi_dev
FRONTEND_URL=http://localhost:3000
BACKEND_URL=http://localhost:8000
REDIS_DSN=redis://localhost:6379/0

Production Environment

.env.production
SECRET_KEY=${SECRET_KEY}
DATABASE_URL=${DATABASE_URL}
FRONTEND_URL=https://yourdomain.com
BACKEND_URL=https://api.yourdomain.com
REDIS_DSN=${REDIS_URL}

In production, use environment variables or secure secret management systems instead of .env files.

Advanced Configuration

Custom Configuration Values

Extend the Settings class to add custom configuration:

app/config/settings.py
class Settings:
    def __init__(self):
        load_dotenv()

        # Existing configuration...

        # Custom configuration
        self.MAX_UPLOAD_SIZE: int = int(os.getenv("MAX_UPLOAD_SIZE", "10485760"))  # 10MB
        self.RATE_LIMIT_REQUESTS: int = int(os.getenv("RATE_LIMIT_REQUESTS", "100"))
        self.RATE_LIMIT_WINDOW: int = int(os.getenv("RATE_LIMIT_WINDOW", "3600"))  # 1 hour

        # Feature flags
        self.ENABLE_REGISTRATION: bool = os.getenv("ENABLE_REGISTRATION", "true").lower() == "true"
        self.ENABLE_OAUTH: bool = os.getenv("ENABLE_OAUTH", "true").lower() == "true"

Configuration Validation

Add validation to ensure configuration integrity:

app/config/settings.py
import os
from typing import Optional
from dotenv import load_dotenv

class Settings:
    def __init__(self):
        load_dotenv()

        # Load configuration
        self.SECRET_KEY: str = os.getenv("SECRET_KEY")
        self.DATABASE_URL: str = os.getenv("DATABASE_URL")

        # Validate critical settings
        self._validate_config()

    def _validate_config(self):
        """Validate critical configuration values."""
        if not self.SECRET_KEY:
            raise ValueError("SECRET_KEY environment variable is required")

        if not self.DATABASE_URL:
            raise ValueError("DATABASE_URL environment variable is required")

        if len(self.SECRET_KEY) < 32:
            raise ValueError("SECRET_KEY must be at least 32 characters long")

Configuration Best Practices

Security Guidelines

Never commit sensitive configuration values to version control. Use environment variables or secure secret management systems.

Best Practices:

  1. Use strong SECRET_KEY: Generate a secure random key for production
  2. Environment separation: Use different configurations for dev/staging/production
  3. Secure secrets: Use secret management services in production
  4. Validate inputs: Add validation for critical configuration values
  5. Document defaults: Clearly document default values and requirements

Performance Considerations

  1. Singleton pattern: Configuration is loaded once at startup
  2. Type hints: Use type hints for better IDE support and validation
  3. Lazy loading: Only load configuration when needed
  4. Caching: Cache expensive configuration computations

Testing Configuration

Create test-specific configuration:

tests/conftest.py
import pytest
from app.config.settings import Settings

@pytest.fixture
def test_settings():
    """Override settings for testing."""
    settings = Settings()
    settings.DATABASE_URL = "postgresql://test:test@localhost:5432/test_db"
    settings.SECRET_KEY = "test-secret-key"
    settings.ACCESS_TOKEN_EXPIRATION_DAYS = 1
    return settings

Troubleshooting

Common Issues

Missing Environment Variables: Ensure all required environment variables are set before starting the application.

Invalid Configuration: Check that configuration values are properly formatted and within expected ranges.

Common Problems:

  1. SECRET_KEY not set: Application won't start without a valid SECRET_KEY
  2. Database connection: Verify DATABASE_URL format and database accessibility
  3. OAuth configuration: Ensure OAuth credentials are valid and redirect URIs match
  4. Port conflicts: Check that configured ports are available

Debug Configuration

Add logging to debug configuration issues:

app/config/settings.py
import logging
import os
from dotenv import load_dotenv

logger = logging.getLogger(__name__)

class Settings:
    def __init__(self):
        load_dotenv()

        # Log configuration loading
        logger.info("Loading application configuration...")

        self.SECRET_KEY: str = os.getenv("SECRET_KEY")
        if not self.SECRET_KEY:
            logger.error("SECRET_KEY not found in environment variables")

        logger.info("Configuration loaded successfully")

Next Steps