181 lines
5.4 KiB
Python
181 lines
5.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Application Configuration Module for MYP Platform
|
|
================================================
|
|
|
|
Flask configuration classes for different environments.
|
|
"""
|
|
|
|
import os
|
|
from datetime import timedelta
|
|
|
|
# Base configuration directory
|
|
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
|
PROJECT_ROOT = os.path.abspath(os.path.join(BASE_DIR, '..', '..'))
|
|
|
|
class Config:
|
|
"""Base configuration class with common settings."""
|
|
|
|
# Secret key for Flask sessions and CSRF protection
|
|
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-secret-key-change-in-production-744563017196A'
|
|
|
|
# Session configuration
|
|
PERMANENT_SESSION_LIFETIME = timedelta(hours=24)
|
|
SESSION_COOKIE_SECURE = False # Set to True in production with HTTPS
|
|
SESSION_COOKIE_HTTPONLY = True
|
|
SESSION_COOKIE_SAMESITE = 'Lax'
|
|
|
|
# Database configuration
|
|
DATABASE_URL = os.environ.get('DATABASE_URL') or f'sqlite:///{os.path.join(PROJECT_ROOT, "database", "myp.db")}'
|
|
SQLALCHEMY_DATABASE_URI = DATABASE_URL
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
SQLALCHEMY_ENGINE_OPTIONS = {
|
|
'pool_pre_ping': True,
|
|
'pool_recycle': 300,
|
|
}
|
|
|
|
# Upload configuration
|
|
UPLOAD_FOLDER = os.path.join(PROJECT_ROOT, 'uploads')
|
|
MAX_CONTENT_LENGTH = 500 * 1024 * 1024 # 500MB max file size
|
|
ALLOWED_EXTENSIONS = {'gcode', 'stl', 'obj', '3mf', 'amf'}
|
|
|
|
# Security configuration
|
|
WTF_CSRF_ENABLED = True
|
|
WTF_CSRF_TIME_LIMIT = 3600 # 1 hour
|
|
|
|
# Mail configuration (optional)
|
|
MAIL_SERVER = os.environ.get('MAIL_SERVER')
|
|
MAIL_PORT = int(os.environ.get('MAIL_PORT') or 587)
|
|
MAIL_USE_TLS = os.environ.get('MAIL_USE_TLS', 'true').lower() in ['true', 'on', '1']
|
|
MAIL_USERNAME = os.environ.get('MAIL_USERNAME')
|
|
MAIL_PASSWORD = os.environ.get('MAIL_PASSWORD')
|
|
|
|
# Logging configuration
|
|
LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO')
|
|
LOG_FILE_MAX_BYTES = 10 * 1024 * 1024 # 10MB
|
|
LOG_BACKUP_COUNT = 5
|
|
|
|
# Application-specific settings
|
|
SCHEDULER_ENABLED = os.environ.get('SCHEDULER_ENABLED', 'true').lower() in ['true', 'on', '1']
|
|
SCHEDULER_INTERVAL = int(os.environ.get('SCHEDULER_INTERVAL', '60')) # seconds
|
|
|
|
# SSL/HTTPS configuration
|
|
SSL_ENABLED = os.environ.get('SSL_ENABLED', 'false').lower() in ['true', 'on', '1']
|
|
SSL_CERT_PATH = os.environ.get('SSL_CERT_PATH')
|
|
SSL_KEY_PATH = os.environ.get('SSL_KEY_PATH')
|
|
|
|
# Network configuration
|
|
DEFAULT_PORT = int(os.environ.get('PORT', '5000'))
|
|
DEFAULT_HOST = os.environ.get('HOST', '0.0.0.0')
|
|
|
|
@staticmethod
|
|
def init_app(app):
|
|
"""Initialize application with this configuration."""
|
|
pass
|
|
|
|
|
|
class DevelopmentConfig(Config):
|
|
"""Development environment configuration."""
|
|
|
|
DEBUG = True
|
|
TESTING = False
|
|
|
|
# More verbose logging in development
|
|
LOG_LEVEL = 'DEBUG'
|
|
|
|
# Disable some security features for easier development
|
|
SESSION_COOKIE_SECURE = False
|
|
WTF_CSRF_ENABLED = False # Disable CSRF for easier API testing
|
|
|
|
@staticmethod
|
|
def init_app(app):
|
|
Config.init_app(app)
|
|
|
|
# Development-specific initialization
|
|
import logging
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
|
|
|
|
class TestingConfig(Config):
|
|
"""Testing environment configuration."""
|
|
|
|
TESTING = True
|
|
DEBUG = True
|
|
|
|
# Use in-memory database for testing
|
|
DATABASE_URL = 'sqlite:///:memory:'
|
|
SQLALCHEMY_DATABASE_URI = DATABASE_URL
|
|
|
|
# Disable CSRF for testing
|
|
WTF_CSRF_ENABLED = False
|
|
|
|
# Shorter session lifetime for testing
|
|
PERMANENT_SESSION_LIFETIME = timedelta(minutes=5)
|
|
|
|
@staticmethod
|
|
def init_app(app):
|
|
Config.init_app(app)
|
|
|
|
|
|
class ProductionConfig(Config):
|
|
"""Production environment configuration."""
|
|
|
|
DEBUG = False
|
|
TESTING = False
|
|
|
|
# Strict security settings for production
|
|
SESSION_COOKIE_SECURE = True # Requires HTTPS
|
|
WTF_CSRF_ENABLED = True
|
|
|
|
# Production logging
|
|
LOG_LEVEL = 'WARNING'
|
|
|
|
# SSL should be enabled in production
|
|
SSL_ENABLED = True
|
|
|
|
@staticmethod
|
|
def init_app(app):
|
|
Config.init_app(app)
|
|
|
|
# Production-specific initialization
|
|
import logging
|
|
from logging.handlers import RotatingFileHandler
|
|
|
|
# Set up file logging for production
|
|
log_dir = os.path.join(os.path.dirname(app.instance_path), 'logs')
|
|
if not os.path.exists(log_dir):
|
|
os.makedirs(log_dir)
|
|
|
|
file_handler = RotatingFileHandler(
|
|
os.path.join(log_dir, 'myp_platform.log'),
|
|
maxBytes=Config.LOG_FILE_MAX_BYTES,
|
|
backupCount=Config.LOG_BACKUP_COUNT
|
|
)
|
|
file_handler.setFormatter(logging.Formatter(
|
|
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'
|
|
))
|
|
file_handler.setLevel(logging.WARNING)
|
|
app.logger.addHandler(file_handler)
|
|
app.logger.setLevel(logging.WARNING)
|
|
|
|
|
|
# Configuration dictionary for easy access
|
|
config = {
|
|
'development': DevelopmentConfig,
|
|
'testing': TestingConfig,
|
|
'production': ProductionConfig,
|
|
'default': DevelopmentConfig
|
|
}
|
|
|
|
|
|
def get_config_by_name(config_name):
|
|
"""
|
|
Get configuration class by name.
|
|
|
|
Args:
|
|
config_name (str): Name of the configuration ('development', 'testing', 'production')
|
|
|
|
Returns:
|
|
Config: Configuration class
|
|
"""
|
|
return config.get(config_name, config['default']) |