import os import json import requests from typing import Dict, Optional, List, Any class HuggingFaceSpaceHelper: """Helper utilities for integrating with Hugging Face Spaces""" def __init__(self): self.hf_token = os.getenv("HF_TOKEN") self.space_name = os.getenv("HF_SPACE_NAME") self.is_in_space = self._is_huggingface_space() def _is_huggingface_space(self) -> bool: """Check if code is running in a Hugging Face Space""" return os.path.exists("/opt/conda/bin/python") and os.getenv("SPACE_ID") is not None def get_space_url(self) -> str: """Get the URL for the current HF space""" if not self.space_name: return "Not running in a named HF Space" return f"https://huggingface.co/spaces/{self.space_name}" def get_gradio_url(self) -> str: """Get the Gradio URL for the Space""" if not self.space_name: return "" return f"https://{self.space_name}.hf.space" def get_hostname(self) -> str: """Get the appropriate hostname for services in HF Spaces""" if self.is_in_space: # In HF Spaces, services on the same container are accessible via localhost return "localhost" return "0.0.0.0" # Default for local development def get_port_mapping(self) -> Dict[int, int]: """Get mappings for ports in HF spaces vs local environment""" # HF Spaces uses specific ports for various services return { 7860: 7860, # Default Gradio port, available publicly 8000: 8000, # FastAPI server, available within container 8001: 8001, # Additional services, available within container # Add more port mappings as needed } def get_hf_metadata(self) -> Dict[str, Any]: """Get metadata about the HF Space environment""" metadata = { "is_huggingface_space": self.is_in_space, "space_name": self.space_name, "space_url": self.get_space_url(), "gradio_url": self.get_gradio_url(), } # Add environment-specific info for HF Spaces if self.is_in_space: metadata.update({ "space_id": os.getenv("SPACE_ID"), "space_runtime": os.getenv("SPACE_RUNTIME"), "container_hostname": os.getenv("HOSTNAME"), "python_path": os.getenv("PYTHONPATH"), }) return metadata def get_env_file_path(self) -> str: """Get appropriate .env file path based on environment""" if self.is_in_space: return "/app/.env" # Default location in HF Spaces return ".env" # Local development def get_mongodb_uri(self) -> Optional[str]: """Get the MongoDB URI, potentially customized for HF Space environment""" # Use environment variable first mongo_uri = os.getenv("MONGODB_URI") # If not available and we're in a Space, try to use HF Spaces secrets if not mongo_uri and self.is_in_space: try: # HF Spaces stores secrets in a specific location from huggingface_hub import get_space_runtime runtime = get_space_runtime() mongo_uri = runtime.get_secret("MONGODB_URI") except: pass return mongo_uri def install_dependencies(self, packages: List[str]): """Install Python packages if needed (useful for HF Spaces)""" if not self.is_in_space: return # Skip in local environments import subprocess try: subprocess.check_call(["pip", "install", "--no-cache-dir"] + packages) print(f"Successfully installed: {', '.join(packages)}") except subprocess.CalledProcessError as e: print(f"Failed to install packages: {e}") if __name__ == "__main__": hf_helper = HuggingFaceSpaceHelper() print(json.dumps(hf_helper.get_hf_metadata(), indent=2)) print(f"MongoDB URI: {hf_helper.get_mongodb_uri() or 'Not configured'}") print(f"Environment file path: {hf_helper.get_env_file_path()}")