Spaces:
Running
Running
File size: 6,037 Bytes
232e999 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
#!/usr/bin/env python3
"""
Secure Configuration Management for GlycoAI
Handles API keys and secrets safely for both local development and Hugging Face Spaces
"""
import os
import logging
from typing import Optional, Dict, Any
# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class SecureConfig:
"""Secure configuration manager for API keys and secrets"""
def __init__(self):
self.config = {}
self._load_configuration()
def _load_configuration(self):
"""Load configuration from environment variables"""
# Mistral AI Configuration
self.mistral_api_key = self._get_secret(
"MISTRAL_API_KEY",
description="Mistral AI API Key"
)
self.mistral_agent_id = self._get_secret(
"MISTRAL_AGENT_ID",
description="Mistral AI Agent ID",
required=False
)
# Dexcom API Configuration (for future real API integration)
self.dexcom_client_id = self._get_secret(
"DEXCOM_CLIENT_ID",
description="Dexcom API Client ID",
required=False
)
self.dexcom_client_secret = self._get_secret(
"DEXCOM_CLIENT_SECRET",
description="Dexcom API Client Secret",
required=False
)
# Application Configuration
self.app_environment = os.getenv("ENVIRONMENT", "development")
self.debug_mode = os.getenv("DEBUG", "false").lower() == "true"
self.log_level = os.getenv("LOG_LEVEL", "INFO")
# Hugging Face Space Detection
self.is_huggingface_space = os.getenv("SPACE_ID") is not None
logger.info(f"Configuration loaded for environment: {self.app_environment}")
logger.info(f"Running on Hugging Face Space: {self.is_huggingface_space}")
def _get_secret(self, key: str, description: str = "", required: bool = True) -> Optional[str]:
"""Safely get secret from environment variables"""
value = os.getenv(key)
if value:
logger.info(f"β
{description or key} loaded successfully")
return value
elif required:
logger.error(f"β Required secret {key} ({description}) not found!")
logger.error(f"Please set the {key} environment variable")
return None
else:
logger.warning(f"β οΈ Optional secret {key} ({description}) not set")
return None
def validate_configuration(self) -> Dict[str, Any]:
"""Validate that all required configuration is present"""
validation_result = {
"valid": True,
"errors": [],
"warnings": []
}
# Check required secrets
if not self.mistral_api_key:
validation_result["valid"] = False
validation_result["errors"].append("MISTRAL_API_KEY is required")
# Check optional but recommended secrets
if not self.mistral_agent_id:
validation_result["warnings"].append("MISTRAL_AGENT_ID not set - will use standard chat completion")
# Environment-specific checks
if self.is_huggingface_space:
if not all([self.mistral_api_key]):
validation_result["errors"].append("Hugging Face Space requires MISTRAL_API_KEY in secrets")
return validation_result
def get_mistral_config(self) -> Dict[str, Optional[str]]:
"""Get Mistral AI configuration"""
return {
"api_key": self.mistral_api_key,
"agent_id": self.mistral_agent_id
}
def get_dexcom_config(self) -> Dict[str, Optional[str]]:
"""Get Dexcom API configuration"""
return {
"client_id": self.dexcom_client_id,
"client_secret": self.dexcom_client_secret
}
def is_development(self) -> bool:
"""Check if running in development mode"""
return self.app_environment == "development"
def is_production(self) -> bool:
"""Check if running in production mode"""
return self.app_environment == "production"
# Global configuration instance
config = SecureConfig()
def get_config() -> SecureConfig:
"""Get the global configuration instance"""
return config
def validate_environment():
"""Validate environment configuration and provide helpful messages"""
print("π Validating GlycoAI Configuration...")
print("=" * 50)
validation = config.validate_configuration()
if validation["valid"]:
print("β
Configuration validation passed!")
else:
print("β Configuration validation failed!")
for error in validation["errors"]:
print(f" β {error}")
if validation["warnings"]:
print("\nβ οΈ Warnings:")
for warning in validation["warnings"]:
print(f" β οΈ {warning}")
# Provide setup instructions
if not validation["valid"]:
print("\nπ Setup Instructions:")
print("=" * 30)
if config.is_huggingface_space:
print("π€ For Hugging Face Spaces:")
print("1. Go to your Space settings")
print("2. Add Repository secrets:")
print(" - MISTRAL_API_KEY: your_mistral_api_key")
print(" - MISTRAL_AGENT_ID: your_agent_id (optional)")
else:
print("π» For Local Development:")
print("1. Create a .env file in your project root:")
print(" MISTRAL_API_KEY=your_mistral_api_key")
print(" MISTRAL_AGENT_ID=your_agent_id")
print("2. Or set environment variables:")
print(" export MISTRAL_API_KEY=your_mistral_api_key")
print(" export MISTRAL_AGENT_ID=your_agent_id")
return validation["valid"]
if __name__ == "__main__":
validate_environment() |