streamlit_ttyd icon indicating copy to clipboard operation
streamlit_ttyd copied to clipboard

Localhost refused to connect

Open joshjetson opened this issue 2 years ago • 8 comments

After setting the port to a specific integer and making sure the port was open on my router the would be terminal window shows a broken page icon that says Localhost refused to connect.

joshjetson avatar Jun 01 '23 06:06 joshjetson

I'm having the same issue. Are you using it within a docker container?

caviri avatar Jul 17 '23 12:07 caviri

You can modify the source code simply running ttyd server. it will work or you dont need use this library if you're running ttyd server as a process on linux server you can directly render the iframe on the streamlit.

directly render without this module:- (you must run ttyd server)

ttyd_url = "http://localhost:7681" # Replace with the actual URL of your TTYD page

iframe_html = f''

st.write(iframe_html, unsafe_allow_html=True)

another method to call the ttyd iframe without this module:- (you must run ttyd server) import streamlit as st iframe_url = "http://localhost:7681" st.components.v1.iframe(iframe_url, width=800, height=400)

Using this library update the source code in actual python site-packages where your source code is installed.

ttydproc = subprocess.Popen( # f"ttyd {flags} {cmd}", f"ttyd bash", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, )

natarajan0007 avatar Sep 26 '23 06:09 natarajan0007

This project doesn't properly bundle the ttyd executable it depends on, so the calls to ttyd don't work. It only works if you git clone this project as if you were the developer and execute from that exact folder.

Also, it's really bad form to distribute executables without clear provenance in Python package. The proper way to set this up would have to have GitHub Actions script that compiles https://github.com/tsl0922/ttyd from source and injects into the generated Python wheel on a per platform basis.

jbarlow83 avatar Jan 01 '25 23:01 jbarlow83

Happy new year and thanks @jbarlow83 for the feedback.

Although at this point I am not integrating ttyd building from source but I have added a way to provide your own ttyd binary path to the terminal function.

Also the package is now relatively better designed for distribution using flit

Thanks again.

NeveIsa avatar Jan 02 '25 09:01 NeveIsa

Thanks for the quick feedback.

Regarding the use of Docker, typically Docker containers acquire a private IP address that is distinct from the host computer (unless port mapping is setup). Also, the iframe asks the user's browser to open an additional port, so to direct the browser to the correct location, it needs to do something like this:


def get_host_url_with_port(port: int) -> str:
    """Get the host URL."""
    host_url = st.context.headers["host"]
    try:
        host, _streamlit_port = host_url.split(":", maxsplit=1)
    except ValueError:
        host = host_url
    return f"//{host}:{port}"  # Use the same protocol

That checks the browser's headers to see what

Then when it's time to show the iframe, use:

iframe(src=get_host_url_with_port(port))

There might be cases where st.context.headers["host"] isn't accurate enough but this should be a good start.

jbarlow83 avatar Jan 04 '25 20:01 jbarlow83

I think it is simpler to let users explicitly set the parameters when there is non-transparency in network between host and container. How about modifying port parameter to ttyd_port and adding an iframe_port argument which will equal ttyd_port if iframe_port not explicitly provided?

This will be a breaking change but should be ok.

NeveIsa avatar Jan 05 '25 16:01 NeveIsa

The issue isn't the port, it's the server. Setting Docker aside for the moment, if you run streamlit anywhere other than localhost, streamlit-ttyd won't work, because it always tries to use an iframe on localhost.

jbarlow83 avatar Jan 05 '25 17:01 jbarlow83

I have added your fix but not tested. Could you please help test the code on your end?

NeveIsa avatar Jan 09 '25 09:01 NeveIsa