NiWaRe commited on
Commit
2d37ec5
·
1 Parent(s): d1338b0

debug sub-module adding

Browse files
Files changed (2) hide show
  1. Dockerfile +6 -0
  2. app.py +120 -63
Dockerfile CHANGED
@@ -33,6 +33,12 @@ ENV WEAVE_SILENT=True
33
  ENV MCP_TRANSPORT=http
34
  ENV HOST=0.0.0.0
35
 
 
 
 
 
 
 
36
  # Expose port for HTTP transport
37
  EXPOSE 7860
38
 
 
33
  ENV MCP_TRANSPORT=http
34
  ENV HOST=0.0.0.0
35
 
36
+ # Set W&B cache directories to writable locations
37
+ ENV WANDB_CACHE_DIR=/tmp/.wandb_cache
38
+ ENV WANDB_CONFIG_DIR=/tmp/.wandb_config
39
+ ENV WANDB_DATA_DIR=/tmp/.wandb_data
40
+ ENV HOME=/tmp
41
+
42
  # Expose port for HTTP transport
43
  EXPOSE 7860
44
 
app.py CHANGED
@@ -2,7 +2,7 @@
2
  """
3
  HuggingFace Spaces entry point for the Weights & Biases MCP Server.
4
 
5
- This script runs the MCP server with streamable HTTP transport for HF Spaces.
6
  """
7
 
8
  import os
@@ -13,42 +13,77 @@ from pathlib import Path
13
  # Add the src directory to Python path
14
  sys.path.insert(0, str(Path(__file__).parent / "src"))
15
 
 
 
 
 
 
 
 
 
 
16
  from fastapi.responses import HTMLResponse
17
  from fastapi.middleware.cors import CORSMiddleware
18
- from mcp.server.fastmcp import FastMCP
19
-
20
- # Import and configure the MCP server components
21
- from wandb_mcp_server.server import (
22
- validate_and_get_api_key,
23
- setup_wandb_login,
24
- configure_wandb_logging,
25
- initialize_weave_tracing,
26
- register_tools,
27
- ServerMCPArgs
28
- )
29
- from wandb_mcp_server.utils import get_rich_logger
30
 
31
- # Configure logging for the app
32
  logging.basicConfig(
33
  level=logging.INFO,
34
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
35
  )
36
-
37
- logger = get_rich_logger("huggingface-spaces-app")
38
 
39
  # Read the index.html file content
40
  INDEX_HTML_PATH = Path(__file__).parent / "index.html"
41
  with open(INDEX_HTML_PATH, "r") as f:
42
  INDEX_HTML_CONTENT = f.read()
43
 
44
- def main():
45
- """Main entry point for HuggingFace Spaces."""
46
- logger.info("Starting Weights & Biases MCP Server on HuggingFace Spaces")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
 
48
- # Configure W&B logging behavior
 
49
  configure_wandb_logging()
50
 
51
- # Create minimal args for HF Spaces (always use HTTP transport)
52
  args = ServerMCPArgs(
53
  transport="http",
54
  host="0.0.0.0",
@@ -56,60 +91,82 @@ def main():
56
  wandb_api_key=os.environ.get("WANDB_API_KEY")
57
  )
58
 
59
- # Validate and get API key
60
  try:
61
  api_key = validate_and_get_api_key(args)
62
-
63
- # Perform W&B login
64
  setup_wandb_login(api_key)
65
-
66
- # Initialize Weave tracing for MCP tool calls
67
- weave_initialized = initialize_weave_tracing()
68
-
69
  logger.info("W&B API configured successfully")
70
- logger.info(f"Weave tracing: {'Enabled' if weave_initialized else 'Disabled'}")
71
  except ValueError as e:
72
  logger.warning(f"W&B API key not configured: {e}")
73
- logger.warning("MCP server will start but operations will fail without a valid API key")
74
- logger.warning("Please set WANDB_API_KEY in the Space's environment variables")
75
 
