websocket connection in Python
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 websocket
import json
import ssl
import threading
import time
if __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:
python
import websocket
import json
import ssl
import threading
import time
if __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))
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 callbacks
ws = 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 thread
def run_ws():
ws.run_forever()
# Start the WebSocket connection thread
thread = threading.Thread(target=run_ws)
thread.start()
# Keep the main thread alive
while True:
try:
time.sleep(1)
except KeyboardInterrupt:
ws.close()
thread.join()
break
By 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