NiWaRe commited on
Commit
ceeb737
·
1 Parent(s): 2504e6a

qrefactor to include main index route

Browse files
Files changed (1) hide show
  1. app.py +86 -33
app.py CHANGED
@@ -2,19 +2,28 @@
2
  """
3
  HuggingFace Spaces entry point for the Weights & Biases MCP Server.
4
 
5
- This script starts the MCP server in HTTP mode, making it accessible
6
- via Server-Sent Events (SSE) for remote MCP clients.
7
  """
8
 
9
  import os
10
  import sys
11
  import logging
12
  from pathlib import Path
 
13
 
14
  # Add the src directory to Python path
15
  sys.path.insert(0, str(Path(__file__).parent / "src"))
16
 
17
- from wandb_mcp_server.server import cli
 
 
 
 
 
 
 
 
18
  from wandb_mcp_server.utils import get_rich_logger
19
 
20
  # Configure logging for the app
@@ -25,43 +34,87 @@ logging.basicConfig(
25
 
26
  logger = get_rich_logger("huggingface-spaces-app")
27
 
28
- def main():
29
- """Main entry point for HuggingFace Spaces."""
 
 
 
30
  logger.info("Starting Weights & Biases MCP Server on HuggingFace Spaces")
31
 
32
- # Ensure we're running in HTTP mode for HuggingFace Spaces
33
- # Override command line arguments to force HTTP transport
34
- original_argv = sys.argv.copy()
35
- sys.argv = [
36
- sys.argv[0], # Keep the script name
37
- "--transport", "http",
38
- "--host", os.environ.get("HOST", "0.0.0.0"), # Listen on all interfaces for HuggingFace Spaces
39
- "--port", str(os.environ.get("PORT", "7860")) # Use PORT env var or default to 7860
40
- ]
41
-
42
  # Check for required environment variables
43
  wandb_api_key = os.environ.get("WANDB_API_KEY")
44
  if not wandb_api_key:
45
- logger.error("WANDB_API_KEY environment variable is required!")
46
- logger.error("Please set your Weights & Biases API key in the Space's environment variables.")
47
- logger.error("You can get your API key from: https://wandb.ai/authorize")
48
- sys.exit(1)
 
49
 
50
- logger.info(f"WANDB_API_KEY configured: {'Yes' if wandb_api_key else 'No'}")
51
  logger.info(f"Starting HTTP server on port {os.environ.get('PORT', '7860')}")
52
- logger.info("MCP endpoint will be available at: /mcp")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- try:
55
- # Call the CLI function which will start the server
56
- cli()
57
- except KeyboardInterrupt:
58
- logger.info("Server stopped by user")
59
- except Exception as e:
60
- logger.error(f"Server error: {e}", exc_info=True)
61
- sys.exit(1)
62
- finally:
63
- # Restore original argv
64
- sys.argv = original_argv
65
 
66
  if __name__ == "__main__":
67
- main()
 
2
  """
3
  HuggingFace Spaces entry point for the Weights & Biases MCP Server.
4
 
5
+ This script creates a FastAPI application with a landing page and mounts
6
+ the MCP server from the existing server module.
7
  """
8
 
9
  import os
10
  import sys
11
  import logging
12
  from pathlib import Path
13
+ from contextlib import asynccontextmanager
14
 
15
  # Add the src directory to Python path
16
  sys.path.insert(0, str(Path(__file__).parent / "src"))
17
 
18
+ from fastapi import FastAPI, Request
19
+ from fastapi.responses import HTMLResponse
20
+ from fastapi.staticfiles import StaticFiles
21
+ from fastapi.templating import Jinja2Templates
22
+ from fastapi.middleware.cors import CORSMiddleware
23
+ import uvicorn
24
+
25
+ # Import the existing MCP server instance and utilities
26
+ from wandb_mcp_server.server import mcp
27
  from wandb_mcp_server.utils import get_rich_logger
28
 
29
  # Configure logging for the app
 
34
 
35
  logger = get_rich_logger("huggingface-spaces-app")
36
 
37
+ # Lifecycle manager for the app
38
+ @asynccontextmanager
39
+ async def lifespan(app: FastAPI):
40
+ """Manage application lifecycle."""
41
+ # Startup
42
  logger.info("Starting Weights & Biases MCP Server on HuggingFace Spaces")
43
 
 
 
 
 
 
 
 
 
 
 
44
  # Check for required environment variables
45
  wandb_api_key = os.environ.get("WANDB_API_KEY")
46
  if not wandb_api_key:
47
+ logger.warning("WANDB_API_KEY environment variable is not set!")
48
+ logger.warning("Please set your Weights & Biases API key in the Space's environment variables.")
49
+ logger.warning("You can get your API key from: https://wandb.ai/authorize")
50
+ else:
51
+ logger.info("WANDB_API_KEY configured: Yes")
52
 
 
53
  logger.info(f"Starting HTTP server on port {os.environ.get('PORT', '7860')}")
54
+ logger.info("Landing page available at: /")
55
+ logger.info("MCP endpoint available at: /mcp/sse")
56
+
57
+ yield
58
+
59
+ # Shutdown
60
+ logger.info("Shutting down Weights & Biases MCP Server")
61
+
62
+ # Create FastAPI app with lifecycle management
63
+ app = FastAPI(
64
+ title="Weights & Biases MCP Server",
65
+ description="Model Context Protocol server for querying W&B data",
66
+ lifespan=lifespan
67
+ )
68
+
69
+ # Add CORS middleware
70
+ app.add_middleware(
71
+ CORSMiddleware,
72
+ allow_origins=["*"],
73
+ allow_credentials=True,
74
+ allow_methods=["*"],
75
+ allow_headers=["*"],
76
+ )
77
+
78
+ # Mount static files (create directory if it doesn't exist)
79
+ static_dir = Path(__file__).parent / "static"
80
+ static_dir.mkdir(exist_ok=True)
81
+ app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
82
+
83
+ # Set up templates
84
+ templates_dir = Path(__file__).parent / "templates"
85
+ templates = Jinja2Templates(directory=str(templates_dir))
86
+
87
+ @app.get("/", response_class=HTMLResponse)
88
+ async def index(request: Request):
89
+ """Serve the landing page."""
90
+ return templates.TemplateResponse("index.html", {"request": request})
91
+
92
+ @app.get("/health")
93
+ async def health():
94
+ """Health check endpoint."""
95
+ return {"status": "healthy", "service": "wandb-mcp-server"}
96
+
97
+ # Mount the existing MCP server at /mcp path
98
+ # The MCP server from server.py already has all tools registered
99
+ mcp.run(
100
+ transport="streamable-http",
101
+ http_app=app,
102
+ http_path="/mcp"
103
+ )
104
+
105
+ def main():
106
+ """Main entry point for HuggingFace Spaces."""
107
+ # Run the FastAPI app with Uvicorn
108
+ port = int(os.environ.get("PORT", "7860"))
109
+ host = os.environ.get("HOST", "0.0.0.0")
110
 
111
+ uvicorn.run(
112
+ "app:app",
113
+ host=host,
114
+ port=port,
115
+ log_level="info",
116
+ reload=False
117
+ )
 
 
 
 
118
 
119
  if __name__ == "__main__":
120
+ main()