A library to create multi-page Streamlit applications with ease.

Overview

Hydralit hydra

The Hydralit package is a wrapping and template project to combine multiple independant (or somewhat dependant) Streamlit applications into a multi-page application.

Currently the project implements a host application HydraApp and each child application simply needs to be a class deriving from the HydraHeadApp class and implement a single, simple method, run().

When converting existing applications, you can effectively put all the existing code inside the run() method and create a wrapper class deriving from HydraHeadApp. Then you create the parent app as an instance of HydraApp, add your child apps to it (see examples app.py and secure_app.py) and with only a few lines of code everything will magically come together.

Hydralit >=1.0.3 now requires a minimum version of Streamlit >=0.86.x to fully support the recently migrated beta containers, if using Streamlit <=0.85.x please continue to use Hydralit <=1.0.2


Installing Hydralit

Hydralit can be installed from PyPI:

pip install -U hydralit

NOTE

Due to the Streamlit execution model, the ability to use internal nav links from a child app is one-shot when using the navbar. This means that the internal link will redirect to the child, however if a script rerun request is made within the child app (changing the value of a widget for example), the nav will bounce back to the calling app. You can disable the navbar and the Streamlit core components nav menu will appear and the internal links will work as expected.

Latest features

  • Can set auto login with guest account when using a secure app
  • Support for a non-secure app in a secure app (like a signup app)
  • Full integration with the Hydralit Navbar that now supports complex nav!
  • some bug fixes where app to app redirect was inconsistant
  • Banners
  • Compression behind download button
  • Hydralit Navbar
  • Can turn off the navbar animation now! (must be using Hydralit_components >=1.0.4)

Complex and sticky nav with no Streamlit markers is as easy as a couple of parameters in the Hydralit constructor.

app = HydraApp(title='Secure Hydralit Data Explorer',favicon="πŸ™",hide_streamlit_markers=True,use_navbar=True, navbar_sticky=True)

Now powered by Hydralit Components.

Currently the complex collapsable menu format is not supported by Hydralit Navbar, however if you can live without it for now, you will be rewarded with an animated and responsive navbar.

Quick Example

Examples

You can try it out by running the two sample applications with their children that are located in the hydralit-example repository.

hydralit_example> pip install -r requirements.txt

hydralit_example> streamlit run secure.app

You can see this example running here

example

Converting existing applications

This code sample comes directly from the Streamlit example data explorer

import streamlit as st
import pandas as pd
import numpy as np

st.title('Uber pickups in NYC')

DATE_COLUMN = 'date/time'
DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
            'streamlit-demo-data/uber-raw-data-sep14.csv.gz')

@st.cache
def load_data(nrows):
    data = pd.read_csv(DATA_URL, nrows=nrows)
    lowercase = lambda x: str(x).lower()
    data.rename(lowercase, axis='columns', inplace=True)
    data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
    return data

data_load_state = st.text('Loading data...')
data = load_data(10000)
data_load_state.text("Done! (using st.cache)")

if st.checkbox('Show raw data'):
    st.subheader('Raw data')
    st.write(data)

st.subheader('Number of pickups by hour')
hist_values = np.histogram(data[DATE_COLUMN].dt.hour, bins=24, range=(0,24))[0]
st.bar_chart(hist_values)

# Some number in the range 0-23
hour_to_filter = st.slider('hour', 0, 23, 17)
filtered_data = data[data[DATE_COLUMN].dt.hour == hour_to_filter]

st.subheader('Map of all pickups at %s:00' % hour_to_filter)
st.map(filtered_data)

Let's also use a simple application to combine with the demo above.

import streamlit as st
import numpy as np
import pandas as pd
from data.create_data import create_table

def app():
    st.title('Small Application with a table and chart.')

    st.write("See `apps/simple.py` to know how to use it.")

    st.markdown("### Plot")
    df = create_table()

    st.line_chart(df)

You can easily convert these apps to be used within Hydralit by simply wrapping each in a class derived from HydraHeadApp within Hydralit and putting all the code in the run() method.

For the above Streamlit demo application, this means all that is needed is a slight modification, we create a file sample_app.py and add;

import streamlit as st
import pandas as pd
import numpy as np

