Programatically closing the Websocket

karthi289
Hi

I have implemented the following code in python for consuming websocket :
#####
from kiteconnect import KiteTicker
kws = KiteTicker(api_key, access_token)

tick_stock = [t['instrument_token']]
def on_ticks(ws, ticks):
# Callback to receive ticks.
print("Ticks: ",(ticks[0].get("last_price")), ticks[0].get("last_trade_time"))

def on_connect(ws, response):
# Callback on successful connect.
# Subscribe to a list of instrument_tokens (RELIANCE and ACC here).
ws.subscribe(tick_stock)
# Set RELIANCE to tick in `full` mode.
ws.set_mode(ws.MODE_FULL, tick_stock)
time.sleep(30)
ws.unsubscribe(tick_stock)
kws.close()


def on_close(ws, code, reason):
# On connection close stop the main loop
# Reconnection will not happen after executing `ws.stop()`
print("Closing ws connection: ", code, reason)
ws.stop()

# Assign the callbacks.
kws.on_ticks = on_ticks
kws.on_connect = on_connect
kws.on_close = on_close



# Infinite loop on the main thread. Nothing after this will run.
# You have to use the pre-defined callbacks to manage subscriptions.
kws.connect()

#####

Question :
I want to consume the websocket ticks only for the next n seconds (Eg., 20 seconds) and close the connection automatically..

How do I implement the same ?
  • Nivas
    You might find this similar discussion here helpful for understanding how to stop the WebSocket connection. You could consider tweaking it by using a sleep function to close the connection after a few seconds.
  • karthi289
    @Nivas Thanks for reply, but unfortunately, the referenced code is not working. The console keeps on printing the tick data continuously, despite meeting the condition : Current Minute >= 15.. Here is the code :
    from kiteconnect import KiteTicker
    kws = KiteTicker(api_key, access_token)
    tick_data = {}
    tick_data['trade_id'] = trade_id
    tick_data['tick_data'] = []

    tick_stock = [t['instrument_token']]
    def on_ticks(ws, ticks):
    # Callback to receive ticks.
    tk = {}
    tk['t_stamp'] = ticks[0].get("last_trade_time")
    tk['last_price'] = ticks[0].get("last_price")
    print("Ticks: ",tk['t_stamp'],tk['last_price'])

    def on_connect(ws, response):
    # Callback on successful connect.
    # Subscribe to ADANIENT in `full` mode.
    ws.subscribe(tick_stock)
    # Set ADANI to tick in `full` mode.
    ws.set_mode(ws.MODE_FULL, tick_stock)


    def on_close(ws, code, reason):
    # On connection close stop the main loop
    # Reconnection will not happen after executing `ws.stop()`
    print("Closing ws connection: ", code, reason)
    ws.stop()

    # Assign the callbacks.
    kws.on_ticks = on_ticks
    kws.on_connect = on_connect
    kws.on_close = on_close

    kws.connect()
    while True:
    if datetime.now(timezone("Asia/Kolkata")).minute <= 15:
    print("Market closed, exiting...")
    kws.close()
    break


    What am I missing here ?
  • Nivas
    You're missing threaded=True in your kws.connect() call, as mentioned in this thread. Without it, the WebSocket connection runs in the main thread and blocks the program, which can prevent it from reaching your close logic.

    This runs the WebSocket client in a background thread, allowing your main program to continue and cleanly close the socket when needed.
  • karthi289
    Nivas

    Thanks again for the reply. :)
    The threaded=True was not giving me any output at all - none of the ticks were printed. However, I found and managed to tweak my code using this thread and got what I wanted
    I was able to start the code and make it run exactly for next n seconds
    PS: threaded = True did not make any difference. I was able to get the desired output independent of threaded param in kws.connect()
  • karthi289
    Nivas,

    I am now facing with a different issue when trying to run this in AWS Lambda; My goal is to run a function every 10 minutes, and consume the tick data is the tick.seconds is between 1 and 20. Below is the code; This is running fine locally in my VS Code, but throwing an Error in Lambda :
    2025-06-26T11:49:50.477+05:30
    Exception in thread Thread-4 (run):
    2025-06-26T11:49:50.478+05:30
    Traceback (most recent call last):
    2025-06-26T11:49:50.478+05:30
    File "/var/lang/lib/python3.13/threading.py", line 1041, in _bootstrap_inner
    2025-06-26T11:49:50.478+05:30
    self.run()
    2025-06-26T11:49:50.478+05:30
    ~~~~~~~~^^
    2025-06-26T11:49:50.478+05:30
    File "/var/lang/lib/python3.13/threading.py", line 992, in run
    2025-06-26T11:49:50.478+05:30
    self._target(*self._args, **self._kwargs)
    2025-06-26T11:49:50.478+05:30
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2025-06-26T11:49:50.478+05:30
    File "/opt/python/twisted/internet/base.py", line 695, in run
    2025-06-26T11:49:50.478+05:30
    self.startRunning(installSignalHandlers=installSignalHandlers)
    2025-06-26T11:49:50.478+05:30
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2025-06-26T11:49:50.478+05:30
    File "/opt/python/twisted/internet/base.py", line 926, in startRunning
    2025-06-26T11:49:50.478+05:30
    raise error.ReactorNotRestartable()
    2025-06-26T11:49:50.478+05:30
    twisted.internet.error.ReactorNotRestartable

    Below is the code I am running to collect the tick data between 1 and 20 seconds, run for 30 seconds from start and close the code (and the connection) afterwards :
    tick_data = []
    kws.connect()

    while True:
    def on_ticks(ws, ticks):
    feed_data(ticks)

    def feed_data(ticks):
    for tick in ticks:
    # print(tick)

    tk = {}
    tk['instrument_token'] = tick['instrument_token']
    tk['t_stamp'] = tick["last_trade_time"].astimezone(timezone('Asia/Kolkata')).strftime("%Y-%m-%d %H:%M:%S")
    tk['last_price'] = tick["last_price"]
    print(json.dumps(tk, indent=1))
    if 0 < tick["last_trade_time"].second < 20:
    tick_data.append(tk)

    kws.on_ticks=on_ticks

    def update_item(l_tick) :
    print("Updated tick data to DynamoDB; ", l_tick)

    if (datetime.now(timezone("Asia/Kolkata")) -start_time).total_seconds() % 2 == 0:
    update_item(tick_data)
    ttl_seconds = 30
    if (datetime.now(timezone("Asia/Kolkata")) -start_time).total_seconds() > ttl_seconds:
    update_item(tick_data)
    print(str(ttl_seconds) + " seconds passed, closing connection...")
    kws.unsubscribe(instrument_token)
    kws.close()
    kws.stop()
    print("Tick Data: ", json.dumps(tick_data, indent=2))
    break

    Could you please help ?
  • karthi289
    @Nivas Can you help ?
Sign In or Register to comment.