Set_page_config layout after authentification

Hello everybody,

I am close to launch my first app using streamlit but I am facing an issue.

I have a 2 part in my app. One landin/welcome page and the app itself with multiples pages.
The welcome page need to be in wide layout and the other in centered.
To put it simple, if the user is login, it’s contered, if not it’s wide.

Before I was using google authentification without cookies, for dev. And it was working ok because the user need to reload the page to login. So I can check if the user is auth, then I apply the page_config. But now I added extra_streamlit_components CookieManager. And because it need to run before I can use set_page_config, I get an error.

streamlit.errors.StreamlitAPIException: set_page_config() can only be called once per app page, and must be called as the first Streamlit command in your script.

Just using:

@st.cache_resource(experimental_allow_widgets=True)
def get_manager():
    return stx.CookieManager()

cookie_manager = get_manager()
st.set_page_config(
    layout="centered")

I looked and couldn’t found a solution online. Look like nothing is possible. I could in theory use the multipages features of streamlit and add a set_page_config for each but then the user can access any page at any time, not what I want, and the layout is ugly and I can’t add stuff on top. (I know their is a hacky solution to that too but meh). Maybe it is possible to make a multipages but hide the pages? So I can manage in python the swap between pages.

Anybody have a solution ? It is a bit annoying as it is the only thing that I couln’t figure it out by searching or with hacky solution.

Thanks in advance and for this great tool

1 Like

Why would extra_streamlit_components CookieManager has to be run before set_page_config? The set_page_config has to be the boss.

1 Like

Because I check if the user has already login with this device by using cookies to do auto-authentification.

1 Like

So the cookie manager cannot determine if user has login or not if you call set_page_config first. Why?

1 Like

No it can, but I want to set the layout of the page depending of if the user is longin or not.

1 Like

You can try to use the column. centered is around 730px wide.

1 Like

I tired already but the layout endup weird because it’s a bit complex

1 Like

What other things you have tried so far?

1 Like

By the way what is the point of all that?

1 Like

I will release the app soon, you will be able to see. But basically I have a chatbot that I want centered and dashboard that I want wide. Rn it is wide as default, so once login, you need to go to the option and manually change it. Not good enough as a user experience.

The issue with multiple column is that the chat_input appear on the top.
Also weird thing happed when resizing the app. And the app is build to be use on the side of another window, in a phone format.

So for I didn’t try anything else. As I said, without cookie everything worked fine but I need to use them.
I am not an expert in web dev as I’m more a data engineer/scientist. So I can’t implement cookies from nothing.

I asked here in last resort but I doubt there is any solution. I feel like I touch the limite of what streamlit is capable. I am missing a part in my tech sandwich to orchestrate all of that, like fastapi, django or flask. I will take a look as I will soon need to do a website in any case. So I can use the website as hub with authentification and payment to redirect to the app.

Because implementing google authentification was a nightmare, stripe too as they are suppose to be use with more conventional frameworks. And I can’t find a way to add more authentification API, which is a huge deal breaker on my side.

1 Like

You can try to change the layout via css. Be careful doing this as the targeted selector (.block-container) might change in future streamlit releases.

import streamlit as st
import random


init_layout = 'wide'
st.set_page_config(layout=init_layout)


css_layout_centered = """
    <style>
        .block-container {
            max-width: 46rem;
            padding-left: 1rem;
            padding-right: 1rem;
            padding-top: 5rem;
        }
    </style>
"""

logged_in = random.choice([True, False])

if logged_in:
    st.markdown(css_layout_centered, unsafe_allow_html=True)

    st.title('layout: centered')
    st.write('aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbb ccccccccccccccc ddddddddddddd eeeeeeeeeeeeee fffffffffffff ggggggg hhhhhhh')
else:
    st.title(f'init layout: {init_layout}')
    st.write('aaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbb ccccccccccccccc ddddddddddddd eeeeeeeeeeeeee fffffffffffff ggggggg hhhhhhh')

streamlit-extras has a stylable container, you might want to try this as well.

The streamlit roadmap is very promising.

You may go to the streamlit github, and raise an issue there for your particular case.

2 Likes

Thanks, I will take a look. Look promising

At this point I will also check the function itself in streamlit if I can create a small function like st.set_layout(“wide”). Derived from the set_page_config javascript function.
I know nothing is JS tho, so it’s gonna be fun.

1 Like

You idea worked for my case, thanks a lot.

Now my app is wide. But for the chatbot, the input is wide, which is nice because it is easier and the textbox are smaller and easier to read. Perfect.

Thanks again.

Have you checked
1.streamlit_extras.switch_page_button import switch_page
2.st_pages these libraries . hope you find any insight out of this .
st.switch_page - Streamlit Docs .