Streamlit with paho.mqtt - IS NOT POSSIBLE

My conclusion/experience after a week of trying to use paho.mqtt with streamlit is that it is not possible.

Some points that I could understand this week, client.loop_forever() runs in the same context as streamlit, as it has a while

The second point that I believe is the “problem” of it not working is because of on_message, since we need to add add_script_run_ctx to the parent thread, something that is not “possible”, not being possible, it gives a signal to streamlit to rerun.

Another point is that using paho as the main thread and running streamlit in its thread will “work”, but instead of updating a stack of widgets will be created.

Anyway, I’ll leave the code I made, but just so someone can come and do the opposite.

from threading import Thread
import streamlit as st
from streamlit.runtime.scriptrunner import add_script_run_ctx, get_script_run_ctx
from streamlit.runtime.scriptrunner.script_run_context import SCRIPT_RUN_CONTEXT_ATTR_NAME
import paho.mqtt.client as mqtt
import os
from dotenv import load_dotenv

class MyClient(mqtt.Client):

  def __init__(self) -> None:
    super().__init__("", None, None, 4, "tcp", True)
    self._init()

  def _init(self):
    load_dotenv()

    server = os.getenv("SERVER")
    port = os.getenv("PORT")

    self.on_message = self.my_on_message
    self.on_connect = self.my_on_connect
    self.username_pw_set(username=os.getenv("USER_MQTT"), password=os.getenv("PASSWORD"))
    self.subscribe(os.getenv("TOPIC"))

    self.connect(server, int(port))

  def my_on_message(self, client, userdata, msg):
    message = str(msg.payload)
    st.write(message)
      

  def my_on_connect(self, client, userdata, flags, rc):
      self.subscribe(os.getenv("TOPIC"))
  

if __name__ == "__main__":
  
  client = MyClient()
  client.loop_forever()
  """
  if 'status' not in st.session_state:
    print("CREATE CLIENT MQTT")
    
    client = MyClient()

    thread = Thread(target=client.loop_forever)
    add_script_run_ctx(thread=thread, ctx= get_script_run_ctx())
    thread.start()

    st.session_state['status'] = 'created'
  """