Jofthomas HF Staff commited on
Commit
8e3a76a
·
verified ·
1 Parent(s): f89ad20

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +97 -2
main.py CHANGED
@@ -7,6 +7,7 @@ import time
7
  import traceback
8
  import logging
9
  from typing import List, Dict, Optional, Set
 
10
 
11
  from fastapi import FastAPI, WebSocket, WebSocketDisconnect
12
  from fastapi.responses import HTMLResponse
@@ -26,6 +27,7 @@ CUSTOM_ACTION_URL = 'https://play.pokemonshowdown.com/action.php?'
26
  CUSTOM_BATTLE_VIEW_URL_TEMPLATE = "https://jofthomas.com/play.pokemonshowdown.com/testclient.html#{battle_id}"
27
  custom_config = ServerConfiguration(CUSTOM_SERVER_URL, CUSTOM_ACTION_URL)
28
  DEFAULT_BATTLE_FORMAT = "gen9randombattle"
 
29
 
30
  # Define available agents with their corresponding classes
31
  AGENT_CONFIGS = {
@@ -537,6 +539,7 @@ async def get_homepage():
537
  """Serves the main HTML page with WebSocket connection and improved styling."""
538
  # NOTE: Ensure the static path '/static/pokemon_huggingface.png' is correct
539
  # and the image exists in a 'static' folder next to your main.py
 
540
  return """
541
  <!DOCTYPE html>
542
  <html lang="en">
@@ -716,6 +719,88 @@ async def get_homepage():
716
  </html>
717
  """
718
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
719
  @app.websocket("/ws")
720
  async def websocket_endpoint(websocket: WebSocket):
721
  await manager.connect(websocket)
@@ -756,6 +841,16 @@ async def startup_event():
756
  app.mount("/static", StaticFiles(directory=static_dir), name="static")
757
  print(f"Mounted static directory '{static_dir}' at '/static'")
758
 
 
 
 
 
 
 
 
 
 
 
759
  print("🚀 Starting background tasks")
760
  # Start the main lifecycle manager task
761
  background_task_handle = asyncio.create_task(manage_agent_lifecycle(), name="LifecycleManager")
@@ -844,6 +939,7 @@ if __name__ == "__main__":
844
  print(f" - {name}")
845
  print("="*60)
846
  print(f"Server will run on http://0.0.0.0:7860")
 
847
  print("="*60)
848
 
849
  # Run with uvicorn
@@ -853,5 +949,4 @@ if __name__ == "__main__":
853
  port=7860,
854
  reload=False, # Disable reload for production/stable testing
855
  log_level="info" # Uvicorn's log level
856
- )
857
-
 
7
  import traceback
8
  import logging
9
  from typing import List, Dict, Optional, Set
10
+ import html # --- ADDED FOR /last_action --- (HTML escaping)
11
 
12
  from fastapi import FastAPI, WebSocket, WebSocketDisconnect
13
  from fastapi.responses import HTMLResponse
 
27
  CUSTOM_BATTLE_VIEW_URL_TEMPLATE = "https://jofthomas.com/play.pokemonshowdown.com/testclient.html#{battle_id}"
28
  custom_config = ServerConfiguration(CUSTOM_SERVER_URL, CUSTOM_ACTION_URL)
29
  DEFAULT_BATTLE_FORMAT = "gen9randombattle"
30
+ LAST_ACTION_FILE = "last_action.txt" # --- ADDED FOR /last_action --- (Filename)
31
 
32
  # Define available agents with their corresponding classes
