Python-server / test.py
Srevarshan1502's picture
added
605b91b
Raw
History Blame Contribute Delete
5.58 kB
import asyncio
import websockets
import json
# Replace with your actual Space URL
# For Hugging Face Spaces, use wss://<your-space-id>.hf.space/ws
WS_URL = "wss://Srevarshan1502-collaborative-python-executor.hf.space/ws"
async def run_python_code(code_to_execute: str):
try:
async with websockets.connect(WS_URL) as websocket:
print("Connected to WebSocket.")
# Send the Python code
await websocket.send(json.dumps({"type": "code", "content": code_to_execute}))
print(f"Sent code:\n---\n{code_to_execute}\n---")
full_output = ""
execution_complete = False
while not execution_complete:
try:
# Keep waiting for messages until execution_complete
# Increased timeout to 60 seconds as per your last script
message = await asyncio.wait_for(websocket.recv(), timeout=60)
data = json.loads(message)
if data["type"] == "output":
full_output += data["content"]
print(f"Received output chunk: {data['content'].strip()}")
elif data["type"] == "input_request":
print("\n--- Input Requested ---")
user_input = input("Please enter input for the script: ")
# IMPORTANT: Add newline character for the server's readline() to process it as a complete line
await websocket.send(json.dumps({"type": "input", "content": user_input + "\n"}))
print(f"Sent input: {user_input}")
elif data["type"] == "execution_complete":
print("\n--- Execution Complete ---")
# The 'result' field from the server's execution_complete message
server_result = data['result']
print(f"Result details from server: {server_result}")
# Consolidate output from the server_result as well
if server_result.get('output'):
full_output += server_result['output']
if server_result.get('error'):
# Prepend "Error:" if it's the first error message
if "Error from server:" not in full_output:
full_output += "\nError from server:\n"
full_output += server_result['error']
execution_complete = True
elif data["type"] == "pong":
# print("Received pong.") # Optional: uncomment to see pongs
pass
else:
print(f"Received unknown message type: {data['type']} - {data.get('content')}")
except asyncio.TimeoutError:
print("Timeout: No message received from server for 60 seconds. Disconnecting.")
break
except websockets.exceptions.ConnectionClosedOK:
print("Connection closed by server (OK).")
# If it closes OK before execution_complete, it's an issue
if not execution_complete:
print("WARNING: Connection closed OK before execution_complete message was received!")
break
except websockets.exceptions.ConnectionClosedError as e:
print(f"Connection closed with error: {e}")
break
except json.JSONDecodeError:
print(f"Received invalid JSON: {message}")
break
except Exception as e:
print(f"An unexpected error occurred during message reception: {e}")
break
print("\n--- Final Consolidated Output ---")
print(full_output)
return full_output
except websockets.exceptions.InvalidURI as e:
print(f"Invalid WebSocket URI: {e}")
except ConnectionRefusedError:
print("Connection refused. Is the server running and accessible?")
except Exception as e:
print(f"Could not connect to WebSocket: {e}")
return None
if __name__ == "__main__":
# Test 1: Simple print statement (Matches the current app.py test 1)
print("\n=== Running Test 1: Simple Print ===")
asyncio.run(run_python_code(code_to_execute = "print('Hello, Space!')"))
# Test 2: Code with interactive input (corrected syntax)
print("\n=== Running Test 2: Interactive Input ===")
interactive_code = """
name = input("Enter your name: ")
age = int(input("How old are you? "))
print(f"Hello, {name}! You are {age} years old.")
"""
# For app.py's Test 2 (where exec is not yet active)
# asyncio.run(run_python_code(code_to_execute="DUMMY_CODE_FOR_TESTING_SYS_REDIRECTION"))
# Once app.py has Test 3 (with exec) uncomment this:
asyncio.run(run_python_code(interactive_code))
# Test 3: Code with error (uncomment when full exec is working)
# print("\n=== Running Test 3: Code with Error ===")
# asyncio.run(run_python_code("print(1/0)"))
# Test 4: Long-running code (will hit timeout if not finished, uncomment when full exec is working)
# print("\n=== Running Test 4: Long Running Code ===")
# asyncio.run(run_python_code("import time\nfor i in range(5):\n print(f'Counting: {i}')\n time.sleep(1)"))