Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with session_id #13

Closed
PacoLunaMX opened this issue Oct 15, 2021 · 6 comments
Closed

Problem with session_id #13

PacoLunaMX opened this issue Oct 15, 2021 · 6 comments

Comments

@PacoLunaMX
Copy link

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

@TangleSpace
Copy link
Owner

some code would be helpful, as the session state management in Hydralit isn't exactly the same as Streamlit and the "answers" on the forum aren't specific to Hydralit.

Hydralit needs to know your custom session parameters ahead of time, as you might want to share them across apps, so the approach is to tell Hydralit in the constructor about your session state parameters, then you get or set their values from the parent or child apps using some simpler methods than the "hacks" they talk about in the forums. For example, if you want to add two parameters called "session_id" and "my_special_value" to the app and have it available across all the child apps, if you are using the decorator method to add apps, you can get/set the values as per the example below.

`
#when we import hydralit, we automatically get all of Streamlit
import hydralit as hy

#custom user session parameters to share across apps
user_s_params = {'session_id': 42, 'my_special_value': 'Hydralit Fun!'}

app = hy.HydraApp(title='Simple Multi-Page App',navbar_animation=True, session_params=user_s_params)

@app.addapp(is_home=True)
def my_home():
hy.info('Hello from Home!')

@app.addapp()
def app2():
hy.info('Hello from app 2')
app.session_state.my_special_value='I changed the parameter'

@app.addapp(title='The Best', icon="🥰")
def app3():
hy.info('Hello from app 3, A.K.A, The Best 🥰')
app.session_state.session_id=51

#Run the whole lot, we get navbar, state management and app isolation, all with this tiny amount of work.
app.run()

#print all the user defined session state parameters and their values
print(app.get_user_session_params())
`

you can get the value of any user parameter by calling app.get_user_session_params(), this returns a dict with the key/values of your parameters. You can set the value from within a child app or the parent by directly assigning a value, app.session_state.session_id=51

If you are using the class method to create a child app, it is still recommended you create and provide a default value for the parameters at the start in the constructor for the HydraApp, the only difference is within the child you can get/set the user parameters you defined like this,
self.session_state.session_id=51 print(f'session_id value is: {self.session_state.session_id}')

If you try to assign a value to a session state parameter within a child app that doesn't exist, it will be automatically created for you, for example
self.session_state.crazy_value = 99 print(f'crazy_value is: {self.session_state.crazy_value}')

You can access this from any other child apps once it is create, like this, self.session_state.crazy_value, if it doesn't exist, you will get the much more informative error,
Error details: 'SessionState' object has no attribute 'crazy_value'

If you simple and directly assign a value to a new parameter, that will create it automatically for you from within the both the parent and child apps.

The catch is you haven't specially told the parent about this parameter, so when you call app.get_user_session_params(), it won't appear. Doesn't mean it isn't there, you simply have defined it at the start. Hydralit was built to allow flexibility, but encourage best practise.

@PacoLunaMX
Copy link
Author

Hi!, i have use the exact same code that you show and it stills gives me the error

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

sorry, i'm not an experct in python, and i'm trying to use Hydralit for a project. I really appreciate your time to help me.

@PacoLunaMX
Copy link
Author

This is the raw error

Traceback (most recent call last): File "C:\Users\fhino\Downloads\borrar.py", line 9, in <module> app = HydraApp( File "C:\Users\fhino\AppData\Local\Programs\Python\Python39\lib\site-packages\hydralit\hydra_app.py", line 163, in __init__ self.session_state = SessionState.get(previous_app=None, selected_app=None,other_nav_app=None, preserve_state=preserve_state, allow_access=self._no_access_level,logged_in=False,access_hash=None) File "C:\Users\fhino\AppData\Local\Programs\Python\Python39\lib\site-packages\hydralit\sessionstate.py", line 60, in get session_id = ReportThread.get_report_ctx().session_id AttributeError: 'NoneType' object has no attribute 'session_id' [Finished in 2.2s]

@TangleSpace
Copy link
Owner

Are you running your script borrar.py with this command:
streamlit run borrar.py
?
As the only time I've seen that error is when someone runs their python script directly, like this:
python borrar.py

This won't work, Streamlit and Hydralit have to be run using the Streamlit run command, like this in your case.

streamlit run borrar.py

Can you please confirm what version of Streamlit and Hydralit you are running?
To make sure you are using the latest, please ensure to run,
pip install -U streamlit hydralit

If you could also share some code, as the only reason for an error with the session state like is for some reason your environment isn't able to even create a Streamlit session object, very odd.

@PacoLunaMX
Copy link
Author

Yes, this is the exact code. The code from 'borrar.py' is the same:
`import streamlit as st
from hydralit import HydraApp
from Club_IQ import Club_IQ
from Scout_IQ import Scout_IQ
import sys

def main():
user_s_params = {'session_id': 42, 'my_special_value': 'Hydralit Fun!'}

app = HydraApp(title="App", use_navbar=True, session_params=user_s_params)

app.add_app('Club IQ', app=Club_IQ())
app.add_app('Scout IQ', app=Scout_IQ())

app.run()

if name == "main":
main()`

When i run it in sublime text gives the error AttributeError: 'NoneType' object has no attribute 'session_id'.

When i run it in the terminal with streamlit run main.py it runs the app and open it in the browser but gives the next error:

AttributeError: 'NoneType' object has no attribute 'assign_session'.

It shows the title 'Club IQ', but it does not show anything more, just the error. The error also appears in the terminal.

@TangleSpace
Copy link
Owner

ok, for starters i can see alot wrong with your code, instead of me completely rewriting your code so it works, i suggest you have another look at the example code in the read me on the home page, https://github.com/TangleSpace/hydralit

There is also an extensive example application located here, https://github.com/TangleSpace/hydralit-example

Your Python code isn't correct, don't worry about Streamlit or Hydralit, for example, when you run a file called "borray.py", you don't use the commend streamlit run main.py, you use the command streamlit run borray.py

main is the function, not the file name.

Also, this line is completely incorrect if name == "main":

this is basic Python, it should be,
if __name__ == '__main__':

It also appears whatever Club_IQ and Scout_IQ are, these need to be Python classes that inherit from HydraHeadApp like the sample on converting or wrapping code in the read me, for example like this.

import streamlit as st

#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------------------------------------------
        <put all your code here>

or you can just write python functions and use the decorator method to add them as apps, again two examples are in the read me https://github.com/TangleSpace/hydralit

for example, don't touch anything about this code, just put it in a file named example.py and run it with the command streamlit run example.py, it will work just fine.

#when we import hydralit, we automatically get all of Streamlit
import hydralit as hy

app = hy.HydraApp(title='Simple Multi-Page App')

@app.addapp(is_home=True)
def my_home():
 hy.info('Hello from Home!')

@app.addapp()
def app2():
 hy.info('Hello from app 2')

@app.addapp(title='The Best', icon="🥰")
def app3():
 hy.info('Hello from app 3, A.K.A, The Best 🥰')

#Run the whole lot, we get navbar, state management and app isolation, all with this tiny amount of work.
app.run()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants