Files
claude-code-monitor/backend/app/api/websocket_endpoint.py
felix.zoesch f6ef7ff5d3 Initial commit: Claude Code Monitor v1.0.0
Complete real-time monitoring dashboard for Claude Code

Features:
- FastAPI backend with REST API and WebSocket
- React + TypeScript frontend with dark theme
- SQLite database for event storage
- 6 hook scripts for Claude Code events
- Docker deployment setup
- Real-time event tracking and statistics
- Event filtering (ALL, TOOLS, AGENTS, PROMPTS, SESSIONS)
- Connection status indicator
- Reset stats functionality

Tech Stack:
- Backend: Python 3.11, FastAPI, SQLAlchemy, WebSockets
- Frontend: React 18, TypeScript, Vite
- Database: SQLite
- Deployment: Docker, Docker Compose

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-15 09:49:06 +01:00

66 lines
2.1 KiB
Python

"""WebSocket API endpoint for real-time updates."""
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends
from sqlalchemy.orm import Session
import logging
import json
from app.websocket import manager
from app.database import get_db
from app.crud import get_statistics
router = APIRouter(tags=["websocket"])
logger = logging.getLogger(__name__)
@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
"""
WebSocket endpoint for real-time event updates.
Clients connect to this endpoint to receive:
- New events as they're created
- Updated statistics
- Reset notifications
Message types:
- event_created: New event with updated statistics
- stats_updated: Statistics update
- stats_reset: All stats have been reset
- connection_status: Connection status message
"""
await manager.connect(websocket)
try:
# Send initial connection message
await manager.send_personal_message(
{"type": "connection_status", "message": "Connected to Claude Code Monitor"},
websocket,
)
# Keep connection alive and handle incoming messages
while True:
try:
# Receive messages from client (for future features like pings)
data = await websocket.receive_text()
message = json.loads(data)
# Handle ping/pong for connection health
if message.get("type") == "ping":
await manager.send_personal_message(
{"type": "pong", "timestamp": message.get("timestamp")},
websocket,
)
except WebSocketDisconnect:
logger.info("Client disconnected")
break
except Exception as e:
logger.error(f"Error handling WebSocket message: {e}")
# Don't break on error, continue listening
except Exception as e:
logger.error(f"WebSocket error: {e}")
finally:
manager.disconnect(websocket)