#add an import to Hydralit
from hydralit import HydraHeadApp

#create a wrapper class
class MySampleApp(HydraHeadApp):

#wrap all your code in this method and you should be done
    def run(self):
        #-------------------existing untouched code------------------------------------------
        st.title('Uber pickups in NYC')

        DATE_COLUMN = 'date/time'
        DATA_URL = ('https://s3-us-west-2.amazonaws.com/'
                    'streamlit-demo-data/uber-raw-data-sep14.csv.gz')

        @st.cache
        def load_data(nrows):
            data = pd.read_csv(DATA_URL, nrows=nrows)
            lowercase = lambda x: str(x).lower()
            data.rename(lowercase, axis='columns', inplace=True)
            data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
            return data

        data_load_state = st.text('Loading data...')
        data = load_data(10000)
        data_load_state.text("Done! (using st.cache)")

        if st.checkbox('Show raw data'):
            st.subheader('Raw data')
            st.write(data)

        st.subheader('Number of pickups by hour')
        hist_values = np.histogram(data[DATE_COLUMN].dt.hour, bins=24, range=(0,24))[0]
        st.bar_chart(hist_values)

        # Some number in the range 0-23
        hour_to_filter = st.slider('hour', 0, 23, 17)
        filtered_data = data[data[DATE_COLUMN].dt.hour == hour_to_filter]

        st.subheader('Map of all pickups at %s:00' % hour_to_filter)
        st.map(filtered_data)
        #-------------------existing untouched code------------------------------------------

For the other small application, again we can convert this very easily by wrapping in a class derived from HydraHeadApp from Hydralit and putting all the code in the run() method, we create a file small_app.py and add;

import streamlit as st
import numpy as np
import pandas as pd
from data.create_data import create_table

#add an import to Hydralit
from hydralit import HydraHeadApp

#create a wrapper class
class MySmallApp(HydraHeadApp):

#wrap all your code in this method and you should be done
    def run(self):
        #-------------------existing untouched code------------------------------------------
        st.title('Small Application with a table and chart.')

        st.markdown("### Plot")
        df = create_table()

        st.line_chart(df)

These are is now ready to be used within a Hydralit application. We just need to create a simple host application that derives from the HydraApp class in Hydralit, add the children and we are done! we create a file host_app.py and add;

from hydralit import HydraApp
import streamlit as st
from sample_app import MySampleApp
from small_app import MySmallApp


if __name__ == '__main__':

    #this is the host application, we add children to it and that's it!
    app = HydraApp(title='Sample Hydralit App',favicon="πŸ™")
  
    #add all your application classes here
    app.add_app("Small App", icon="🏠", app=MySmallApp())
    app.add_app("Sample App",icon="πŸ”Š", app=MySampleApp())

    #run the whole lot
    app.run()

That's it!

This super simple example is made of 3 files.

hydralit sample project
β”‚   host_app.py
β”‚   small_app.py
β”‚   sample_app.py

Run this sample

hydralit sample project> pip install hydralit

hydralit sample project> streamlit run host.app

Examples

The code for a host application that is secured with a login app is shown below, the entire example is located in the hydralit-example repository.

