Environment Configuration¶
Detailed guide for configuring different environments for Dash CopilotKit Components applications.
Environment Types¶
Development Environment¶
- Local development with hot reload
- Debug mode enabled
- Detailed error messages
- Development API keys
Staging Environment¶
- Production-like configuration
- Testing with production data
- Performance monitoring
- Staging API keys
Production Environment¶
- Optimized for performance
- Security hardened
- Monitoring and logging
- Production API keys
Environment Variables¶
Required Variables¶
# CopilotKit Configuration
COPILOTKIT_PUBLIC_API_KEY=ck_pub_your_key_here
# OR for custom runtime
OPENAI_API_KEY=sk-your_openai_key_here
COPILOTKIT_RUNTIME_URL=https://your-runtime.com/api/copilotkit
# Application Settings
DASH_ENV=production # development, staging, production
DASH_DEBUG=false
DASH_HOST=0.0.0.0
DASH_PORT=8050
# Security
SECRET_KEY=your-secret-key-here
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
Optional Variables¶
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
REDIS_URL=redis://localhost:6379
# Logging
LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR
LOG_FORMAT=json # json, text
# Performance
WORKERS=4
TIMEOUT=30
MAX_REQUESTS=1000
# Monitoring
SENTRY_DSN=https://your-sentry-dsn
DATADOG_API_KEY=your-datadog-key
Configuration Management¶
Using python-dotenv¶
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
class Config:
"""Base configuration"""
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key'
COPILOTKIT_PUBLIC_API_KEY = os.environ.get('COPILOTKIT_PUBLIC_API_KEY')
OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
COPILOTKIT_RUNTIME_URL = os.environ.get('COPILOTKIT_RUNTIME_URL')
class DevelopmentConfig(Config):
"""Development configuration"""
DEBUG = True
DASH_ENV = 'development'
LOG_LEVEL = 'DEBUG'
class StagingConfig(Config):
"""Staging configuration"""
DEBUG = False
DASH_ENV = 'staging'
LOG_LEVEL = 'INFO'
class ProductionConfig(Config):
"""Production configuration"""
DEBUG = False
DASH_ENV = 'production'
LOG_LEVEL = 'WARNING'
# Configuration mapping
config = {
'development': DevelopmentConfig,
'staging': StagingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
Environment-specific App Configuration¶
import os
from dash import Dash
import dash_bootstrap_components as dbc
def create_app():
"""Application factory"""
env = os.environ.get('DASH_ENV', 'development')
app = Dash(
__name__,
external_stylesheets=[dbc.themes.BOOTSTRAP],
suppress_callback_exceptions=True
)
# Configure based on environment
if env == 'development':
app.config.update(
dev_tools_hot_reload=True,
dev_tools_ui=True,
dev_tools_props_check=True
)
else:
app.config.update(
dev_tools_hot_reload=False,
dev_tools_ui=False,
dev_tools_props_check=False
)
return app
app = create_app()
Development Environment Setup¶
Local Development¶
- Create
.envfile:
# .env
DASH_ENV=development
DASH_DEBUG=true
COPILOTKIT_PUBLIC_API_KEY=ck_pub_dev_key_here
LOG_LEVEL=DEBUG
- Install development dependencies:
- Run development server:
Development with Docker¶
# Dockerfile.dev
FROM python:3.11-slim
WORKDIR /app
# Install development dependencies
COPY requirements-dev.txt .
RUN pip install -r requirements-dev.txt
# Copy source code
COPY . .
# Development server with hot reload
CMD ["python", "app.py"]
# docker-compose.dev.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "8050:8050"
environment:
- DASH_ENV=development
- DASH_DEBUG=true
volumes:
- .:/app
env_file:
- .env.dev
Staging Environment¶
Staging Configuration¶
# .env.staging
DASH_ENV=staging
DASH_DEBUG=false
COPILOTKIT_PUBLIC_API_KEY=ck_pub_staging_key_here
DATABASE_URL=postgresql://user:pass@staging-db:5432/stagingdb
REDIS_URL=redis://staging-redis:6379
LOG_LEVEL=INFO
SENTRY_DSN=https://staging-sentry-dsn
Staging Deployment¶
# docker-compose.staging.yml
version: '3.8'
services:
app:
build: .
ports:
- "8050:8050"
environment:
- DASH_ENV=staging
env_file:
- .env.staging
depends_on:
- postgres
- redis
postgres:
image: postgres:15-alpine
environment:
- POSTGRES_DB=stagingdb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- staging_postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- staging_redis_data:/data
volumes:
staging_postgres_data:
staging_redis_data:
Production Environment¶
Production Configuration¶
# .env.production
DASH_ENV=production
DASH_DEBUG=false
DASH_HOST=0.0.0.0
DASH_PORT=8050
# Security
SECRET_KEY=super-secret-production-key
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com
# CopilotKit
COPILOTKIT_PUBLIC_API_KEY=ck_pub_production_key_here
# Database
DATABASE_URL=postgresql://produser:prodpass@prod-db:5432/proddb
REDIS_URL=redis://prod-redis:6379
# Monitoring
LOG_LEVEL=WARNING
SENTRY_DSN=https://production-sentry-dsn
DATADOG_API_KEY=production-datadog-key
# Performance
WORKERS=4
TIMEOUT=30
MAX_REQUESTS=1000
Production Security¶
import os
from cryptography.fernet import Fernet
class ProductionConfig:
"""Production configuration with enhanced security"""
@staticmethod
def get_secret_key():
"""Get or generate secret key"""
key = os.environ.get('SECRET_KEY')
if not key:
raise ValueError("SECRET_KEY environment variable is required")
return key
@staticmethod
def get_encrypted_api_key():
"""Decrypt API key"""
encryption_key = os.environ.get('ENCRYPTION_KEY')
encrypted_key = os.environ.get('ENCRYPTED_COPILOTKIT_KEY')
if encryption_key and encrypted_key:
cipher = Fernet(encryption_key.encode())
return cipher.decrypt(encrypted_key.encode()).decode()
return os.environ.get('COPILOTKIT_PUBLIC_API_KEY')
Environment Validation¶
Configuration Validator¶
import os
import sys
from typing import List, Optional
class ConfigValidator:
"""Validate environment configuration"""
REQUIRED_VARS = [
'COPILOTKIT_PUBLIC_API_KEY',
'SECRET_KEY'
]
PRODUCTION_REQUIRED = [
'DATABASE_URL',
'REDIS_URL',
'SENTRY_DSN'
]
@classmethod
def validate(cls, env: str = None) -> List[str]:
"""Validate configuration and return list of errors"""
errors = []
env = env or os.environ.get('DASH_ENV', 'development')
# Check required variables
for var in cls.REQUIRED_VARS:
if not os.environ.get(var):
errors.append(f"Missing required environment variable: {var}")
# Check production-specific variables
if env == 'production':
for var in cls.PRODUCTION_REQUIRED:
if not os.environ.get(var):
errors.append(f"Missing production environment variable: {var}")
# Validate API key format
api_key = os.environ.get('COPILOTKIT_PUBLIC_API_KEY')
if api_key and not api_key.startswith('ck_pub_'):
errors.append("COPILOTKIT_PUBLIC_API_KEY should start with 'ck_pub_'")
return errors
@classmethod
def validate_or_exit(cls, env: str = None):
"""Validate configuration and exit if errors found"""
errors = cls.validate(env)
if errors:
print("Configuration errors found:")
for error in errors:
print(f" - {error}")
sys.exit(1)
print("Configuration validation passed")
# Validate on import
if __name__ == "__main__":
ConfigValidator.validate_or_exit()
Environment-specific Features¶
Feature Flags¶
import os
class FeatureFlags:
"""Environment-based feature flags"""
@staticmethod
def is_development():
return os.environ.get('DASH_ENV') == 'development'
@staticmethod
def is_production():
return os.environ.get('DASH_ENV') == 'production'
@staticmethod
def enable_debug_tools():
return FeatureFlags.is_development()
@staticmethod
def enable_analytics():
return not FeatureFlags.is_development()
@staticmethod
def enable_error_reporting():
return os.environ.get('SENTRY_DSN') is not None
# Usage in app
if FeatureFlags.enable_debug_tools():
app.config.update(dev_tools_ui=True)
if FeatureFlags.enable_analytics():
# Initialize analytics
pass
Environment-specific Components¶
import dash_copilotkit_components
from config import FeatureFlags
def create_copilot_component():
"""Create CopilotKit component with environment-specific config"""
base_config = {
'id': 'main-copilot',
'ui_type': 'chat',
'height': '500px'
}
if FeatureFlags.is_development():
# Development configuration
base_config.update({
'public_api_key': os.environ.get('COPILOTKIT_PUBLIC_API_KEY'),
'instructions': 'You are a development assistant with debug capabilities.'
})
else:
# Production configuration
base_config.update({
'public_api_key': os.environ.get('COPILOTKIT_PUBLIC_API_KEY'),
'instructions': 'You are a professional assistant.'
})
return dash_copilotkit_components.DashCopilotkitComponents(**base_config)
Environment Migration¶
Database Migrations¶
import os
from alembic import command
from alembic.config import Config
def run_migrations():
"""Run database migrations based on environment"""
env = os.environ.get('DASH_ENV', 'development')
alembic_cfg = Config("alembic.ini")
alembic_cfg.set_main_option("sqlalchemy.url", os.environ.get('DATABASE_URL'))
if env == 'production':
# Production migrations with backup
print("Running production migrations...")
command.upgrade(alembic_cfg, "head")
else:
# Development migrations
command.upgrade(alembic_cfg, "head")
if __name__ == "__main__":
run_migrations()
Troubleshooting¶
Common Environment Issues¶
- Missing environment variables: Use validation scripts
- Wrong API keys: Check key format and permissions
- Database connection issues: Verify connection strings
- Port conflicts: Check port availability
- Permission issues: Verify file and directory permissions
Environment Debugging¶
import os
import json
def debug_environment():
"""Debug environment configuration"""
env_vars = {
'DASH_ENV': os.environ.get('DASH_ENV'),
'DASH_DEBUG': os.environ.get('DASH_DEBUG'),
'DASH_HOST': os.environ.get('DASH_HOST'),
'DASH_PORT': os.environ.get('DASH_PORT'),
'COPILOTKIT_PUBLIC_API_KEY': 'SET' if os.environ.get('COPILOTKIT_PUBLIC_API_KEY') else 'NOT SET',
'DATABASE_URL': 'SET' if os.environ.get('DATABASE_URL') else 'NOT SET',
'REDIS_URL': 'SET' if os.environ.get('REDIS_URL') else 'NOT SET'
}
print("Environment Configuration:")
print(json.dumps(env_vars, indent=2))
if __name__ == "__main__":
debug_environment()
Next Steps¶
- Production Deployment - Deploy to production
- Performance Optimization - Optimize for production
- Monitoring - Monitor your application