PyscoutAI / hf_utils.py
PyScoutAI's picture
Upload 15 files
ead2510 verified
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()}")