Secure Hydralit Explorer
"},None,"./resources/lock.png"], banner_spacing=[5,30,60,30,5], use_navbar=True, navbar_sticky=False, navbar_theme=over_theme ) #Home button will be in the middle of the nav list now app.add_app("Home", icon="🏠", app=apps.HomeApp(title='Home'),is_home=True) #add all your application classes here app.add_app("Cheat Sheet", icon="πŸ“š", app=apps.CheatApp(title="Cheat Sheet")) app.add_app("Sequency Denoising",icon="πŸ”Š", app=apps.WalshApp(title="Sequency Denoising")) app.add_app("Sequency (Secure)",icon="πŸ”ŠπŸ”’", app=apps.WalshAppSecure(title="Sequency (Secure)")) app.add_app("Solar Mach", icon="πŸ›°οΈ", app=apps.SolarMach(title="Solar Mach")) app.add_app("Spacy NLP", icon="⌨️", app=apps.SpacyNLP(title="Spacy NLP")) app.add_app("Uber Pickups", icon="πŸš–", app=apps.UberNYC(title="Uber Pickups")) app.add_app("Solar Mach", icon="πŸ›°οΈ", app=apps.SolarMach(title="Solar Mach")) #we have added a sign-up app to demonstrate the ability to run an unsecure app #only 1 unsecure app is allowed app.add_app("Signup", icon="πŸ›°οΈ", app=apps.SignUpApp(title='Signup'), is_unsecure=True) #we want to have secure access for this HydraApp, so we provide a login application #optional logout label, can be blank for something nicer! app.add_app("Login", apps.LoginApp(title='Login'),is_login=True) #specify a custom loading app for a custom transition between apps, this includes a nice custom spinner app.add_loader_app(apps.MyLoadingApp(delay=5)) #app.add_loader_app(apps.QuickLoaderApp()) #we can inject a method to be called everytime a user logs out @app.logout_callback def mylogout_cb(): print('I was called from Hydralit at logout!') #we can inject a method to be called everytime a user logs in @app.login_callback def mylogin_cb(): print('I was called from Hydralit at login!') #-----if we want to auto login a guest but still have a secure app, we can assign a guest account and go straight in #check if this is first open user_access_level, username = app.check_access() if user_access_level == 0 and username is None: app.set_access(1, 'guest') #-------------------------------------------------------------------------------------------------------------------- #if the menu is looking shit, use some sections #check user access level to determine what should be shown on the menu user_access_level, username = app.check_access() # If the menu is cluttered, just rearrange it into sections! # completely optional, but if you have too many entries, you can make it nicer by using accordian menus if user_access_level > 1: complex_nav = { 'Home': ['Home'], 'Intro πŸ†': ['Cheat Sheet',"Solar Mach"], 'Hotstepper πŸ”₯': ["Sequency Denoising","Sequency (Secure)"], 'Clustering': ["Uber Pickups"], 'NLP': ["Spacy NLP"], } elif user_access_level == 1: complex_nav = { 'Home': ['Home'], 'Intro πŸ†': ['Cheat Sheet',"Solar Mach"], 'Hotstepper πŸ”₯': ["Sequency Denoising"], 'Clustering': ["Uber Pickups"], 'NLP': ["Spacy NLP"], } else: complex_nav = { 'Home': ['Home'], } #and finally just the entire app and all the children. app.run(complex_nav) #print user movements and current login details used by Hydralit user_access_level, username = app.check_access() prev_app, curr_app = app.get_nav_transition() print(prev_app,'- >', curr_app) print(int(user_access_level),'- >', username) ">
from hydralit import HydraApp
import streamlit as st
import apps


