vasanthfeb13's picture
Fix: Rename 'app' to 'api_app' to avoid Gradio SDK confusion
6104a7e
import os
import sys
import threading
import time
import uvicorn
from fastapi import FastAPI
import os
import sys
# --- MONKEY PATCH START ---
# Fix for: ImportError: cannot import name 'HfFolder' from 'huggingface_hub'
try:
import huggingface_hub
if not hasattr(huggingface_hub, "HfFolder"):
print("[NACC] Patching huggingface_hub.HfFolder for Gradio compatibility...")
class HfFolder:
@classmethod
def save_token(cls, token):
pass
@classmethod
def get_token(cls):
return os.getenv("HF_TOKEN")
huggingface_hub.HfFolder = HfFolder
except ImportError:
pass
# --- MONKEY PATCH END ---
import gradio as gr
from pathlib import Path
# Add src to path
sys.path.append(os.path.join(os.path.dirname(__file__), "src"))
from nacc_orchestrator.server import build_service, create_app
from nacc_orchestrator.config import NodeDefinition
from nacc_ui.professional_ui_v2 import create_professional_ui_v2 as create_ui
from nacc_node.tools import NodeServer
from nacc_node.config import NodeConfig
# 1. Build the Orchestrator Service
service = build_service()
# 2. Register the Local Node (Auto-Discovery for HF Space)
local_node_def = NodeDefinition(
node_id="hf-space-local",
transport="http",
base_url="http://127.0.0.1:8001",
display_name="Local Node (Demo)",
tags=["local", "demo", "linux"],
priority=10
)
service.registry.add_node(local_node_def)
print(f"βœ… Auto-registered local node: {local_node_def.node_id}")
# 3. Create the FastAPI App
orchestrator_app = create_app(service)
# 4. Create a combined FastAPI app
# 4. Create a combined FastAPI app (renamed to avoid Gradio SDK confusion)
api_app = FastAPI()
api_app.mount("/api", orchestrator_app)
def start_local_node():
"""Start a local node in the background for the HF Space demo."""
print("πŸš€ Starting local NACC Node for HF Space...")
try:
# Create a temporary config for the local node
config = NodeConfig(
node_id="hf-space-local",
root_dir=Path.cwd(),
display_name="Local Node (Demo)",
tags=["local", "demo"],
allowed_commands=[
"/bin/sh", "/bin/bash", # Shell access
"ls", "cat", "echo", "grep", "head", "tail", "pwd", "whoami",
"mkdir", "touch", "rm", "cp", "mv", # File operations
"python", "python3", "pip", "pip3", # Python
"curl", "wget", "git", # Network/Dev tools
"df", "du", "free", "top", "ps" # System info
],
sync_targets={}
)
# Start node on port 8001
server = NodeServer(config, host="127.0.0.1", port=8001)
server.serve_forever()
except Exception as e:
print(f"❌ Failed to start local node: {e}")
def start_orchestrator_api():
"""Start the orchestrator API in the background."""
print("🧠 Starting NACC Orchestrator API...")
uvicorn.run(orchestrator_app, host="127.0.0.1", port=8888)
# Start background services
# NOTE: For 'sdk: gradio', this must run at import time, not just in __main__
if not os.environ.get("NACC_SERVICES_STARTED"):
os.environ["NACC_SERVICES_STARTED"] = "1"
# 1. Start the Orchestrator API in a thread
api_thread = threading.Thread(target=start_orchestrator_api, daemon=True)
api_thread.start()
# 2. Start a Local Node in a thread (so the Space works out-of-the-box)
node_thread = threading.Thread(target=start_local_node, daemon=True)
node_thread.start()
# 3. Give services a moment to spin up
time.sleep(3)
# 4. Create the UI (Gradio will launch this)
print("πŸ’» Launching NACC UI...")
demo = create_ui()
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)