""" AUTHOR: Khushal P Soonderji DATE: monday, 23rd Dec., 2024 OBJECTIVE: To provide a SocketIO app for socket-base communication with the front-end. REFERENCES: 01. YouTube: https://www.youtube.com/watch?v=H1eLJMC5oTg&t=3s DOWNLOADS: N/A """ import datetime # ***************************************************************************************************************** # ***** **** # *** IMPORT *** # ***** **** # ***************************************************************************************************************** # To make sibling directories accessible for imports: import sys sys.path.append(".") sys.path.append("..") # System-level activities: import io import os # my utils: from utils_v2.string import json # To work with SocketIO: import socketio import eventlet # For asynchronous activities: import asyncio # for debugging: from icecream import IceCreamDebugger # To work with date and time: import time # To work with Zerodha's Kite platform: from kiteconnect import KiteConnect, KiteTicker # ***************************************************************************************************************** # ***** **** # *** MACROS / ONE-TIME INIT *** # ***** **** # ***************************************************************************************************************** INSTRUMENT_MAP = { 256265: "NIFTY 50", 260617: "NIFTY 100", 259849: "NIFTY IT", 341249: "HDFCBANK", 738561: "RELIANCE", 408065: "INFY", 2953217: "TCS", 356865: "HINDUNILVR", 1270529: "ICICIBANK", 492033: "KOTAKBANK", 110630919: "GOLD25JAN75800CE", 110050823: "SILVER25FEB76000CE", 10670594: "NIFTY24DEC23650PE", 17167874: "BANKNIFTY24DEC45000PE", } INSTRUMENT_TOKENS = list(INSTRUMENT_MAP.keys()) # ***************************************************************************************************************** # ***** **** # *** VARIABLES *** # ***** **** # ***************************************************************************************************************** # The SocketIo server: sio = socketio.Server(cors_allowed_origins = "*") app = socketio.WSGIApp(sio) # Debugging: printer = IceCreamDebugger(prefix = "SocketIO | ", includeContext = True) # ***************************************************************************************************************** # ***** **** # *** FUNCTIONS *** # ***** **** # ***************************************************************************************************************** @sio.event def connect(sid, environ): printer(sid) # --------------------------------------------------------------------------------------------------------------------- @sio.event def disconnect(sid): printer(sid) # --------------------------------------------------------------------------------------------------------------------- def on_ticks(ws, ticks): try: # print(json.to_string(ticks[0], default=str)) printer(len(ticks)) now = datetime.datetime.now() for t in ticks: t["last_trade_time"] = t.get("last_trade_time", now).strftime("%Y-%m-%d %H:%M:%S") t["exchange_timestamp"] = t.get("exchange_timestamp", now).strftime("%Y-%m-%d %H:%M:%S") sio.emit("ticks", ticks) sio.emit("ticks", {"name": "Bhopli"}) sio.emit("debug", {"name": "Debugger Bhopli"}) except Exception as exception: printer(exception) # --------------------------------------------------------------------------------------------------------------------- def on_connect(ws, response): ws.subscribe(INSTRUMENT_TOKENS) ws.set_mode(ws.MODE_FULL, INSTRUMENT_TOKENS) printer("Subscribed to token(s) in 'Full' mode", len(INSTRUMENT_TOKENS)) # --------------------------------------------------------------------------------------------------------------------- def start_live_feed_input( api_key: str, access_token: str, ): kite_ws = KiteTicker( api_key = api_key, access_token = access_token ) # Assign the callbacks: kite_ws.on_ticks = on_ticks # kite_ws.on_close = on_close # kite_ws.on_error = on_error kite_ws.on_connect = on_connect # kite_ws.on_reconnect = on_reconnect # kite_ws.on_noreconnect = on_noreconnect # If you choose to go threaded, you will need to work purely with callbacks. # You will need to have an infinite loop in the main thread. kite_ws.connect(threaded = True) # --------------------------------------------------------------------------------------------------------------------- @sio.event def subscribe(sid, data): printer(data) sio.emit("echo", data) # ***************************************************************************************************************** # ***** **** # *** MAIN PROGRAM *** # ***** **** # ***************************************************************************************************************** if __name__ == "__main__": # Connect to Zerodha: creds = json.from_file(r"../creds/zerodha/api.json") start_live_feed_input( api_key = creds["apiKey"], access_token = creds["accessToken"] ) eventlet.wsgi.server(eventlet.listen(("0.0.0.0", 5214)), app)