if __name__ == '__main__':
    over_theme = {'txc_inactive': '#FFFFFF'}
    #this is the host application, we add children to it and that's it!
    app = HydraApp(
        title='Secure Hydralit Data Explorer',
        favicon="πŸ™",
        hide_streamlit_markers=False,
        #add a nice banner, this banner has been defined as 5 sections with spacing defined by the banner_spacing array below.
        use_banner_images=["./resources/hydra.png",None,{'header':"

Secure Hydralit Explorer


"
},None,"./resources/lock.png"], banner_spacing=[5,30,60,30,5], use_navbar=True, navbar_sticky=False, navbar_theme=over_theme ) #Home button will be in the middle of the nav list now app.add_app("Home", icon="🏠", app=apps.HomeApp(title='Home'),is_home=True) #add all your application classes here app.add_app("Cheat Sheet", icon="πŸ“š", app=apps.CheatApp(title="Cheat Sheet")) app.add_app("Sequency Denoising",icon="πŸ”Š", app=apps.WalshApp(title="Sequency Denoising")) app.add_app("Sequency (Secure)",icon="πŸ”ŠπŸ”’", app=apps.WalshAppSecure(title="Sequency (Secure)")) app.add_app("Solar Mach", icon="πŸ›°οΈ", app=apps.SolarMach(title="Solar Mach")) app.add_app("Spacy NLP", icon="⌨️", app=apps.SpacyNLP(title="Spacy NLP")) app.add_app("Uber Pickups", icon="πŸš–", app=apps.UberNYC(title="Uber Pickups")) app.add_app("Solar Mach", icon="πŸ›°οΈ", app=apps.SolarMach(title="Solar Mach")) #we have added a sign-up app to demonstrate the ability to run an unsecure app #only 1 unsecure app is allowed app.add_app("Signup", icon="πŸ›°οΈ", app=apps.SignUpApp(title='Signup'), is_unsecure=True) #we want to have secure access for this HydraApp, so we provide a login application #optional logout label, can be blank for something nicer! app.add_app("Login", apps.LoginApp(title='Login'),is_login=True) #specify a custom loading app for a custom transition between apps, this includes a nice custom spinner app.add_loader_app(apps.MyLoadingApp(delay=5)) #app.add_loader_app(apps.QuickLoaderApp()) #we can inject a method to be called everytime a user logs out @app.logout_callback def mylogout_cb(): print('I was called from Hydralit at logout!') #we can inject a method to be called everytime a user logs in @app.login_callback def mylogin_cb(): print('I was called from Hydralit at login!') #-----if we want to auto login a guest but still have a secure app, we can assign a guest account and go straight in #check if this is first open user_access_level, username = app.check_access() if user_access_level == 0 and username is None: app.set_access(1, 'guest') #-------------------------------------------------------------------------------------------------------------------- #if the menu is looking shit, use some sections #check user access level to determine what should be shown on the menu user_access_level, username = app.check_access() # If the menu is cluttered, just rearrange it into sections! # completely optional, but if you have too many entries, you can make it nicer by using accordian menus if user_access_level > 1: complex_nav = { 'Home': ['Home'], 'Intro πŸ†': ['Cheat Sheet',"Solar Mach"], 'Hotstepper πŸ”₯': ["Sequency Denoising","Sequency (Secure)"], 'Clustering': ["Uber Pickups"], 'NLP': ["Spacy NLP"], } elif user_access_level == 1: complex_nav = { 'Home': ['Home'], 'Intro πŸ†': ['Cheat Sheet',"Solar Mach"], 'Hotstepper πŸ”₯': ["Sequency Denoising"], 'Clustering': ["Uber Pickups"], 'NLP': ["Spacy NLP"], } else: complex_nav = { 'Home': ['Home'], } #and finally just the entire app and all the children. app.run(complex_nav) #print user movements and current login details used by Hydralit user_access_level, username = app.check_access() prev_app, curr_app = app.get_nav_transition() print(prev_app,'- >', curr_app) print(int(user_access_level),'- >', username)

You can try it out by running the two sample applications with their children that are located in the hydralit-example repository.

hydralit_example> pip install -r requirements.txt

