File size: 4,194 Bytes
ec4aa90 |
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 |
"""
Sandbox execution configuration.
Handles environment-specific settings for local vs Hugging Face deployment.
"""
import os
import logging
logger = logging.getLogger(__name__)
def is_huggingface_space() -> bool:
"""Detect if running in Hugging Face Spaces environment."""
return os.getenv("SPACE_ID") is not None or os.getenv("SYSTEM") == "spaces"
def is_modal_configured() -> bool:
"""Check if Modal is properly configured with credentials."""
# Check for Modal token in environment
token_id = os.getenv("MODAL_TOKEN_ID")
token_secret = os.getenv("MODAL_TOKEN_SECRET")
# Check if modal config exists
modal_config_exists = os.path.exists(os.path.expanduser("~/.modal.toml"))
return bool((token_id and token_secret) or modal_config_exists)
def get_execution_mode() -> str:
"""
Determine the execution mode based on environment.
Returns:
"modal" - Use Modal for execution (required for Hugging Face)
"local" - Use local subprocess execution
"auto" - Try Modal first, fallback to local
"""
# Explicit mode from environment
mode = os.getenv("EXECUTION_MODE", "").lower()
if mode in ("modal", "local", "auto"):
return mode
# Auto-detect based on environment
if is_huggingface_space():
# Hugging Face Spaces MUST use Modal
if is_modal_configured():
logger.info("Hugging Face Spaces detected - using Modal execution")
return "modal"
else:
logger.error("Hugging Face Spaces detected but Modal not configured!")
logger.error("Set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET environment variables")
return "modal" # Still return modal, will fail with clear error
# Local development - try Modal first, fallback to local
if is_modal_configured():
return "auto"
else:
logger.info("Modal not configured - using local execution")
return "local"
def should_prefer_modal() -> bool:
"""Determine if Modal should be preferred over local execution."""
mode = get_execution_mode()
if mode == "modal":
return True
elif mode == "local":
return False
else: # auto
return is_modal_configured()
def validate_environment():
"""
Validate that the environment is properly configured.
Raises warnings or errors for configuration issues.
"""
mode = get_execution_mode()
is_hf = is_huggingface_space()
modal_ok = is_modal_configured()
if is_hf and not modal_ok:
logger.error("=" * 60)
logger.error("CONFIGURATION ERROR: Hugging Face Spaces Deployment")
logger.error("=" * 60)
logger.error("Modal is REQUIRED for Hugging Face Spaces but not configured.")
logger.error("")
logger.error("To fix this:")
logger.error("1. Get Modal token from: https://modal.com/settings")
logger.error("2. Set Hugging Face Secrets:")
logger.error(" - MODAL_TOKEN_ID")
logger.error(" - MODAL_TOKEN_SECRET")
logger.error("3. Restart the Space")
logger.error("=" * 60)
return False
if mode == "modal" and not modal_ok:
logger.warning("Execution mode set to 'modal' but Modal not configured")
logger.warning("Tests will fail until Modal is configured")
return False
if mode == "local" and is_hf:
logger.warning("Local execution mode on Hugging Face Spaces will not work")
logger.warning("Change EXECUTION_MODE to 'modal'")
return False
# All good
logger.info(f"Environment validated: mode={mode}, huggingface={is_hf}, modal_configured={modal_ok}")
return True
# Configuration values
EXECUTION_MODE = get_execution_mode()
PREFER_MODAL = should_prefer_modal()
IS_HUGGINGFACE = is_huggingface_space()
MODAL_CONFIGURED = is_modal_configured()
# Log configuration on import
logger.info(f"Sandbox Configuration:")
logger.info(f" Execution Mode: {EXECUTION_MODE}")
logger.info(f" Prefer Modal: {PREFER_MODAL}")
logger.info(f" Hugging Face: {IS_HUGGINGFACE}")
logger.info(f" Modal Configured: {MODAL_CONFIGURED}")
|