Hi,
I am trying to make the samples more production ready by handling error conditions. Testing an incorrect password, I am receiving the following text:
ERROR:root:LOGIN STATUS: {
  "Domain":"Login",
  "ID":1,
  "Key":{
    "Name":"rateserverss"
  },
  "State":{
    "Code":"UserUnknownToPermSys",
    "Data":"Suspect",
    "Stream":"Closed",
    "Text":"rateserverss, unknown to system."
  },
  "Type":"Status"
}
I am detecting this, however how do I terminate the loop in the main program? 
logger.error("LOGIN STATUS: %s", json.dumps(message_json, sort_keys=True, indent=2, separators=(',', ':')))
if message_json['State']['Stream'] != "Open" or message_json['State']['Data'] != "Ok":
    logger.error("Login Request rejected / failed:"+message_json['State']['Text'])
    shutdown_app = True
    exit(5000)The routine exits, however the main code is never executed and the program just hangs, processing additional callbacks. 
Note I am using threading and the run_forever version of the web socket app:
ws_address = "ws://{}:{}/WebSocket".format(host, port)
print("Connecting to WebSocket " + ws_address + " ...")
logger.info("Connecting to WebSocket " + ws_address + " ...")
web_socket_app = websocket.WebSocketApp(ws_address, header=['User-Agent: Python'],
                                        on_message=on_message,
                                        on_error=on_error,
                                        on_close=on_close,
                                        subprotocols=['tr_json2'])
web_socket_app.on_open = on_open
# Event loop
wst = threading.Thread(target=web_socket_app.run_forever)