hydralit_example> streamlit run secure.app
Comments
  • No module 'streamlit.script_run_context'

    No module 'streamlit.script_run_context'

    Hi there. I am running Streamlit 1.8.1 (the latest, I think). When I try and run my Hydralit app, I get the following:

    ModuleNotFoundError: No module named 'streamlit.script_run_context'

    This seems to be part of the sessionstate.py file.

    Can something be done to fix this on my side?

    opened by ryanblumenow 7
  • Problem with session_id

    Problem with session_id

    Hi!, i'm trying to make a multi page with hydralit and i keep gettin this error:

    AttributeError: 'NoneType' object has no attribute 'session_id'

    I found a answer to this problem in the streamlit webb, wich was:

    ` def _get_state(hash_funcs=None): try: session = _get_session() except (AttributeError, NameError): session = sys

        if not hasattr(session, "_custom_session_state"):
            session._custom_session_state = _SessionState(session, hash_funcs)
    
        return session._custom_session_state
    

    `

    But when i dont' really know how to do it, when i call this function in my code gives me another error:

    NameError: name '_get_session' is not defined

    opened by PacoLunaMX 6
  • hydralit 1.0.12 and streamlit 1.9.0

    hydralit 1.0.12 and streamlit 1.9.0

    Hi !

    When I try to implement hydralit 1.0.12 in my App (I use streamlit 1.9.0) the following error occurs:

    from streamlit.script_run_context import get_script_run_ctx
    ModuleNotFoundError: No module named 'streamlit.script_run_context'
    

    It would be great if you could fix this. Thank you for sharing hydralit with us! :)

    opened by mckry 5
  • self.do_redirect does not change the menu option in the navbar

    self.do_redirect does not change the menu option in the navbar

    Hello @TangleSpace! I love this package!

    I hope I am not doing something wrong, but when I put the code self.do_redirect("Title of app to run") in my code on a button, the relevant app does run, but the navbar does not change to reflect this. It stays on the navbar option of the original app where the button is housed.

    Did I miss something, or do something incorrectly?

    opened by ryanblumenow 5
  • The api of streamlit.script_run_context api has changed

    The api of streamlit.script_run_context api has changed

    https://github.com/TangleSpace/hydralit/blob/ecaec562aedc3854c2dbae9be76e9a679da228b9/hydralit/sessionstate.py#L8

    at streamlitβ€˜s latest version,it use scriptrunner package:

    from streamlit.scriptrunner import get_script_run_ctx
    
    opened by cgx9 5
  • Import Syntax Issues With Streamlit 1.12.2

    Import Syntax Issues With Streamlit 1.12.2

    Trying to build a website using Hydralit, and encountered ModuleNotFound errors immediately upon importing the library.

    It seems like at some point Streamlit changed around their code schema; changing two lines in sessionstate.py seemed to do the trick:

    # from
    from streamlit.scriptrunner.script_run_context import get_script_run_ctx
    
    # to
    from streamlit.runtime.scriptrunner.script_run_context import get_script_run_ctx
    

    and

    # from
    from streamlit.server.server import Server
    
    # to
    from streamlit.web.server import Server
    

    I'm pretty new to Streamlit/Hydralit, but hopefully these changes won't break anything else? Seems to be working just fine from the testing I've been doing.

    opened by code49 4
  • Update for using `st.session_state`

    Update for using `st.session_state`

    As of Streamlit 1.12, the older API used to hack in a SessionState has been entirely deprecated (with an ugly hack to retrieve the Server from the GC) in favour of the built-in st.session_state. This comes from the advice of this gist here: https://gist.github.com/tvst/036da038ab3e999a64497f42de966a92

    I'd be happy to contribute a pull request (I think it should be minor changes), though my only concern is that hydralit_components may require the old SessionState. Could any of the maintainers of either repository comment on this?

    opened by saikumarmk 3
  • Latest streamlit version not supported

    Latest streamlit version not supported

    Hi, I'm having issue using the package.

    Traceback (most recent call last):
      File "/home/irfan/PycharmProjects/TES-Search/multiapp.py", line 1, in <module>
        import hydralit as hy
      File "/home/irfan/environments/The-Entities-Swissknife/lib/python3.7/site-packages/hydralit/__init__.py", line 5, in <module>
        from hydralit.hydra_app import HydraApp
      File "/home/irfan/environments/The-Entities-Swissknife/lib/python3.7/site-packages/hydralit/hydra_app.py", line 4, in <module>
        from hydralit.sessionstate import SessionState
      File "/home/irfan/environments/The-Entities-Swissknife/lib/python3.7/site-packages/hydralit/sessionstate.py", line 8, in <module>
        from streamlit.script_run_context import get_script_run_ctx
    ModuleNotFoundError: No module named 'streamlit.script_run_context'
    
    opened by mirfan899 3
  • How to change the default big loader?

    How to change the default big loader?

    I'm making a streamlit app based on the hydralit-example: https://github.com/TangleSpace/hydralit-example

    My app loads some data at first from database. While this is happening a rather large loading screen is present. image

    How can I tame this loader and select a more compact one?

    The structure of the code I use for the app-page: import hydralit as hy import pandas as pd import streamlit as st

    #create a wrapper class class generate_app_page(hy.HydraHeadApp): def run(self): col1, col2 = hy.columns([2,4]) msr = col1.selectbox('some nice label', get_ids_from_db())

    opened by DucoBouter 3
  • Loaders and spacing

    Loaders and spacing

    Hi there! This package is great.

    Two quick questions: I've integrated an existing app into Hydralit, but the top menu is appearing about an inch below the top of the screen. Is there a way to move it to the top?

    And, when I load a page/app I get all three loaders with the large text that is is "Loading now". Is there a way to customize which loader shows and remove/format the text?

    opened by rblumenowgs 3
  • thank you/small bug

    thank you/small bug

    howdy, this is incredible work. I want to be you.

    The loading_app in hydra_app points to a resources/failure.png file that comes with hydra-examples, but not with the module itself. It eclipses other error messages with "cant find failure.png". I think that line just needs to be wiped.

    bug 
    opened by rambam613 3
  • Keyed widget values are lost when switching the pages

    Keyed widget values are lost when switching the pages

    I have a two page application where in one of them I have a few widgets like text box which is connected to a session state variable via the key. It works fine until I am in this page but if I open the other page and comeback again then the widget values and their session state values are lost. I tried this solution https://gist.github.com/okld/8ca97ba892a7c20298fd099b196a8b4d but it fails and shows the error: Error details: Values for st.button, st.download_button, st.file_uploader, and st.form cannot be set using st.session_state. Any suggestion?

    opened by Yashar78 0
  • The uploaded video file co-exists among different apps

    The uploaded video file co-exists among different apps

    The first step in all apps is to upload a video file, like

    f = st.file_uploader("upload video")
    st.video(f)
    

    If I upload the video in app1, and then navigate to app2, the video also shows. Is there any solutio to clear the components in app2? Thanks.

    opened by xueliang 0
  • add basic logging options to HydraApp

    add basic logging options to HydraApp

    Hey there! I have been loving using Hydralit, but ran into the issue of the app runner catching all exceptions, and wanted the ability to pass a logger through to get some more information when an error occurs.

    Hope you find the addition useful! If not, no worries :)

    opened by josh-hm 0
  • making cookie based login work.

    making cookie based login work.

    So I was trying to hold a JWT token in cookie when login button is pressed.

    app.py

    import hydralit as hy
    import streamlit as st
    from hydralit_components import CookieManager
    from login import LoginApp
    
    cookie_manager = CookieManager()
    app = hy.HydraApp(title='test', favicon="πŸ™", hide_streamlit_markers=True,
                      allow_url_nav=True, sidebar_state="expanded",
                      layout='wide'
                      )
    
    app.add_app("Login", LoginApp(cookie_manager=cookie_manager), is_login=True, logout_label="Logout")
    
    @app.logout_callback
    def mylogout_cb():
        cookie_manager.delete('user_data')
        print('I was called from Hydralit at logout!')
    
    @app.login_callback
    def mylogin_cb():
        print('I was called from Hydralit at login!')
    

    login.py

    class LoginApp(HydraHeadApp):
        """
        This is an example login application to be used to secure access within a HydraApp streamlit application.
        This application implementation uses the allow_access session variable and uses the do_redirect method if the login check is successful.
    
        """
    
        def __init__(self, cookie_manager, title='', **kwargs):
            self.__dict__.update(kwargs)
            self.title = title
            self.cookie_manager = cookie_manager
    
        def _check_cookie_login(self) -> dict | None:
            """
            Check if the user is logged in.
            """
            session_cookie = self.cookie_manager.get("user_data")
            if session_cookie:
                return {'user': 'joe', 'level': 1}
            # ToDo: Check parse jwt and check if its valid and then return the user dict
    
        def run(self) -> None:
            """
            Application entry point.
            """
            login = self._check_cookie_login()
            if login:
                self.set_access(1, login['user'], cache_access=True)
                self.do_redirect()
    
            st.markdown("<h1 style='text-align: center;'>Secure Hydralit Login</h1>", unsafe_allow_html=True)
    
            c1, c2, c3, = st.columns([2, 2, 2])
    
            form_data = self._create_login_form(c2)
    
            pretty_btn = """
            <style>
            div[class="row-widget stButton"] > button {
                width: 100%;
            }
            </style>
            <br><br>
            """
            c2.markdown(pretty_btn, unsafe_allow_html=True)
    
            if form_data['submitted']:
                self._do_login(form_data, c2)
    
        @staticmethod
        def _create_login_form(parent_container) -> Dict:
    
            login_form = parent_container.form(key="login_form")
    
            form_state = {}
            form_state['username'] = login_form.text_input('Username')
            form_state['password'] = login_form.text_input('Password', type="password")
            form_state['submitted'] = login_form.form_submit_button('Login')
    
            parent_container.write("sample login -> joe & joe")
    
            return form_state
    
        def _do_login(self, form_data, msg_container) -> None:
    
            # access_level=0 Access denied!
            access_level = self._check_login(form_data)
    
            if access_level > 0:
                msg_container.success(f"βœ”οΈ Login success")
                with st.spinner("πŸ€“ now redirecting to application...."):
                    time.sleep(1)
    
                    self.set_access(1, form_data['username'], cache_access=True)
                    self.cookie_manager.set("user_data", 'True')
                    # Do the kick to the home page
                    self.do_redirect()
            else:
                self.session_state.allow_access = 0
                self.session_state.current_user = None
    
                msg_container.error(f"❌ Login unsuccessful, πŸ˜• please check your username and password and try again.")
    
        def _check_login(self, login_data) -> int:
    
            if login_data['username'] == 'joe' and login_data['password'] == 'joe':
                return 1
            else:
                return 0
    

    The above basically checks if there is a cookie with name user_data and logs in automatically if its set. When the cookie is not found it loads the modified example from example code.

    When the username and password matches. It should set a cookie with name user_data but this fails here. But doing the same using login_callback in app.py works

    @app.logout_callback
    def mylogout_cb():
        cookie_manager.delete('user_data')
        print('I was called from Hydralit at logout!')
    
    @app.login_callback
    def mylogin_cb():
        print('I was called from Hydralit at login!')
        cookie_manager.set('user_data', "Joe")
    

    Now whenever I reload the page I can skip the login page. But hitting the logout button sends invokes the mylogout_cb function. But cookie_manager.delete('user_data') has no effect and doesn't delete the cookie.

    But putting the same cookie_manager.delete('user_data') inside the mylogin_cb callback actually deletes the cookie on next login / on page reload.

    Am i missing something here ?. What would be the best way for me to achieve this. I tried extra_streamlit_components library and it has the same behaviour

    opened by 0-MegaMind-0 2
