33import logging
44import os
55import time
6- from pathlib import Path
7- from typing import Dict , List , Optional , Set
6+ from typing import List , Optional
87from watchdog .events import FileSystemEventHandler , FileSystemEvent
98from watchdog .observers import Observer
109
1110import uvicorn
12- from fastapi import FastAPI , WebSocket , WebSocketDisconnect
13- from fastapi .staticfiles import StaticFiles
14- from fastapi .responses import FileResponse
11+ from fastapi import WebSocket , WebSocketDisconnect
1512
16- from .vite_server import ViteServer
13+ from eval_protocol .dataset_logger import default_logger
14+ from eval_protocol .utils .vite_server import ViteServer
15+
16+ default_logger
1717
1818logger = logging .getLogger (__name__ )
1919
@@ -22,7 +22,7 @@ class FileWatcher(FileSystemEventHandler):
2222 """File system watcher that tracks file changes."""
2323
2424 def __init__ (self , websocket_manager ):
25- self .websocket_manager = websocket_manager
25+ self .websocket_manager : WebSocketManager = websocket_manager
2626 self .ignored_patterns = {
2727 ".git" ,
2828 "__pycache__" ,
@@ -83,7 +83,21 @@ def disconnect(self, websocket: WebSocket):
8383
8484 def broadcast_file_update (self , update_type : str , file_path : str ):
8585 """Broadcast file update to all connected clients."""
86+ if not file_path .startswith (default_logger .datasets_dir ):
87+ return
88+
8689 message = {"type" : update_type , "path" : file_path , "timestamp" : time .time ()}
90+ # Include file contents for created and modified events
91+ if update_type in ["file_created" , "file_changed" ] and os .path .exists (file_path ):
92+ try :
93+ with open (file_path , "r" , encoding = "utf-8" ) as f :
94+ message ["contents" ] = f .read ()
95+ except Exception as e :
96+ logger .warning (f"Failed to read file contents for { file_path } : { e } " )
97+ message ["contents" ] = None
98+ elif update_type == "file_deleted" :
99+ message ["contents" ] = None
100+
87101 json_message = json .dumps (message )
88102
89103 # Broadcast to all active connections
@@ -194,9 +208,17 @@ async def run_async(self, reload: bool = False):
194208 # Store the event loop for WebSocket manager
195209 self .websocket_manager ._loop = asyncio .get_running_loop ()
196210
197- config = uvicorn .Config (self .app , host = self .host , port = self .port , reload = reload , log_level = "info" )
211+ config = uvicorn .Config (
212+ self .app ,
213+ host = self .host ,
214+ port = self .port ,
215+ reload = reload ,
216+ reload_dirs = self .watch_paths ,
217+ log_level = "info" ,
218+ )
198219 server = uvicorn .Server (config )
199220 await server .serve ()
221+
200222 except KeyboardInterrupt :
201223 logger .info ("Shutting down LogsServer..." )
202224 finally :
@@ -231,3 +253,7 @@ def serve_logs(
231253 """
232254 server = LogsServer (host = host , port = port , watch_paths = watch_paths )
233255 server .run (reload = reload )
256+
257+
258+ if __name__ == "__main__" :
259+ serve_logs (reload = True )
0 commit comments