Thanks for sharing your question! It looks like you shared this on StackOverflow as well, and got the following answers:
The question is what kind of user the target is. If it’s another coder, just create a requirements.txt file for your project and give them the source code (i.e. using an online repository like GitHub). Then they can recreate your environments and run the app via Streamlit locally themselves. If the target user is not a coder, you need to package everything, i.e. in a Docker container (see i.e. official documentation here docs.streamlit.io/knowledge-base/tutorials/deploy/docker)
Another option is to package your app as an executable – I recommend checking out this thread.
Desktop operating systems usually come with a preinstalled firewall, configured by default to block any incoming connections unless they come from localhost. You might have to configure the firewall to allow an application to listen to incoming requests in a certain port using a certain protocol.
In a corporate environment is common that IT people configure the operating system to comply with the organization policies before handing the computer to users, that are not granted the required permissions to change configurations.
If your operating system was configured by people in your org, those peple can answer your questions better than stranges in the Internet. If not, learn how to configure the firewall.
And no, I don’t know firewall stuff; I am not a web developer, either…that’s why I am using Streamlit …to readily and simply convert a desktop Python program into a web-based one, to explore sharing, etc.
So, I do happen to have some additional privileges in a server box; and, late last night, I found another thread with some brief instructions on how to use docker to launch a streamlit app…it worked; I can now reach my app from any computer.
Another handy way to do this is with ngrok, which allows you to expose a local port to the internet. https://ngrok.com/
# in one console window
streamlit run app.py
# In another
ngrok http 8501
Which generates a url that you can share with others to be able to access your app (as long as those commands keep running). It’s not ideal for all scenarios, but I’ve found it handy when just wanting to share something quickly without actually hosting it anywhere.
I don’t know about ngrok. I think the OP and I are looking for a self-hosting option and not expose anything outside the company four walls. A brief look at ngrok webpage and it seems like it uses some server in Europe.
In my previous post, I included a link to the repo with the instructions I followed…they are just a few lines, so, I can include them here:
Go to your working directory
Create a file named Dockerfile, with the following contents:
Copy your streamlit file over and rename it myapp.py, to match reference inside Dockerfile
Build: docker build -t myapp1:latest
Run: docker run -d -p 8501:8501 --name=testgui myapp1:latest
Go to browser and use app
Stop: docker stop testgui
Remove container: docker rm testgui
Remove image: docker rmi myapp1:latest
Oops…post-edit: You need the requirements.txt file, too.
So, like I said, the above steps kind of worked for me in that I was able to run the program in one machine and connect to it from another BUT, it only works once…for the first user to connect to it…what’s up with that?
Is this issue normal?
What else does not need to do for the app to work for multiple users?
then, when at a terminal prompt, after I type docker run ..., I do not get the prompt back
which is the same thing that happens if you type: streamlit run <myapp>.py, when working locally, anyway; so,
I was not quite surprised about that
What surprises me is that even though supposedly there is some kind of web-server running, it is not able to handle more than one user; in other words, after I launch docker run... for the first time, the program only works for the one user that connects first; if a second user wants to use the program, it does not work correctly for them.
And so, in as much as I did not like the ngrok proposal, I speculate that the solution may be along those lines, i.e., some kind of additional web-server that can launch different instances of the app got subsequent users? Here is where I don’t know what I am talking about because I am not a web-developer.
FWIW, I just did what seemed to me the simplest thing that could possibly work and it actually worked.
Launched a streamlit app in a device (endeavourOS without any special network configuration)
Sent the link to the app url (let’s say http://192.168.0.10:8501) to a couple of other devices connected to the same local network (android)
Open the link in each of the other devices.
This worked for me and I guess it should work in most domestic networks. As I said before, it may or may not work in your corporate network / with corporate devices, depending on corporate policies and how they are implemented.
Hi, Goyo…thanks for nothing Your answer is as good as “It works for me” and it does not help…would you mind showing the precise steps you followed in that “simplest thing that could possibly work”? I really doubt that it is a network issue, it seems more of a web server issue.
By the way, I was reading the Panel docs and, interestingly enough, they mention something interesting in relation to allowing different users having their own instance of the app while visiting the same web page…something about wrapping the final Python app back into a function. Panel uses the Bokeh server.
I enumerated the steps 1, 2 and 3. Let me know whatever you don’t understand. It is as simple as it looks. Launch the app in a computer (streamlit run app.py), look at the “Network URL” that appears in the terminal, go to another computer, open a browser and point it to the aforementioned “Network URL”, that’s all. I used two clients simultaneously because you said it only worked for one in your setup, so I wanted to test that.
I am not saying you are having network issues, that I don’t know. You were using docker and I barely know anything about it so I won’t even speculate about what went wrong. It was just a warning that network issues can happen.
I don’t know about your issue about not handling multiple users, but the simplest case that @Goyo is describing is: launch your app locally the same way you always do: streamlit run my_app.py. There really aren’t any special instruction here.
Observe two things when you launch your app locally.
The terminal will report two links to your running app. One via local host and one via your ip.
The window that automatically opens up is using the localhost version. The localhost url will not work on another computer. The ip version will (provided the other computer is on the same local network and any involved firewalls allow it, etc.).
My own network is pretty locked down so I hadn’t bothered to check if anything special needed to be done to offer up the app to the network. Thanks @Goyo for doing a test.
If you can open up your app on two different tab simultaneously locally, then the app is not having an issue with multiple users. Each tab is a separate session. If accessing the app from a different computer using the ip address link causes a limit on connections, I would suspect it is a network configuration issue.
A cache only caches the final output and no action within. Furthermore, it caches relative to its inputs, so you’d need to pass it the data of the file so it can cache the correct validation status for different files.
import streamlit as st
st.session_state.inpfile_checked = False
# run check on locally defined uploaded_file variable
inpfile = st.file_uploader("Input file", type='csv', key='inpfile')
st.session_state.inpfile_checked = inpfile_validate(inpfile)
st.write('Error: Unacceptable file name.')
Note, I didn’t run a test with the st.cache to see if it correctly identifies files as “the same” as you’d want. Since the file uploader returns an UploadedFile object which is a subclass of BytesIO, I am guessing it will perform as desired. Just a caveat that I didn’t validate that point with testing.
“This happens because the Streamlit cache is global to all users. So everyone contributes to everyone else’s performance.”
Between the above statement and what you and the docs mention regarding caching of inputs and outputs, one also needs to make sure that the function does not have any side effects. In my case, the side effect was changing the value of a global variable without it being an input nor an output…this side effect does not happen after the function has been cached.