pylord/API-BFSI
0
1"""2Configuration Management for RiskShield3Handles environment variables and application settings4"""5 6from pydantic_settings import BaseSettings7from typing import List8import os9from pathlib import Path10 11class Settings(BaseSettings):12 """13 Application settings with validation14 """15 16 # Application Info17 APP_NAME: str = "RiskShield Fraud Detection API"18 APP_VERSION: str = "1.0.0"19 APP_DESCRIPTION: str = "AI-powered fraud detection system"20 21 # API Configuration22 API_HOST: str = "0.0.0.0"23 API_PORT: int = 800024 API_WORKERS: int = 425 DEBUG: bool = False26 27 # Database Configuration28 DB_USER: str = "neondb_owner"29 DB_PASSWORD: str = "npg_PRu3eQ9Wojpi"30 DB_HOST: str = "lep-square-cake-ahgu680l-pooler.c-3.us-east-1.aws.neon.techocalhost"31 DB_PORT: str = "5432"32 DB_NAME: str = "neondb"33 DB_SSLMODE: str ="require"34 35 36 37 # Database Connection Pool38 DB_POOL_SIZE: int = 539 DB_MAX_OVERFLOW: int = 1040 DB_POOL_TIMEOUT: int = 3041 DB_POOL_RECYCLE: int = 360042 43 # Model Configuration44 MODEL_PATH: str = "model/catboost_fraud_model_balanced_tuned.cbm"45 46 # Security47 SECRET_KEY: str = "change-this-secret-key-in-production"48 JWT_SECRET: str = "change-this-jwt-secret-in-production"49 JWT_ALGORITHM: str = "HS256"50 ACCESS_TOKEN_EXPIRE_MINUTES: int = 3051 52 # Password Requirements53 MIN_PASSWORD_LENGTH: int = 654 MAX_PASSWORD_LENGTH: int = 10055 56 # CORS Configuration57 CORS_ORIGINS: List[str] = [58 "http://localhost:3000",59 "http://localhost:5500",60 "http://127.0.0.1:5500",61 "http://127.0.0.1:3000"62 ]63 64 # Fraud Detection Thresholds65 FRAUD_THRESHOLD: float = 0.666 HIGH_RISK_THRESHOLD: float = 0.867 HIGH_AMOUNT_THRESHOLD: float = 10000068 69 # Rule-Based Detection70 NIGHT_HOURS_START: int = 2271 NIGHT_HOURS_END: int = 672 HIGH_AMOUNT_NIGHT_THRESHOLD: float = 5000073 WEEKEND_HIGH_THRESHOLD: float = 8000074 HOLIDAY_HIGH_THRESHOLD: float = 7000075 NEW_ACCOUNT_DAYS: int = 1076 VELOCITY_CHECK_HOURS: int = 177 VELOCITY_CHECK_THRESHOLD: int = 378 79 # Rate Limiting80 RATE_LIMIT_ENABLED: bool = True81 RATE_LIMIT_REQUESTS: int = 10082 RATE_LIMIT_PERIOD: int = 60 # seconds83 84 # Logging Configuration85 LOG_LEVEL: str = "INFO"86 LOG_FILE: str = "logs/riskshield.log"87 LOG_FORMAT: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"88 LOG_MAX_BYTES: int = 10485760 # 10MB89 LOG_BACKUP_COUNT: int = 590 91 # Feature Flags92 ENABLE_ML_MODEL: bool = True93 ENABLE_RULE_ENGINE: bool = True94 ENABLE_HF_EXPLANATIONS: bool = False95 ENABLE_METRICS: bool = True96 97 # Performance98 ENABLE_CACHING: bool = False99 CACHE_TTL: int = 3600100 101 # Monitoring102 METRICS_PORT: int = 9090103 104 # Email Configuration (for alerts - optional)105 SMTP_HOST: str = "smtp.gmail.com"106 SMTP_PORT: int = 587107 SMTP_USER: str = ""108 SMTP_PASSWORD: str = ""109 ALERT_EMAIL: str = ""110 ENABLE_EMAIL_ALERTS: bool = False111 112 # Redis Configuration (optional)113 REDIS_HOST: str = "localhost"114 REDIS_PORT: int = 6379115 REDIS_DB: int = 0116 REDIS_ENABLED: bool = False117 118 @property119 def database_url(self) -> str:120 """Generate database URL (Neon + local compatible)"""121 return (122 f"postgresql://{self.DB_USER}:{self.DB_PASSWORD}@"123 f"{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}?sslmode={self.DB_SSLMODE}"124 )125 126 @property127 def async_database_url(self) -> str:128 """Generate async database URL (Neon + asyncpg)"""129 return (130 f"postgresql+asyncpg://{self.DB_USER}:{self.DB_PASSWORD}@"131 f"{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}?sslmode={self.DB_SSLMODE}"132 )133 134 def is_production(self) -> bool:135 """Check if running in production"""136 return not self.DEBUG137 138 def validate_model_path(self) -> bool:139 """Validate model file exists"""140 return Path(self.MODEL_PATH).exists()141 142 class Config:143 env_file = ".env"144 env_file_encoding = "utf-8"145 case_sensitive = True146 147 148# Global settings instance149settings = Settings()150 151 152# Logging Configuration153def setup_logging():154 """Setup application logging"""155 import logging156 from logging.handlers import RotatingFileHandler157 158 # Create logs directory if not exists159 log_dir = Path(settings.LOG_FILE).parent160 log_dir.mkdir(parents=True, exist_ok=True)161 162 # Configure logging163 logging.basicConfig(164 level=getattr(logging, settings.LOG_LEVEL),165 format=settings.LOG_FORMAT,166 handlers=[167 RotatingFileHandler(168 settings.LOG_FILE,169 maxBytes=settings.LOG_MAX_BYTES,170 backupCount=settings.LOG_BACKUP_COUNT171 ),172 logging.StreamHandler()173 ]174 )175 176 logger = logging.getLogger(__name__)177 logger.info(f"Logging configured: {settings.LOG_LEVEL}")178 return logger179 180 181# Configuration Display182def display_config():183 """Display current configuration (for debugging)"""184 print("=" * 60)185 print("🛡️ RiskShield Configuration")186 print("=" * 60)187 print(f"App Name: {settings.APP_NAME}")188 print(f"Version: {settings.APP_VERSION}")189 print(f"Debug Mode: {settings.DEBUG}")190 print(f"API Host: {settings.API_HOST}")191 print(f"API Port: {settings.API_PORT}")192 print(f"Database: {settings.DB_NAME} @ {settings.DB_HOST}:{settings.DB_PORT}")193 print(f"Model Path: {settings.MODEL_PATH}")194 print(f"Model Exists: {settings.validate_model_path()}")195 print(f"Fraud Threshold: {settings.FRAUD_THRESHOLD}")196 print(f"ML Model Enabled: {settings.ENABLE_ML_MODEL}")197 print(f"Rule Engine Enabled: {settings.ENABLE_RULE_ENGINE}")198 print(f"Rate Limiting: {settings.RATE_LIMIT_ENABLED}")199 print(f"CORS Origins: {len(settings.CORS_ORIGINS)} configured")200 print("=" * 60)201 202 203# Validation Functions204def validate_configuration() -> List[str]:205 """206 Validate configuration and return list of warnings/errors207 """208 issues = []209 210 # Check database configuration211 if settings.DB_PASSWORD == "admin123":212 issues.append("⚠️ WARNING: Using default database password")213 214 # Check secret keys215 if "change-this" in settings.SECRET_KEY.lower():216 issues.append("⚠️ WARNING: Using default SECRET_KEY")217 218 if "change-this" in settings.JWT_SECRET.lower():219 issues.append("⚠️ WARNING: Using default JWT_SECRET")220 221 # Check model file222 if not settings.validate_model_path():223 issues.append(f"⚠️ WARNING: Model file not found at {settings.MODEL_PATH}")224 225 # Check production settings226 if settings.is_production():227 if settings.DEBUG:228 issues.append("⚠️ WARNING: Debug mode enabled in production")229 230 if not settings.RATE_LIMIT_ENABLED:231 issues.append("⚠️ WARNING: Rate limiting disabled in production")232 233 # Check thresholds234 if settings.FRAUD_THRESHOLD < 0 or settings.FRAUD_THRESHOLD > 1:235 issues.append("❌ ERROR: Invalid fraud threshold (must be 0-1)")236 237 return issues238 239 240# Environment Detection241def get_environment() -> str:242 """Detect current environment"""243 if settings.DEBUG:244 return "development"245 elif os.getenv("STAGING"):246 return "staging"247 else:248 return "production"249 250 251# Export commonly used settings252__all__ = [253 'settings',254 'setup_logging',255 'display_config',256 'validate_configuration',257 'get_environment'258]259 260 261if __name__ == "__main__":262 # Display configuration when run directly263 display_config()264 265 # Validate configuration266 issues = validate_configuration()267 if issues:268 print("\n⚠️ Configuration Issues:")269 for issue in issues:270 print(f" {issue}")271 else:272 print("\n✅ Configuration validated successfully")