76
- # Create the MCP server
77
- logger.info("Creating MCP server for HTTP transport")
78
- mcp = FastMCP(
79
- "wandb-mcp-server",
80
- host="0.0.0.0",
81
- port=7860,
82
- stateless_http=True
83
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- # Register all W&B tools
86
- register_tools(mcp)
87
 
88
- # Add custom routes to the MCP server
89
- # FastMCP creates routes using decorators, we can add our own
90
- @mcp.get("/")
91
- async def index():
92
- """Serve the landing page."""
93
- return HTMLResponse(content=INDEX_HTML_CONTENT)
94
 
95
- @mcp.get("/health")
96
- async def health():
97
- """Health check endpoint."""
98
- wandb_configured = bool(os.environ.get("WANDB_API_KEY"))
99
- return {
100
- "status": "healthy",
101
- "service": "wandb-mcp-server",
102
- "wandb_configured": wandb_configured
103
- }
104
 
105
- logger.info("Landing page available at: /")
106
- logger.info("Health check available at: /health")
107
- logger.info("MCP endpoint (Streamable HTTP) available at: /mcp")
108
- logger.info(f"Starting server on 0.0.0.0:7860")
109
 
110
- # Run the MCP server with streamable-http transport
111
- # This will start the uvicorn server internally
112
- mcp.run(transport="streamable-http")
 
 
 
 
113
 
114
  if __name__ == "__main__":
115
  main()
 
2
  """
3
  HuggingFace Spaces entry point for the Weights & Biases MCP Server.
4
 
5
+ Simplified approach for HF Spaces deployment.
6
  """
7
 
8
  import os
 
13
  # Add the src directory to Python path
14
  sys.path.insert(0, str(Path(__file__).parent / "src"))
15
 
16
+ # Configure W&B directories for HF Spaces (must be done before importing wandb)
17
+ os.environ["WANDB_CACHE_DIR"] = "/tmp/.wandb_cache"
18
+ os.environ["WANDB_CONFIG_DIR"] = "/tmp/.wandb_config"
19
+ os.environ["WANDB_DATA_DIR"] = "/tmp/.wandb_data"
20
+ os.environ["HOME"] = "/tmp"
21
+ os.environ["WANDB_SILENT"] = "True"
22
+ os.environ["WEAVE_SILENT"] = "True"
23
+
24
+ from fastapi import FastAPI
25
  from fastapi.responses import HTMLResponse
26
  from fastapi.middleware.cors import CORSMiddleware
27
+ import uvicorn
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # Configure logging
30
  logging.basicConfig(
31
  level=logging.INFO,
32
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
33
  )
34
+ logger = logging.getLogger("huggingface-spaces-app")
 
35
 
36
  # Read the index.html file content
37
  INDEX_HTML_PATH = Path(__file__).parent / "index.html"
38
  with open(INDEX_HTML_PATH, "r") as f:
39
  INDEX_HTML_CONTENT = f.read()
40
 
41
+ # Create FastAPI app
42
+ app = FastAPI(
43
+ title="Weights & Biases MCP Server",
44
+ description="Model Context Protocol server for querying W&B data",
45
+ version="0.1.0"
46
+ )
47
+
48
+ # Add CORS middleware
49
+ app.add_middleware(
50
+ CORSMiddleware,
51
+ allow_origins=["*"],
52
+ allow_credentials=True,
53
+ allow_methods=["*"],
54
+ allow_headers=["*"],
55
+ )
56
+
57
+ @app.get("/", response_class=HTMLResponse)
58
+ async def index():
59
+ """Serve the landing page."""
60
+ return INDEX_HTML_CONTENT
61
+
62
+ @app.get("/health")
63
+ async def health():
64
+ """Health check endpoint."""
65
+ wandb_configured = bool(os.environ.get("WANDB_API_KEY"))
66
+ return {
67
+ "status": "healthy",
68
+ "service": "wandb-mcp-server",
69
+ "wandb_configured": wandb_configured
70
+ }
71
+
72
+ # Import and setup MCP functionality after basic app setup
73
+ try:
74
+ from wandb_mcp_server.server import (
75
+ validate_and_get_api_key,
76
+ setup_wandb_login,
77
+ configure_wandb_logging,
78
+ initialize_weave_tracing,
79
+ create_mcp_server,
80
+ ServerMCPArgs
81
+ )
82
 
83
+ # Setup W&B on import
84
+ logger.info("Initializing W&B configuration...")
85
  configure_wandb_logging()
86
 
 
87
  args = ServerMCPArgs(
88
  transport="http",
89
  host="0.0.0.0",
 
91
  wandb_api_key=os.environ.get("WANDB_API_KEY")
92
  )
93
 
 
94
  try:
95
  api_key = validate_and_get_api_key(args)
 
 
96
  setup_wandb_login(api_key)
 
 
 
 
97
  logger.info("W&B API configured successfully")
 
98
  except ValueError as e:
99
  logger.warning(f"W&B API key not configured: {e}")
100
+ logger.warning("Server will start but W&B operations will fail")
 
101
 
102
+ # Create MCP server instance
103
+ mcp_server = create_mcp_server("http", "0.0.0.0", 7860)
104
+
105
+ # Try to extract the FastAPI app from FastMCP and mount it
106
+ if hasattr(mcp_server, 'app'):
107
+ # Mount MCP app routes under /mcp
108
+ from fastapi import APIRouter
109
+ mcp_router = APIRouter(prefix="/mcp")
110
+
111
+ # Copy routes from MCP app to our router
112
+ if hasattr(mcp_server.app, 'routes'):
113
+ for route in mcp_server.app.routes:
114
+ if hasattr(route, 'endpoint') and hasattr(route, 'path'):
115
+ mcp_router.add_api_route(
116
+ path=route.path,
117
+ endpoint=route.endpoint,
118
+ methods=route.methods if hasattr(route, 'methods') else ["POST", "GET"],
119
+ )
120
+
121
+ app.include_router(mcp_router)
122
+ logger.info("MCP routes mounted at /mcp")
123
+ else:
124
+ # Fallback: Create simple MCP endpoint
125
+ @app.post("/mcp")
126
+ async def mcp_endpoint():
127
+ return {"message": "MCP server is running", "status": "ready"}
128
+
129
+ @app.get("/mcp")
130
+ async def mcp_sse():
131
+ from fastapi.responses import StreamingResponse
132
+ import json
133
+
134
+ async def event_stream():
135
+ yield f"data: {json.dumps({'status': 'connected'})}\n\n"
136
+
137
+ return StreamingResponse(event_stream(), media_type="text/event-stream")
138
+
139
+ logger.warning("Using fallback MCP endpoints")
140
 
141
+ except Exception as e:
142
+ logger.error(f"Error setting up MCP server: {e}")
143
 
144
+ # Provide fallback endpoints even if MCP setup fails
145
+ @app.post("/mcp")
146
+ async def mcp_fallback():
147
+ return {"error": "MCP server initialization failed", "details": str(e)}
 
 
148
 
149
+ @app.get("/mcp")
150
+ async def mcp_sse_fallback():
151
+ return {"error": "MCP SSE not available", "details": str(e)}
152
+
153
+ def main():
154
+ """Main entry point for HuggingFace Spaces."""
155
+ port = 7860
156
+ host = "0.0.0.0"
 
157
 
158
+ logger.info(f"Starting server on {host}:{port}")
159
+ logger.info("Landing page: /")
160
+ logger.info("Health check: /health")
161
+ logger.info("MCP endpoint: /mcp")
162
 
163
+ uvicorn.run(
164
+ app,
165
+ host=host,
166
+ port=port,
167
+ log_level="info",
168
+ reload=False
169
+ )
170
 
171
  if __name__ == "__main__":
172
  main()