Releases(1.0.14)
  • 1.0.14(Sep 22, 2022)

  • 1.0.13(Jun 22, 2022)

    • Updated to support Streamlit >=1.9
    • Added parameter to disable the app loader entirely

    Cleaned up some of the formatting of the navbar for the new versions of Streamlit, it isn't perfect and never will be since Streamlit are determined to continue to change their crap which keeps partially breaking Hydralit, I'd say deliberately since the $800M company has it's own multi-app solution which they would love to kill Hydralit off.

    Source code(tar.gz)
    Source code(zip)
  • 1.0.12(Jan 28, 2022)

  • 1.0.11(Jan 22, 2022)

    • Fully supports all versions of Streamlit, including 1.4.0 (big thanks to oggers for some amazing support!).
    • Fixed the missing error handling bug, now all exceptions are raised to be handled however the user chooses instead of capturing and displaying an image. (big thanks to rambam613 for finding and fixing this bug, very nice!).
    • Can completely customise the Home and Logout menu entries, title and icon data from the add_app entry will be used for these items now as well as the existing.
    • Cleaned up the formatting when running in sticky and hiding Streamlit headers and footers, yes, they will come back now when using the navbar.
    • Removed the background effort for all loader animations (everyone hated this).
    • Smaller, sleeker navbar, including a much nicer non-animated mode.
    • Full offline support for Font Awesome and Bootstrap icons for navbar entries, as well as all emojis.
    • Improved performance with some refactoring of the session and transition code, apps load faster now.
    Source code(tar.gz)
    Source code(zip)
