Jupter-Lab Startegy creator Scrap data Explore database

Wild Websockets

The first messages are the most important one...



This python code show simple and dirty way to get message from a websocket server, here an example with a well know finance website...

First check the messages received by the webbrowser :

Then use the correct client websockets module application:


  #!/usr/bin/env python
  #coding:utf-8
  
  import websocket, re, os, threading, time, rel, string, secrets
  from datetime import datetime
  from collections import deque
  from os.path import exists
  
  # relative import
  from sys import path;path.extend("..")
  from ScrapperConfig import ScrapperConfig
  from common.MyLogger.my_logger import MyLogger
  from common.Database.database import Database
  from common.Helpers.proxy import getWSSProxy
  
  class wsAppDispatcher:
  Name = "TradingView"
  def __init__(self, logger:MyLogger, config:ScrapperConfig, exchange, asset):
      self.Name += " : " + exchange + "|" + asset 
      self.ticker = exchange + ":" + asset 
      self.logger = logger
      self.config = config
      self.sID = self.generate_sId()
      self.MsgSent = None

  def __call__(*args):
      temp = args[0]
      temp.wsapp = args[1]
      if len(args)==2:
          temp.on_open()
      elif len(args)==3 and type(args[2])==str:
          temp.on_message(args[2])
      elif len(args)==3 and type(args[2])!=str:
          temp.on_message(args[2])
      elif len(args)==4:
          temp.on_close(args[2], args[3])
          exit()
      else:
          temp.logger.error("{0} unexpected error received while dispatching trading view wss message...".format(temp.name))
          pass

  def generate_sId(self):
      alphabet = string.ascii_letters + string.digits
      return "qs_" + ''.join(secrets.choice(alphabet) for i in range(12))

  def on_open(ws):
      ws.logger.info("{0} webSocket connection established on : '{1}'".format(ws.Name, ws.wsapp.url))
      
  def on_message(ws, message):
      msg = ""
      if ws.MsgSent is None:
          # set_auth_token 
          ws.MsgSent = "set_auth_token"
          msg = '~m~54~m~{"m":"'+ws.MsgSent+'","p":["unauthorized_user_token"]}'
          ws.wsapp.send(msg.encode())
          ws.logger.info("{0} websocket message sent '{1}'".format(ws.Name, msg))
      elif ws.MsgSent == "set_auth_token":
          # quote_create_session 
          ws.MsgSent = "quote_create_session"
          msg = '~m~52~m~{"m":"'+ws.MsgSent+'","p":["'+ws.sID+'"]}'
          ws.wsapp.send(msg.encode())     
          ws.logger.info("{0} websocket message sent '{1}'".format(ws.Name, msg))     
      elif ws.MsgSent == "quote_create_session" :
          # quote_add_symbols 
          ws.MsgSent = "quote_add_symbols"
          msg = '~m~63~m~{"m":"'+ws.MsgSent+'","p":["'+ws.sID+'","'+ws.ticker+'"]}'
          ws.wsapp.send(msg.encode()) 
          ws.logger.info("{0} websocket message sent '{1}'".format(ws.Name, msg))
      elif ws.MsgSent == "quote_add_symbols" and re.match(r'.+\{"m":"quote_completed","p":\["%s","%s"\]\}$'%(ws.sID, ws.ticker), message):
          write_to_file(message, ws)
          ws.logger.info("{0} '{1}' ticker datas received !".format(ws.Name, ws.ticker))
          ws.wsapp.close()
          ws.wsapp.keep_running = False
      else:
          ws.logger.info("{0} not expected websocket message received '{1}'".format(ws.Name, message))
          ws.wsapp.close()
          ws.wsapp.keep_running = False

  def on_error(ws, error):
      ws.logger.error("{0} error message received on websocket '{1}'".format(ws.name, error))

  def on_close(ws, close_status_code, close_msg):
      ws.logger.info("{0} connection closed ! '{1}' status '{2}'".format(ws.Name, (close_msg or "empty close_msg"), close_status_code))


class TradingView:
  Name = "TradingView"
  baseUrl = "wss://data.tradingview.com/socket.io"
  def __init__(self, logger, config, exchange, asset):
      linked_ws = wsAppDispatcher(logger, config, exchange, asset)
      ws = websocket.WebSocketApp("{0}/websocket?from=symbols%2F{2}-{3}%2Ffinancials-income-statement%2F&date={1}". \
                          format(self.baseUrl, datetime.utcnow().strftime("%Y_%m_%d-%H_%M"), exchange, asset),
                                      on_open=linked_ws,
                                      on_message=linked_ws,
                                      on_error=linked_ws,
                                      on_close=linked_ws)
      #proxy = next(WSS_PROXY_ITER)                        
      ws.run_forever(dispatcher=rel)#, http_proxy_host=proxy[0], http_proxy_port=proxy[1])
      rel.dispatch() 
      ws.keep_running