Datasourceforcryptocurrency-5 / utils /environment_detector.py
nimazasinich
Data provider stability and ui (#112)
a24b1f8
raw
history blame
7.1 kB
"""
Environment Detection Utility
Detects GPU availability, HuggingFace Space environment, and system capabilities
"""
import os
import platform
import logging
from typing import Dict, Any, Optional
logger = logging.getLogger(__name__)
class EnvironmentDetector:
"""Detect runtime environment and capabilities"""
def __init__(self):
self._gpu_available: Optional[bool] = None
self._is_huggingface: Optional[bool] = None
self._transformers_available: Optional[bool] = None
self._torch_available: Optional[bool] = None
def is_huggingface_space(self) -> bool:
"""Detect if running on HuggingFace Space"""
if self._is_huggingface is None:
# Check for HF Space environment variables
self._is_huggingface = bool(
os.getenv("SPACE_ID") or
os.getenv("SPACE_AUTHOR_NAME") or
os.getenv("SPACE_HOST")
)
return self._is_huggingface
def has_gpu(self) -> bool:
"""Detect if GPU is available"""
if self._gpu_available is None:
self._gpu_available = False
try:
import torch
self._gpu_available = torch.cuda.is_available()
if self._gpu_available:
gpu_name = torch.cuda.get_device_name(0)
logger.info(f"✅ GPU detected: {gpu_name}")
else:
logger.info("ℹ️ No GPU detected - using CPU")
except ImportError:
logger.info("ℹ️ PyTorch not installed - assuming no GPU")
self._gpu_available = False
except Exception as e:
logger.warning(f"Error detecting GPU: {e}")
self._gpu_available = False
return self._gpu_available
def is_torch_available(self) -> bool:
"""Check if PyTorch is installed"""
if self._torch_available is None:
try:
import torch
self._torch_available = True
logger.info(f"✅ PyTorch {torch.__version__} available")
except ImportError:
self._torch_available = False
logger.info("ℹ️ PyTorch not installed")
return self._torch_available
def is_transformers_available(self) -> bool:
"""Check if Transformers library is installed"""
if self._transformers_available is None:
try:
import transformers
self._transformers_available = True
logger.info(f"✅ Transformers {transformers.__version__} available")
except ImportError:
self._transformers_available = False
logger.info("ℹ️ Transformers not installed")
return self._transformers_available
def should_use_ai_models(self) -> bool:
"""
Determine if AI models should be used
Only use if:
- Running on HuggingFace Space, OR
- Transformers is installed AND (GPU available OR explicitly enabled)
"""
if self.is_huggingface_space():
logger.info("✅ HuggingFace Space detected - AI models will be used")
return True
if not self.is_transformers_available():
logger.info("ℹ️ Transformers not available - using fallback mode")
return False
# If transformers installed but not HF Space, check GPU or explicit flag
use_ai = os.getenv("USE_AI_MODELS", "").lower() == "true" or self.has_gpu()
if use_ai:
logger.info("✅ AI models enabled (GPU or USE_AI_MODELS=true)")
else:
logger.info("ℹ️ AI models disabled (no GPU, set USE_AI_MODELS=true to force)")
return use_ai
def get_device(self) -> str:
"""Get the device to use for AI models"""
if self.has_gpu():
return "cuda"
return "cpu"
def get_environment_info(self) -> Dict[str, Any]:
"""Get comprehensive environment information"""
info = {
"platform": platform.system(),
"python_version": platform.python_version(),
"is_huggingface_space": self.is_huggingface_space(),
"torch_available": self.is_torch_available(),
"transformers_available": self.is_transformers_available(),
"gpu_available": self.has_gpu(),
"device": self.get_device() if self.is_torch_available() else "none",
"should_use_ai": self.should_use_ai_models()
}
# Add GPU details if available
if self.has_gpu():
try:
import torch
info["gpu_name"] = torch.cuda.get_device_name(0)
info["gpu_count"] = torch.cuda.device_count()
info["cuda_version"] = torch.version.cuda
except:
pass
# Add HF Space info if available
if self.is_huggingface_space():
info["space_id"] = os.getenv("SPACE_ID", "unknown")
info["space_author"] = os.getenv("SPACE_AUTHOR_NAME", "unknown")
return info
def log_environment(self):
"""Log environment information"""
info = self.get_environment_info()
logger.info("=" * 70)
logger.info("🔍 ENVIRONMENT DETECTION:")
logger.info(f" Platform: {info['platform']}")
logger.info(f" Python: {info['python_version']}")
logger.info(f" HuggingFace Space: {'Yes' if info['is_huggingface_space'] else 'No'}")
logger.info(f" PyTorch: {'Yes' if info['torch_available'] else 'No'}")
logger.info(f" Transformers: {'Yes' if info['transformers_available'] else 'No'}")
logger.info(f" GPU: {'Yes' if info['gpu_available'] else 'No'}")
if info['gpu_available'] and 'gpu_name' in info:
logger.info(f" GPU Name: {info['gpu_name']}")
logger.info(f" Device: {info['device']}")
logger.info(f" AI Models: {'Enabled' if info['should_use_ai'] else 'Disabled (using fallback)'}")
logger.info("=" * 70)
# Global instance
_env_detector = EnvironmentDetector()
def get_environment_detector() -> EnvironmentDetector:
"""Get global environment detector instance"""
return _env_detector
def is_huggingface_space() -> bool:
"""Quick check if running on HuggingFace Space"""
return _env_detector.is_huggingface_space()
def has_gpu() -> bool:
"""Quick check if GPU is available"""
return _env_detector.has_gpu()
def should_use_ai_models() -> bool:
"""Quick check if AI models should be used"""
return _env_detector.should_use_ai_models()
def get_device() -> str:
"""Get device for AI models"""
return _env_detector.get_device()
__all__ = [
'EnvironmentDetector',
'get_environment_detector',
'is_huggingface_space',
'has_gpu',
'should_use_ai_models',
'get_device'
]