Owner
Jackson Storm
I am a data scientist and analyst. Worked for 20 years as all things programming, development, design and analysis, including databases and integration.
Jackson Storm
fds is a tool for Data Scientists made by DAGsHub to version control data and code at once.

Fast Data Science, AKA fds, is a CLI for Data Scientists to version control data and code at once, by conveniently wrapping git and dvc

DAGsHub 359 Dec 22, 2022
Transform-Invariant Non-Negative Matrix Factorization

Transform-Invariant Non-Negative Matrix Factorization A comprehensive Python package for Non-Negative Matrix Factorization (NMF) with a focus on learn

EMD Group 6 Jul 01, 2022
A distributed block-based data storage and compute engine

Nebula is an extremely-fast end-to-end interactive big data analytics solution. Nebula is designed as a high-performance columnar data storage and tabular OLAP engine.

Columns AI 131 Dec 26, 2022
Analytical view of olist e-commerce in Brazil

Analysis of E-Commerce Public Dataset by Olist The objective of this project is to propose an analytical view of olist e-commerce in Brazil. For this

Gurpreet Singh 1 Jan 11, 2022
Synthetic data need to preserve the statistical properties of real data in terms of their individual behavior and (inter-)dependences

Synthetic data need to preserve the statistical properties of real data in terms of their individual behavior and (inter-)dependences. Copula and functional Principle Component Analysis (fPCA) are st

