Hi there,
I seem to have this error (see picture) whenever I start my streamlit application.
However, if I select and go through EACH single page, then the error goes away and the application works as intended (see picture).
I am using fellow forum member okld’s custom sessionstate, and it does work as intended.
Does anyone know what the issue could be and how to solve this?
Here’s the code:
import streamlit as st
from streamlit.hashing import _CodeHasher
from streamlit.report_thread import get_report_ctx
from streamlit.server.server import Server
import py_avataaars as pa
from PIL import Image
import base64
from random import randrange
def main():
state = _get_state()
pages = {
"Background": page_background,
"Skin Color": page_skin_color,
"Head": page_top_type,
"Hair Color": page_hair_color,
"Hat Color": page_hat_color,
"Eyebrow Type": page_eyebrow_type,
"Eye Type": page_eye_type,
"Glasses": page_glasses_type,
"Mouth": page_mouth_type,
"Facial Hair Type": page_facial_hair_type,
"Facial Hair Color": page_facial_hair_color,
"Clothe": page_clothe_type,
"Clothe Color": page_clothe_color,
"Clothe Graphic": page_clothe_graphic,
}
st.sidebar.title("Avatar Customization Options")
page = st.sidebar.radio("Select option", tuple(pages.keys()))
# Display the selected page with the session state
pages[page](state)
# Mandatory to avoid rollbacks with widgets, must be called at the end of your app
state.sync()
# Changing Avatar List Names
pa.FacialHairType.NONE = pa.FacialHairType.DEFAULT
pa.MouthType.HAPPY = pa.FacialHairType.DEFAULT
pa.EyesType.OPEN = pa.EyesType.DEFAULT
pa.AccessoriesType.NONE = pa.AccessoriesType.DEFAULT
def page_background(state):
list_background = ['CIRCLE','TRANSPARENT']
st.title("Background")
state.option_background = st.selectbox('Background',list_background, list_background.index(state.option_background) if state.option_background else 0)
display_state_values(state)
def page_skin_color(state):
list_skin_color = ['BLACK','TANNED','YELLOW','PALE','LIGHT','BROWN','DARK_BROWN']
st.title("Skin Color")
state.option_skin_color = st.selectbox('Skin Color',list_skin_color, list_skin_color.index(state.option_skin_color) if state.option_skin_color else 0)
display_state_values(state)
def page_top_type(state):
list_top_type = ['NO_HAIR','HAT','HIJAB','TURBAN','WINTER_HAT1','WINTER_HAT2','WINTER_HAT3','WINTER_HAT4','LONG_HAIR_BIG_HAIR','LONG_HAIR_BOB','LONG_HAIR_BUN',
'LONG_HAIR_CURLY','LONG_HAIR_CURVY','LONG_HAIR_DREADS','LONG_HAIR_FRIDA','LONG_HAIR_FRO','LONG_HAIR_FRO_BAND','LONG_HAIR_NOT_TOO_LONG','LONG_HAIR_MIA_WALLACE',
'LONG_HAIR_SHAVED_SIDES','LONG_HAIR_STRAIGHT','LONG_HAIR_STRAIGHT2','LONG_HAIR_STRAIGHT_STRAND','SHORT_HAIR_DREADS_01','SHORT_HAIR_DREADS_02','SHORT_HAIR_FRIZZLE',
'SHORT_HAIR_SHAGGY_MULLET','SHORT_HAIR_SHORT_CURLY','SHORT_HAIR_SHORT_FLAT','SHORT_HAIR_SHORT_ROUND','SHORT_HAIR_SHORT_WAVED','SHORT_HAIR_SIDES','SHORT_HAIR_THE_CAESAR','SHORT_HAIR_THE_CAESAR_SIDE_PART']
#Removed 'EYE_PATCH'
st.title("Head")
state.option_top_type = st.selectbox('Head',list_top_type, list_top_type.index(state.option_top_type) if state.option_top_type else 0)
display_state_values(state)
def page_hair_color(state):
list_hair_color = ['BLACK','AUBURN','BLONDE','BLONDE_GOLDEN','BROWN','BROWN_DARK','PASTEL_PINK','PLATINUM','RED','SILVER_GRAY']
st.title("Hair Color")
state.option_hair_color = st.selectbox('Hair Color',list_hair_color, list_hair_color.index(state.option_hair_color) if state.option_hair_color else 0)
display_state_values(state)
def page_hat_color(state):
list_hat_color = ['BLACK','BLUE_01','BLUE_02','BLUE_03','GRAY_01','GRAY_02','HEATHER','PASTEL_BLUE','PASTEL_GREEN','PASTEL_ORANGE','PASTEL_RED','PASTEL_YELLOW','PINK','RED','WHITE']
#['BLACK','AUBURN','BLONDE','BLONDE_GOLDEN','BROWN','BROWN_DARK','PASTEL_PINK','PLATINUM','RED','SILVER_GRAY']
st.title("Hat Color (if a hat type is selected as Head)")
state.option_hat_color = st.selectbox('Hat Color (if a hat is selected as Head)',list_hat_color, list_hat_color.index(state.option_hat_color) if state.option_hat_color else 0)
display_state_values(state)
def page_eyebrow_type(state):
list_eyebrow_type = ['DEFAULT','DEFAULT_NATURAL','ANGRY','ANGRY_NATURAL','FLAT_NATURAL','RAISED_EXCITED','RAISED_EXCITED_NATURAL','SAD_CONCERNED','SAD_CONCERNED_NATURAL','UNI_BROW_NATURAL','UP_DOWN','UP_DOWN_NATURAL','FROWN_NATURAL']
st.title("Eyebrow Type")
state.option_eyebrow_type = st.selectbox('Eyebrow Type',list_eyebrow_type, list_eyebrow_type.index(state.option_eyebrow_type) if state.option_eyebrow_type else 0)
display_state_values(state)
def page_eye_type(state):
list_eye_type = ['OPEN','CLOSE','CRY','DIZZY','EYE_ROLL','HAPPY','HEARTS','SIDE','SQUINT','SURPRISED','WINK','WINK_WACKY']
st.title("Eye Type")
state.option_eye_type = st.selectbox('Eye Type',list_eye_type, list_eye_type.index(state.option_eye_type) if state.option_eye_type else 0)
display_state_values(state)
def page_glasses_type(state):
list_glasses_type = ['NONE','KURT','PRESCRIPTION_01','PRESCRIPTION_02','ROUND','SUNGLASSES','WAYFARERS']
st.title("Glasses")
state.option_glasses_type = st.selectbox('Glasses',list_glasses_type, list_glasses_type.index(state.option_glasses_type) if state.option_glasses_type else 0)
display_state_values(state)
def page_mouth_type(state):
list_mouth_type = ['HAPPY','CONCERNED','DISBELIEF','EATING','GRIMACE','SAD','SCREAM_OPEN','SERIOUS','SMILE','TONGUE','TWINKLE','VOMIT']
st.title("Mouth")
state.option_mouth_type = st.selectbox('Mouth',list_mouth_type, list_mouth_type.index(state.option_mouth_type) if state.option_mouth_type else 0)
display_state_values(state)
def page_facial_hair_type(state):
list_facial_hair_type = ['NONE','BEARD_MEDIUM','BEARD_LIGHT','BEARD_MAJESTIC','MOUSTACHE_FANCY','MOUSTACHE_MAGNUM']
st.title("Facial Hair Type")
state.option_facial_hair_type = st.selectbox('Facial Hair Type',list_facial_hair_type, list_facial_hair_type.index(state.option_facial_hair_type) if state.option_facial_hair_type else 0)
display_state_values(state)
def page_facial_hair_color(state):
list_facial_hair_color = ['BLACK','BLUE_01','BLUE_02','BLUE_03','GRAY_01','GRAY_02','HEATHER','PASTEL_BLUE','PASTEL_GREEN','PASTEL_ORANGE','PASTEL_RED','PASTEL_YELLOW','PINK','RED','WHITE']
#['BLACK','AUBURN','BLONDE','BLONDE_GOLDEN','BROWN','BROWN_DARK','PASTEL_PINK','PLATINUM','RED','SILVER_GRAY']
st.title("Facial Hair Color")
state.option_facial_hair_color = st.selectbox('Facial Hair Color',list_facial_hair_color, list_facial_hair_color.index(state.option_facial_hair_color) if state.option_facial_hair_color else 0)
display_state_values(state)
def page_clothe_type(state):
list_clothe_type = ['BLAZER_SHIRT','BLAZER_SWEATER','COLLAR_SWEATER','GRAPHIC_SHIRT','HOODIE','OVERALL','SHIRT_CREW_NECK','SHIRT_SCOOP_NECK','SHIRT_V_NECK']
st.title("Clothe")
state.option_clothe_type = st.selectbox('Clothe',list_clothe_type, list_clothe_type.index(state.option_clothe_type) if state.option_clothe_type else 0)
display_state_values(state)
def page_clothe_color(state):
list_clothe_color = ['BLACK','BLUE_01','BLUE_02','BLUE_03','GRAY_01','GRAY_02','HEATHER','PASTEL_BLUE','PASTEL_GREEN','PASTEL_ORANGE','PASTEL_RED','PASTEL_YELLOW','PINK','RED','WHITE']
st.title("Clothe Color")
state.option_clothe_color = st.selectbox('Clothe Color',list_clothe_color, list_clothe_color.index(state.option_clothe_color) if state.option_clothe_color else 0)
display_state_values(state)
def page_clothe_graphic(state):
list_clothe_graphic_type = ['BAT','CUMBIA','DEER','DIAMOND','HOLA','PIZZA','RESIST','SELENA','BEAR','SKULL_OUTLINE','SKULL']
st.title("Clothe Graphic (if GRAPHIC_SHIRT is selected as Clothe)")
state.option_clothe_graphic_type = st.selectbox('Clothe Graphic (if GRAPHIC_SHIRT is selected as Clothe)',list_clothe_graphic_type, list_clothe_graphic_type.index(state.option_clothe_graphic_type) if state.option_clothe_graphic_type else 0)
display_state_values(state)
# Static Part
def display_state_values(state):
avatar = pa.PyAvataaar(
style=eval('pa.AvatarStyle.%s' % state.option_background),
skin_color=eval('pa.SkinColor.%s' % state.option_skin_color),
hair_color=eval('pa.HairColor.%s' % state.option_hair_color),
facial_hair_type=eval('pa.FacialHairType.%s' % state.option_facial_hair_type),
facial_hair_color=eval('pa.ClotheColor.%s' % state.option_facial_hair_color),
top_type=eval('pa.TopType.%s' % state.option_top_type),
hat_color=eval('pa.ClotheColor.%s' % state.option_hat_color),
mouth_type=eval('pa.MouthType.%s' % state.option_mouth_type),
eye_type=eval('pa.EyesType.%s' % state.option_eye_type),
eyebrow_type=eval('pa.EyebrowType.%s' % state.option_eyebrow_type),
nose_type=pa.NoseType.DEFAULT,
accessories_type=eval('pa.AccessoriesType.%s' % state.option_glasses_type),
clothe_type=eval('pa.ClotheType.%s' % state.option_clothe_type),
clothe_color=eval('pa.ClotheColor.%s' % state.option_clothe_color),
clothe_graphic_type=eval('pa.ClotheGraphicType.%s' % state.option_clothe_graphic_type),
)
rendered_avatar = avatar.render_png_file('avatar.png')
image = Image.open('avatar.png')
st.image(image)
st.markdown(imagedownload('avatar.png'), unsafe_allow_html=True)
# Custom function by dataprofessor for encoding an donwloading avatar image
def imagedownload(filename):
image_file = open(filename, 'rb')
b64 = base64.b64encode(image_file.read()).decode() # strings <-> bytes conversions
href = f'<a href="data:image/png;base64,{b64}" download={filename}>Download {filename}</a>'
return href
# SessionState code from st_demo_settings.py
class _SessionState:
def __init__(self, session, hash_funcs):
"""Initialize SessionState instance."""
self.__dict__["_state"] = {
"data": {},
"hash": None,
"hasher": _CodeHasher(hash_funcs),
"is_rerun": False,
"session": session,
}
def __call__(self, **kwargs):
"""Initialize state data once."""
for item, value in kwargs.items():
if item not in self._state["data"]:
self._state["data"][item] = value
def __getitem__(self, item):
"""Return a saved state value, None if item is undefined."""
return self._state["data"].get(item, None)
def __getattr__(self, item):
"""Return a saved state value, None if item is undefined."""
return self._state["data"].get(item, None)
def __setitem__(self, item, value):
"""Set state value."""
self._state["data"][item] = value
def __setattr__(self, item, value):
"""Set state value."""
self._state["data"][item] = value
def clear(self):
"""Clear session state and request a rerun."""
self._state["data"].clear()
self._state["session"].request_rerun()
def sync(self):
"""Rerun the app with all state values up to date from the beginning to fix rollbacks."""
# Ensure to rerun only once to avoid infinite loops
# caused by a constantly changing state value at each run.
#
# Example: state.value += 1
if self._state["is_rerun"]:
self._state["is_rerun"] = False
elif self._state["hash"] is not None:
if self._state["hash"] != self._state["hasher"].to_bytes(self._state["data"], None):
self._state["is_rerun"] = True
self._state["session"].request_rerun()
self._state["hash"] = self._state["hasher"].to_bytes(self._state["data"], None)
def _get_session():
session_id = get_report_ctx().session_id
session_info = Server.get_current()._get_session_info(session_id)
if session_info is None:
raise RuntimeError("Couldn't get your Streamlit Session object.")
return session_info.session
def _get_state(hash_funcs=None):
session = _get_session()
if not hasattr(session, "_custom_session_state"):
session._custom_session_state = _SessionState(session, hash_funcs)
return session._custom_session_state
if __name__ == "__main__":
main()
Much appreciated!