Upload app.py with huggingface_hub
Browse files
app.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
HuggingFace Spaces entry point for Garmin Agents web application.
|
| 3 |
+
|
| 4 |
+
This file serves as the deployment template for HuggingFace Spaces. During deployment,
|
| 5 |
+
it should be copied to the repository root as app.py.
|
| 6 |
+
|
| 7 |
+
HuggingFace Spaces expects:
|
| 8 |
+
- app.py at repository root
|
| 9 |
+
- requirements.txt at repository root
|
| 10 |
+
- All application code accessible from app.py
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
import json
|
| 14 |
+
import os
|
| 15 |
+
import tempfile
|
| 16 |
+
|
| 17 |
+
# Handle Google Cloud credentials from HF Spaces secret
|
| 18 |
+
# HF Spaces stores service account JSON as string in GOOGLE_CREDENTIALS_JSON secret
|
| 19 |
+
if creds_json := os.getenv("GOOGLE_CREDENTIALS_JSON"):
|
| 20 |
+
try:
|
| 21 |
+
# Parse JSON string and write to temporary file
|
| 22 |
+
credentials_data = json.loads(creds_json)
|
| 23 |
+
with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json") as f:
|
| 24 |
+
json.dump(credentials_data, f)
|
| 25 |
+
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = f.name
|
| 26 |
+
print("β Google Cloud credentials configured from HF Spaces secret")
|
| 27 |
+
except json.JSONDecodeError as e:
|
| 28 |
+
print(f"β οΈ Failed to parse GOOGLE_CREDENTIALS_JSON: {e}")
|
| 29 |
+
print("Please ensure the secret contains valid JSON")
|
| 30 |
+
|
| 31 |
+
# Set production environment variables
|
| 32 |
+
os.environ.setdefault("DATABASE_TYPE", "firestore")
|
| 33 |
+
os.environ.setdefault("ENABLE_AUTH", "true")
|
| 34 |
+
os.environ.setdefault("ENVIRONMENT", "production")
|
| 35 |
+
|
| 36 |
+
# Verify required environment variables
|
| 37 |
+
required_vars = {
|
| 38 |
+
"GOOGLE_CLOUD_PROJECT": "GCP project ID for Firestore",
|
| 39 |
+
"CHAT_AGENT_MODEL": "AI model specification (e.g., hf:meta-llama/Llama-3.2-3B-Instruct)",
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
missing_vars = []
|
| 43 |
+
for var_name, var_description in required_vars.items():
|
| 44 |
+
if not os.getenv(var_name):
|
| 45 |
+
missing_vars.append(f" - {var_name}: {var_description}")
|
| 46 |
+
|
| 47 |
+
if missing_vars:
|
| 48 |
+
error_msg = "β Missing required environment variables:\n" + "\n".join(missing_vars)
|
| 49 |
+
print(error_msg)
|
| 50 |
+
print("\nPlease configure these in HuggingFace Spaces Settings β Variables")
|
| 51 |
+
raise RuntimeError(error_msg)
|
| 52 |
+
|
| 53 |
+
# Import and launch the web application
|
| 54 |
+
try:
|
| 55 |
+
from garmin_web.app import create_interface, setup_agent, setup_authentication, setup_telemetry
|
| 56 |
+
from garmin_web.config.app_config import get_app_config
|
| 57 |
+
|
| 58 |
+
print("πββοΈ Starting Garmin AI Coach on HuggingFace Spaces...")
|
| 59 |
+
|
| 60 |
+
# Get configuration
|
| 61 |
+
config = get_app_config()
|
| 62 |
+
|
| 63 |
+
# Setup telemetry
|
| 64 |
+
setup_telemetry()
|
| 65 |
+
|
| 66 |
+
# Setup authentication if enabled
|
| 67 |
+
if config.enable_auth:
|
| 68 |
+
print("π Multi-user authentication enabled")
|
| 69 |
+
setup_authentication(config)
|
| 70 |
+
else:
|
| 71 |
+
print("β οΈ Running in single-user mode")
|
| 72 |
+
|
| 73 |
+
# Get model from environment
|
| 74 |
+
model_spec = os.getenv("CHAT_AGENT_MODEL", "hf:meta-llama/Llama-3.2-3B-Instruct")
|
| 75 |
+
print(f"π€ Using model: {model_spec}")
|
| 76 |
+
|
| 77 |
+
# Initialize agent
|
| 78 |
+
setup_agent(model_spec)
|
| 79 |
+
|
| 80 |
+
# Create Gradio interface
|
| 81 |
+
demo = create_interface()
|
| 82 |
+
|
| 83 |
+
print("β
Application initialized successfully")
|
| 84 |
+
|
| 85 |
+
# Launch the interface
|
| 86 |
+
# HuggingFace Spaces automatically handles the server configuration
|
| 87 |
+
if __name__ == "__main__":
|
| 88 |
+
demo.launch()
|
| 89 |
+
|
| 90 |
+
except ImportError as e:
|
| 91 |
+
error_msg = f"β Failed to import application modules: {e}"
|
| 92 |
+
print(error_msg)
|
| 93 |
+
print("Ensure all workspace packages are included in deployment")
|
| 94 |
+
raise
|
| 95 |
+
except Exception as e:
|
| 96 |
+
error_msg = f"β Failed to initialize application: {e}"
|
| 97 |
+
print(error_msg)
|
| 98 |
+
raise
|