33
  AGENT_CONFIGS = {
 
539
  """Serves the main HTML page with WebSocket connection and improved styling."""
540
  # NOTE: Ensure the static path '/static/pokemon_huggingface.png' is correct
541
  # and the image exists in a 'static' folder next to your main.py
542
+ # (Existing HTML content remains unchanged)
543
  return """
544
  <!DOCTYPE html>
545
  <html lang="en">
 
719
  </html>
720
  """
721
 
722
+ # --- ADDED FOR /last_action --- START ---
723
+ @app.get("/last_action", response_class=HTMLResponse)
724
+ async def get_last_action():
725
+ """Serves a simple HTML page displaying the content of last_action.txt."""
726
+ file_content_raw = ""
727
+ error_message = None
728
+ try:
729
+ # Read the file content fresh on each request
730
+ with open(LAST_ACTION_FILE, "r", encoding="utf-8") as f:
731
+ file_content_raw = f.read()
732
+ except FileNotFoundError:
733
+ error_message = f"Error: The file '{LAST_ACTION_FILE}' was not found in the application directory."
734
+ print(f"WARN: {error_message}") # Log server-side
735
+ except Exception as e:
736
+ error_message = f"An unexpected error occurred while reading '{LAST_ACTION_FILE}': {e}"
737
+ print(f"ERROR: {error_message}") # Log server-side
738
+ traceback.print_exc() # Log full traceback for debugging
739
+
740
+ # Escape the raw content to prevent XSS if the file contains HTML/JS
741
+ # Display error message if reading failed
742
+ display_content = html.escape(file_content_raw) if not error_message else error_message
743
+
744
+ # Create the simple HTML response
745
+ html_output = f"""
746
+ <!DOCTYPE html>
747
+ <html lang="en">
748
+ <head>
749
+ <meta charset="UTF-8">
750
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
751
+ <title>Last Action Log</title>
752
+ <style>
753
+ body {{
754
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
755
+ line-height: 1.6;
756
+ padding: 25px;
757
+ background-color: #f8f9fa;
758
+ color: #212529;
759
+ margin: 0;
760
+ }}
761
+ h1 {{
762
+ color: #0d6efd; /* Bootstrap primary blue */
763
+ border-bottom: 2px solid #dee2e6;
764
+ padding-bottom: 10px;
765
+ margin-top: 0;
766
+ }}
767
+ pre {{
768
+ background-color: #ffffff;
769
+ border: 1px solid #ced4da;
770
+ border-radius: 5px;
771
+ padding: 20px;
772
+ white-space: pre-wrap; /* Allows text to wrap */
773
+ word-wrap: break-word; /* Breaks long words */
774
+ font-family: Consolas, 'Courier New', monospace;
775
+ font-size: 0.95em;
776
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
777
+ margin-top: 20px;
778
+ color: #343a40; /* Darker text for contrast */
779
+ }}
780
+ .error {{
781
+ color: #dc3545; /* Bootstrap danger red */
782
+ font-weight: bold;
783
+ background-color: #f8d7da; /* Light red background */
784
+ border: 1px solid #f5c2c7;
785
+ padding: 15px;
786
+ border-radius: 5px;
787
+ }}
788
+ </style>
789
+ </head>
790
+ <body>
791
+ <h1>Last Recorded Action</h1>
792
+ {'<p class="error">' + error_message + '</p>' if error_message else '<pre>' + display_content + '</pre>'}
793
+ <script>
794
+ // Optional: Auto-refresh the page every N seconds
795
+ // setTimeout(() => window.location.reload(), 5000); // Refresh every 5 seconds
796
+ </script>
797
+ </body>
798
+ </html>
799
+ """
800
+ return HTMLResponse(content=html_output)
801
+ # --- ADDED FOR /last_action --- END ---
802
+
803
+
804
  @app.websocket("/ws")
805
  async def websocket_endpoint(websocket: WebSocket):
806
  await manager.connect(websocket)
 
841
  app.mount("/static", StaticFiles(directory=static_dir), name="static")
842
  print(f"Mounted static directory '{static_dir}' at '/static'")
843
 
844
+ # --- ADDED FOR /last_action --- Check if last_action.txt exists ---
845
+ if not os.path.exists(LAST_ACTION_FILE):
846
+ print(f"WARN: '{LAST_ACTION_FILE}' not found. Creating an empty file.")
847
+ try:
848
+ with open(LAST_ACTION_FILE, "w", encoding="utf-8") as f:
849
+ f.write("No actions recorded yet.")
850
+ except Exception as e:
851
+ print(f"ERROR: Could not create '{LAST_ACTION_FILE}': {e}")
852
+ # --- END ADDED SECTION ---
853
+
854
  print("🚀 Starting background tasks")
855
  # Start the main lifecycle manager task
856
  background_task_handle = asyncio.create_task(manage_agent_lifecycle(), name="LifecycleManager")
 
939
  print(f" - {name}")
940
  print("="*60)
941
  print(f"Server will run on http://0.0.0.0:7860")
942
+ print(f"Last action log available at http://0.0.0.0:7860/last_action") # --- ADDED INFO ---
943
  print("="*60)
944
 
945
  # Run with uvicorn
 
949
  port=7860,
950
  reload=False, # Disable reload for production/stable testing
951
  log_level="info" # Uvicorn's log level
952
+ )