32 Dec 20, 2022
OpenARB is an open source program aiming to emulate a free market while encouraging players to participate in arbitrage in order to increase working capital.

Overview OpenARB is an open source program aiming to emulate a free market while encouraging players to participate in arbitrage in order to increase

Tom 3 Feb 12, 2022
Includes all files needed to satisfy hw02 requirements

HW 02 Data Sets Mean Scale Score for Asian and Hispanic Students, Grades 3 - 8 This dataset provides insights into the New York City education system

7 Oct 28, 2021
Multiple Pairwise Comparisons (Post Hoc) Tests in Python

scikit-posthocs is a Python package that provides post hoc tests for pairwise multiple comparisons that are usually performed in statistical data anal

Maksim Terpilowski 264 Dec 30, 2022
Methylation/modified base calling separated from basecalling.

Remora Methylation/modified base calling separated from basecalling. Remora primarily provides an API to call modified bases for basecaller programs s

Oxford Nanopore Technologies 72 Jan 05, 2023
Exploratory Data Analysis of the 2019 Indian General Elections using a dataset from Kaggle.

2019-indian-election-eda Exploratory Data Analysis of the 2019 Indian General Elections using a dataset from Kaggle. This project is a part of the Cou

Souradeep Banerjee 5 Oct 10, 2022
We're Team Arson and we're using the power of predictive modeling to combat wildfires.

We're Team Arson and we're using the power of predictive modeling to combat wildfires. Arson Map Inspiration There’s been a lot of wildfires in Califo

Jerry Lee 3 Oct 17, 2021
A Python module for clustering creators of social media content into networks

sm_content_clustering A Python module for clustering creators of social media content into networks. Currently supports identifying potential networks

72 Dec 30, 2022
Streamz helps you build pipelines to manage continuous streams of data

Streamz helps you build pipelines to manage continuous streams of data. It is simple to use in simple cases, but also supports complex pipelines that involve branching, joining, flow control, feedbac

Python Streamz 1.1k Dec 28, 2022
follow-analyzer helps GitHub users analyze their following and followers relationship

follow-analyzer follow-analyzer helps GitHub users analyze their following and followers relationship by providing a report in html format which conta

Yin-Chiuan Chen 2 May 02, 2022
pyETT: Python library for Eleven VR Table Tennis data

pyETT: Python library for Eleven VR Table Tennis data Documentation Documentation for pyETT is located at https://pyett.readthedocs.io/. Installation

Tharsis Souza 5 Nov 19, 2022
Implementation in Python of the reliability measures such as Omega.

OmegaPy Summary Simple implementation in Python of the reliability measures: Omega Total, Omega Hierarchical and Omega Hierarchical Total. Name Link O

Rafael Valero FernΓ‘ndez 2 Apr 27, 2022
scikit-survival is a Python module for survival analysis built on top of scikit-learn.

scikit-survival scikit-survival is a Python module for survival analysis built on top of scikit-learn. It allows doing survival analysis while utilizi

Sebastian PΓΆlsterl 876 Jan 04, 2023
CPSPEC is an astrophysical data reduction software for timing

CPSPEC manual Introduction CPSPEC is an astrophysical data reduction software for timing. Various timing properties, such as power spectra and cross s

Tenyo Kawamura 1 Oct 20, 2021
A Python adaption of Augur to prioritize cell types in perturbation analysis.

A Python adaption of Augur to prioritize cell types in perturbation analysis.

Theis Lab 2 Mar 29, 2022
An Integrated Experimental Platform for time series data anomaly detection.

Curve Sorry to tell contributors and users. We decided to archive the project temporarily due to the employee work plan of collaborators. There are no

Baidu 486 Dec 21, 2022