""" Environment Detection Utilities This module provides utilities to detect the deployment environment and configure authentication accordingly. """ import os from typing import Dict, Any, Optional def is_huggingface_space() -> bool: """ Detect if the application is running in Hugging Face Spaces. Returns: bool: True if running in HF Spaces, False otherwise """ # HF Spaces sets specific environment variables hf_indicators = [ "SPACE_ID", # HF Space identifier "SPACE_AUTHOR_NAME", # Space author "SPACE_REPO_NAME", # Space repository name "OAUTH_CLIENT_ID", # OAuth client ID (when oauth enabled) ] return any(os.getenv(indicator) for indicator in hf_indicators) def is_local_development() -> bool: """ Detect if the application is running in local development mode. Returns: bool: True if running locally, False otherwise """ return not is_huggingface_space() def get_environment_info() -> Dict[str, Any]: """ Get comprehensive environment information. Returns: Dict containing environment details """ env_info = { "is_hf_space": is_huggingface_space(), "is_local_dev": is_local_development(), "space_id": os.getenv("SPACE_ID"), "space_author": os.getenv("SPACE_AUTHOR_NAME"), "space_repo": os.getenv("SPACE_REPO_NAME"), "oauth_enabled": bool(os.getenv("OAUTH_CLIENT_ID")), "host": os.getenv("HOST", "localhost"), "port": os.getenv("PORT", "7860"), } return env_info def should_enable_auth() -> bool: """ Determine if authentication should be enabled based on environment. Returns: bool: True if auth should be enabled, False otherwise """ return is_huggingface_space() def get_oauth_config() -> Optional[Dict[str, str]]: """ Get OAuth configuration if available. Returns: Dict with OAuth config or None if not available """ if not should_enable_auth(): return None # Force HF-compatible scope for HF Spaces, ignore environment variable if is_huggingface_space(): # HF automatically includes 'openid profile', we specify additional scopes scopes = "openid profile read-repos" else: scopes = os.getenv("OAUTH_SCOPES", "read-repos") # Warn about unsupported scopes for HF Spaces if is_huggingface_space(): unsupported_scopes = [] for scope in scopes.split(): if scope not in ["email", "read-repos", "write-repos", "manage-repos", "read-mcp", "write-discussions", "read-billing", "inference-api", "jobs", "webhooks"]: unsupported_scopes.append(scope) if unsupported_scopes: print(f"⚠️ Warning: Unsupported OAuth scopes detected: {unsupported_scopes}") print("📝 Supported HF scopes: email, read-repos, write-repos, manage-repos, read-mcp, write-discussions, read-billing, inference-api, jobs, webhooks") oauth_config = { "client_id": os.getenv("OAUTH_CLIENT_ID"), "client_secret": os.getenv("OAUTH_CLIENT_SECRET"), "scopes": scopes, "provider_url": os.getenv("OPENID_PROVIDER_URL", "https://huggingface.co"), } # Only return config if client_id is available if oauth_config["client_id"]: return oauth_config return None def debug_environment() -> None: """ Print debug information about the current environment. """ env_info = get_environment_info() oauth_config = get_oauth_config() print("🌍 Environment Debug Information:") print("=" * 50) print(f"🏗️ Environment Type: {'HF Spaces' if env_info['is_hf_space'] else 'Local Development'}") print(f"🔐 Authentication: {'Enabled' if should_enable_auth() else 'Disabled'}") if env_info['is_hf_space']: print(f"🆔 Space ID: {env_info['space_id']}") print(f"👤 Author: {env_info['space_author']}") print(f"📦 Repo: {env_info['space_repo']}") if oauth_config: print(f"🔑 OAuth Client ID: {oauth_config['client_id'][:8]}..." if oauth_config['client_id'] else "Not set") print(f"🔒 OAuth Scopes: {oauth_config['scopes']}") else: print("❌ OAuth not configured") else: print("🏠 Running in local development mode") print("💡 Authentication will be automatically enabled when deployed to HF Spaces") print("=" * 50)