Correct html content-type for Streamlit?

Hey guys,

First of all, sorry if this isn’t the appropriate place, but after browsing other forums for a couple of hours, I’m yet to find a solution.

Basically, I have an Apache Server set up in a CentOS machine, where I’m trying to host a streamlit app. For testing purposes, lets assume this is the script:

#!/usr/bin/python3
print("Content-Type: text/plain;charset=utf-8 \n\n")

import streamlit as st

def main():
	print("Hello World")
 
	a = 2
	print("\nthe value of a is ", a)
 
 	st.write('streamlit dummy message')
 
 	if st.button('First Button'):
 		print('1 - button pressed')
 	
 	b = a + 2
 	print("\n the value of b is ", b)
 
 if __name__ == '__main__':
 	main()

But when accessing the respective page, all i see is:

return

Basically, anything non-streamlit renders normally, while streamlit related commands like button or write provide no output whatsoever.

I tried changing the content-type in the html parameters to application or so, but nothing worked so far.
Also, i must admit I’m quite a beginner in terms of web-hosting so that might be the cause of the problem (and again, sorry for asking this in the wrong place).

Also related, my httpd.confi file for this particular script:

image

If there’s any help you can give I’d be forever in your doubt.
And if there’s more info you need, please don’t hesitate.

Hi @marciorpcoelho,

Thanks for your question! You’re on the right track, it’s just that Streamlit’s execution model won’t really play nice with ExecCGI.

You should run your streamlit app on an unprivileged port (8501 is fine, say), and then use a “reverse proxy” to forward all requests from port 80 (the usual HTTP port) to your streamlit app.

Here’s an example config you can edit for your purposes (and let us know how it goes):

<VirtualHost _default_:80>
DocumentRoot /home/user/website_folder
RewriteEngine On
# Redirect all requests to the local Apache server to port 8080
RewriteRule ^.*$ http://%{HTTP_HOST}:8501%{REQUEST_URI}
</VirtualHost>

ps. we have the beginnings of a FAQ containing such information here. Obviously we have some work to do to improve it! Thanks for bearing with us.

I’ve been playing with your config but I still get ERR_CONNECTION_REFUSED when I try to access it.
Is there any additional config I should be doing?

@marciorpcoelho Did you try disabling CORS from your .streamlit/config.toml file ?

[server]
enableCORS = false
1 Like

Thank you for your input.
I just tried it, by way of a flag in the command line and I got time out errors across all links :weary:

Hi @marciorpcoelho,
another “blind” suggestion may be to check that your Apache configuration supports Websockets. Here is some context: https://www.serverlab.ca/tutorials/linux/web-servers-linux/how-to-reverse-proxy-websockets-with-apache-2-4/

Matteo

@monchier thanks for your help, but alas, all the modules were already installed and configured.

There has been an update, though:
Using the following configuration, I think we’ve made some progress as I am no longer getting any error. The bad news is that all i get now is a blank page.

The config I’m currently using is:

<Virtualhost *:80>

    ServerName streamlit.group.pt
    ServerAlias srcapp.sc.pt

	documentroot /var/www/example.com/html

	RewriteEngine On

	RewriteCond %{HTTP:Upgrade} =websocket
   	RewriteRule /test1 ws://localhost:8501 [P]

   	RewriteCond %{HTTP:Upgrade} !=websocket
   	RewriteRule /test1 http://localhost:8501 [P]

   	ProxyPassReverse /test1 http://localhost:8501

</VirtualHost>

But when i try to open http://streamlit.group.pt/test1 all i get is a blank page.
Opening http://streamlit.group.pt/ returns the default html file though, located at /var/www/example.com/html.
The example .py file I’m currently running from streamlit is also located at /var/www/example.com/html.

I’m going to try and modify the above config and see if can progress further, but any help is more than welcome.

