web_interface.py•9.27 kB
from fastapi import FastAPI, Request, Form
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi.staticfiles import StaticFiles
import uvicorn
import asyncio
from server.weather import get_alerts, echo_resource
app = FastAPI(title="Weather MCP Server Interface")
# Create a simple HTML template
html_template = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather MCP Server Interface</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 15px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
font-weight: 300;
}
.header p {
font-size: 1.1em;
opacity: 0.9;
}
.content {
padding: 40px;
}
.tool-section {
margin-bottom: 40px;
padding: 25px;
border: 1px solid #e1e5e9;
border-radius: 10px;
background: #f8f9fa;
}
.tool-section h2 {
color: #2c3e50;
margin-bottom: 20px;
font-size: 1.5em;
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
color: #34495e;
font-weight: 600;
}
input[type="text"] {
width: 100%;
padding: 12px;
border: 2px solid #e1e5e9;
border-radius: 8px;
font-size: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
}
button {
background: linear-gradient(135deg, #3498db, #2980b9);
color: white;
border: none;
padding: 12px 25px;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(52, 152, 219, 0.4);
}
.result {
margin-top: 20px;
padding: 20px;
background: white;
border-radius: 8px;
border-left: 4px solid #3498db;
white-space: pre-wrap;
font-family: 'Courier New', monospace;
max-height: 400px;
overflow-y: auto;
}
.error {
border-left-color: #e74c3c;
background: #fdf2f2;
color: #c0392b;
}
.success {
border-left-color: #27ae60;
background: #f0f9f4;
color: #27ae60;
}
.loading {
text-align: center;
color: #7f8c8d;
font-style: italic;
}
.examples {
margin-top: 15px;
font-size: 0.9em;
color: #7f8c8d;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🌤️ Weather MCP Server</h1>
<p>Interactive interface for weather alerts and tools</p>
</div>
<div class="content">
<div class="tool-section">
<h2>📡 Get Weather Alerts</h2>
<form id="alertsForm">
<div class="form-group">
<label for="state">US State Code:</label>
<input type="text" id="state" name="state" placeholder="e.g., CA, NY, TX" required>
<div class="examples">Examples: CA (California), NY (New York), TX (Texas)</div>
</div>
<button type="submit">Get Alerts</button>
</form>
<div id="alertsResult" class="result" style="display: none;"></div>
</div>
<div class="tool-section">
<h2>🔊 Echo Resource</h2>
<form id="echoForm">
<div class="form-group">
<label for="message">Message:</label>
<input type="text" id="message" name="message" placeholder="Enter a message to echo" required>
</div>
<button type="submit">Echo Message</button>
</form>
<div id="echoResult" class="result" style="display: none;"></div>
</div>
</div>
</div>
<script>
document.getElementById('alertsForm').addEventListener('submit', async function(e) {
e.preventDefault();
const state = document.getElementById('state').value;
const resultDiv = document.getElementById('alertsResult');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<div class="loading">Fetching weather alerts...</div>';
resultDiv.className = 'result';
try {
const response = await fetch('/api/alerts', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `state=${encodeURIComponent(state)}`
});
const data = await response.json();
if (data.success) {
resultDiv.innerHTML = data.result;
resultDiv.className = 'result success';
} else {
resultDiv.innerHTML = `Error: ${data.error}`;
resultDiv.className = 'result error';
}
} catch (error) {
resultDiv.innerHTML = `Error: ${error.message}`;
resultDiv.className = 'result error';
}
});
document.getElementById('echoForm').addEventListener('submit', async function(e) {
e.preventDefault();
const message = document.getElementById('message').value;
const resultDiv = document.getElementById('echoResult');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<div class="loading">Processing echo...</div>';
resultDiv.className = 'result';
try {
const response = await fetch('/api/echo', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `message=${encodeURIComponent(message)}`
});
const data = await response.json();
if (data.success) {
resultDiv.innerHTML = data.result;
resultDiv.className = 'result success';
} else {
resultDiv.innerHTML = `Error: ${data.error}`;
resultDiv.className = 'result error';
}
} catch (error) {
resultDiv.innerHTML = `Error: ${error.message}`;
resultDiv.className = 'result error';
}
});
</script>
</body>
</html>
"""
@app.get("/", response_class=HTMLResponse)
async def home():
return HTMLResponse(content=html_template)
@app.post("/api/alerts")
async def api_get_alerts(state: str = Form(...)):
try:
result = await get_alerts(state.upper())
return {"success": True, "result": result}
except Exception as e:
return {"success": False, "error": str(e)}
@app.post("/api/echo")
async def api_echo(message: str = Form(...)):
try:
result = echo_resource(message)
return {"success": True, "result": result}
except Exception as e:
return {"success": False, "error": str(e)}
def run_web_interface():
"""Run the web interface server"""
print("Starting web interface on http://localhost:8000")
uvicorn.run(app, host="0.0.0.0", port=8000)
if __name__ == "__main__":
run_web_interface()