Is there a way to create a streamlit app thats the same for everyone? More in description

Summary

I’m trying to create a streamlit app that is the same for every user. What do I mean by this? This wont be interactive and shown data shouldnt change depending on the user. As shown in the code snippet, I open a WebSocket Client to receive data from another script I have, this data will be plotted using different streamlit functions so that the user can visualize.
The problem starts when you open the site twice, this is a problem because streamlit tries to open another websocket with the same port. For what is worth, I’m trying to create a streamlit app that updates every time it received more data in the websocket.

Steps to reproduce

Code snippet:

socket_ran = False

# Setup the WebSocket
async def websocket_client(websocket, path):
    async for message in websocket:
        on_message(message)

async def server_handler():
    async with websockets.serve(websocket_client, "0.0.0.0", 5255) as server:
        await asyncio.Future()
        
def run_server():
    if not socket_ran:
        asyncio.run(server_handler())
    else:
        print("Called Again")

ws_thread = threading.Thread(target = run_server)     
ws_thread.start()   

def _setup(name, ticker, date, status, variables):
    
    # Strategy Name
    st.session_state.name
    
    # Ticker
    st.session_state.ticker.name = ticker["name"]
    st.session_state.ticker.timeframe = ticker["timeframe"]
    st.session_state.ticker.exchange = ticker["exchange"]

    # Strategy Date
    st.session_state.date.start = date["from"]
    st.session_state.date.end = date["to"]
    
    # Process Status
    st.session_state.status = status
    
    # Variables List
    st.session_state.variables = variables
    #? Example : Type : Setup
    {
        "type":"setup",
        "name":"Luda Kelt",
        "ticker":{
            "name":"BTCUSD.P",
            "timeframe": "30m",
            "exchange": "ByBit"
        },
        "date":{
            "from":"",
            "to":""
        },
        "status":"pending",
        
        "variables": [
            {
                "name":"",
                "from":"",
                "to":"",
                "step":""
            },
            {
                "name":"",
                "from":"",
                "to":"",
                "step":""
            }
        ]
    }

def _info(progress, status, eta, data):
    
    # Progress %
    st.session_state.progress = progrss
    
    # Status
    st.session_state.status = status
    
    # Estimated Time
    st.session_state.eta = eta
    
    # Combination Data
    st.session_state.data = data
    
    #? Example : Type : Data
    {
        "type":"data",
        "progress":"34",
        "status":"Initializing",
        "eta":"3 hours 22 minutes",
        
        "data": {
            "screenshot":"",
            
            "overview":{},
            "performance_summary":""
        }
    }

def on_message(message):
    if message["type"] == "setup":
        _setup(
            name = message["name"], 
            ticker = message["ticker"],
            date = message["date"],
            status = message["status"],
            variables = message["variables"]
        )
    
    elif message["type"] == "data":
        _info(
            progress = message["progress"],  
            status = message["status"],
            eta = message["eta"],
            data = message["data"]
        )

def page_setup():
    # Page config
    st.set_page_config(
        page_title = "Testing", 
        layout = "wide", 
        initial_sidebar_state = "expanded"
    )
    
    
page_setup()

Expected behavior:
Only one WebSocket should open, and every time new data is received in the websocket, those st.session_state attributes update, so that in future code, new data is shown to the user every time the websocket receives new data (hope this makes sense)

Actual behavior:
Two WebSocket Clients are being opened, and since you cant open a single port more than once, this raises an error.

Debug info

  • Streamlit version: 1.2
  • Python version: 3.10
  • OS version: Windows 10
  • Browser version: Chrome

Requirements file

threading
websockets
asyncio

Additional information

Please feel free to ask for more information, I’ll kindly provide it. Thanks in advance for your help.

what can I do for someone to help >7

I am not sure what you expect, you said.

Of course you have to take care of that. You need to figure out a way to tell whether you need to open the socket or it is already open and you can reuse it. cache_resource can help with that and you can also maintain app-global state in a module that your main script imports (modules are imported only once).

Your code is too async and websocky for my skillset so I cannot be more specific.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.