Edit:
Forgot to add something:
If I try to open http://streamlit.group.pt:8501 I can see the streamlit report without any issues. It’s only when I try to use http://streamlit.group.pt/test1 that I have this problem. And yes, I have to use the /test1 alias or some sort of alias when providing streamlit services to my clients :weary:

I am wondering you are hitting an issue we found out recently. We recently found a bug in the way the path to the static resources is calculated. Can you try to use a slash at the end of your target path?

Something like:

<Virtualhost *:80>

    ServerName streamlit.group.pt
    ServerAlias srcapp.sc.pt

	documentroot /var/www/example.com/html

	RewriteEngine On

	RewriteCond %{HTTP:Upgrade} =websocket
   	RewriteRule /test1/ ws://localhost:8501 [P]

   	RewriteCond %{HTTP:Upgrade} !=websocket
   	RewriteRule /test1/ http://localhost:8501 [P]

   	ProxyPassReverse /test1/ http://localhost:8501

</VirtualHost>

The you would have to access any app with a trailing slash: http://streamlit.group.pt/test1/

Let me know if this work. Will gave you a link to this bug as soon as I file it.

Also, can you send me a snapshot of your networking tab on Chrome?

Thanks,
Matteo

Bug that may be relevant to this: https://github.com/streamlit/streamlit/issues/1139

Thanks for your help @monchier, but unfortunately, adding the trailing slash didn’t work. The result was the same, blank page.

Hey @marciorpcoelho - this seems like an Apache configuration error, and I’m not sure any of us here have enough direct Apache experience to be very useful for debugging it further :frowning: , apologies.

Have you tried asking the Apache experts at StackOverflow?

Streamlit’s web server is not terribly exotic (it serves both HTTP and Websocket traffic over :8501, by default), so I would assume someone more well-versed in Apache than we are would be able to offer more assistance!

Thanks, I’ll try StackOverflow then!

hi @marciorpcoelho
I am facing the same or a similar problem trying to setup Virtual Host on Apache. Did you progress with this issue on StackOverflow?

Nothing so far on StackOverflow.

However, I got it to work using the following configuration:

<Virtualhost *:80>

    ServerName streamlit.group.pt
    ServerAlias server.pt

    documentroot /var/www/example.com/html/streamlit_reports/

    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket
    RewriteRule /streamlit_report_name ws://streamlit.group.pt:8502 [R]

    RewriteCond %{HTTP:Upgrade} !=websocket
    RewriteRule /streamlit_report_name http://streamlit.group.pt:8502 [R]

    ProxyPassReverse /placeholder http://localhost:8502

The only problem so far, is that when opening the link streamlit.group.pt/streamlit_report_name the link automatically changes to streamlit.group.pt:8502, as I still haven’t managed to find a correct configuraton for this.

Hope it helps.

Thanks so much, @marciorpcoelho, this worked like a charm. The only problem remaining is the one you mention. From our organization, addresses with port numbers are blocked, I reckon many others do the same. I will continue searching for a solution for this and I am most interested in case you find a solution on your end. However, this first part was really important for me so thanks again.

1 Like

No problem, glad it worked for you :slight_smile:

Hi @marciorpcoelho, thanks a lot for your answer, it helped me a lot. I am just wondering if you have fingered out how to solve the issue wih changing to streemlit.group.pt:8502. Thanks again.

Glad it helped, but so far I haven’t managed to solve that small problem. Admittedly I didn’t try much more as it currently serves its purpose and the port displaying isn’t an issue in our company.

1 Like

@marciorpcoelho Question…where in the config are you referring to your streamlit app (i.e .py file)…
I see it was mentioned in initial question but is not present in this solution?

Hello @Gaura
You don’t need to refer to the .py file as they are not related. The config file just sets rules of where the traffic from port 8502 should point to.

You then just need to run your streamlit app (.py file) in the configured port ( in my case, it was 8502) and that’s it. If tomorrow you’d like to change the app, just terminate and run the new app in the same port.

Hope it helped.