websocket connection in Python
17 Nov 2023, 07:13
Hi,
I am trying to connect Websocket in Python, I could not find any help other than WS API, no idea what kind of message to send for a subscription. Can anyone guide me? Below is my code which is not working, it just prints that “WebSocket connection opened”
import websocketimport jsonimport sslimport threadingimport timeif __name__ == '__main__': ws = None CLIENT_ID = 'x' SECRET = 'xx' CTRADER_ID = 'xx' # Define the WebSocket endpoint URL # websocket_url = "wss://api.ctrader.com/v1/socket" websocket_url = "wss://demo.ctraderapi.com:5035" # Define your Client ID and Secret client_id = CLIENT_ID client_secret = SECRET # Define the instrument you want to fetch data for instrument = "EURUSD" # Change this to your desired instrument # Define the subscription message subscribe_message = { "op": "subscribe", "topic": f"candles.{instrument}.1min", } # Define the authentication message auth_message = { "op": "auth", "apiKey": client_id, "secret": client_secret, } def on_message(ws, message): data = json.loads(message) print(data) # Check if the message is a candle update if data["op"] == "candle": candle = data["body"] print(f"Received candle: {candle}") def on_open(ws): print("WebSocket connection opened") # Send authentication message when the connection is opened ws.send(json.dumps(auth_message)) # Send the subscribe message to start receiving data ws.send(json.dumps(subscribe_message)) ssl_context = ssl.create_default_context() ssl_context.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_COMPRESSION | ssl.OP_CIPHER_SERVER_PREFERENCE | ssl.OP_NO_SSLv3 | ssl.OP_SINGLE_DH_USE | ssl.OP_SINGLE_ECDH_USE | ssl.OP_NO_TICKET ssl_context.set_ciphers( "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-CCM8:DHE-RSA-AES128-CCM:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-CCM8:AES256-CCM:AES128-CCM8:AES128-CCM:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA") # Create a WebSocket connection with on_open callback ws = websocket.WebSocketApp(websocket_url, on_message=on_message, on_open=on_open) # Run the WebSocket connection in a separate thread def run_ws(): ws.run_forever() # Start the WebSocket connection thread thread = threading.Thread(target=run_ws) thread.start() # Run the WebSocket connection # sslopt = {"ssl_context": ssl_context} # ws.run_forever(sslopt=sslopt) # # ws.run_forever() # Keep the main thread alive while True: try: time.sleep(1) except KeyboardInterrupt: ws.close() thread.join() break

williamfoley285
19 Jul 2024, 07:13 ( Updated at: 22 Jul 2024, 06:25 )
Hello @ poppy playtime chapter 3, I think you can add print statements or logging messages at various points in your code to help debug and track the flow of execution. You can print the received messages, any errors encountered, or other relevant information to aid in troubleshooting.
Here's an updated version of your code with minor modifications for error handling and logging:
pythonimport websocketimport jsonimport sslimport threadingimport timeif __name__ == '__main__':ws = NoneCLIENT_ID = 'x'SECRET = 'xx'CTRADER_ID = 'xx'# Define the WebSocket endpoint URL# websocket_url = "wss://api.ctrader.com/v1/socket"websocket_url = "wss://demo.ctraderapi.com:5035"# Define your Client ID and Secretclient_id = CLIENT_IDclient_secret = SECRET# Define the instrument you want to fetch data forinstrument = "EURUSD" # Change this to your desired instrument# Define the subscription messagesubscribe_message = {"op": "subscribe","topic": f"candles.{instrument}.1min",}# Define the authentication messageauth_message = {"op": "auth","apiKey": client_id,"secret": client_secret,}def on_message(ws, message):data = json.loads(message)print(data)# Check if the message is a candle updateif data["op"] == "candle":candle = data["body"]print(f"Received candle: {candle}")def on_open(ws):print("WebSocket connection opened")# Send authentication message when the connection is openedws.send(json.dumps(auth_message))# Send the subscribe message to start receiving dataws.send(json.dumps(subscribe_message))def on_error(ws, error):print(f"WebSocket error: {error}")def on_close(ws):print("WebSocket connection closed")ssl_context = ssl.create_default_context()# Add your SSL context options and ciphers if necessary# Create a WebSocket connection with on_open, on_message, on_error, and on_close callbacksws = websocket.WebSocketApp(websocket_url,on_message=on_message,on_open=on_open,on_error=on_error,on_close=on_close)# Run the WebSocket connection in a separate threaddef run_ws():ws.run_forever()# Start the WebSocket connection threadthread = threading.Thread(target=run_ws)thread.start()# Keep the main thread alivewhile True:try:time.sleep(1)except KeyboardInterrupt:ws.close()thread.join()breakBy incorporating these suggestions and carefully reviewing the WebSocket URL, authentication credentials, and subscription message, you should be able to establish a successful connection and receive data from the WebSocket. Remember to adjust the SSL context options and ciphers if necessary, depending on the server's requirements.
@williamfoley285