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.