I am using the st.secrets()
feature to supply my Streamlit app with a login token for an on-demand Dask Cluster via Coiled.io
The script runs fine before including the st.secrets()
line but fails when I include it with the following message in the app terminal, copied below.
I’m not familiar enough with hashing to understand what this actually means
– any help here would be very much appreciated!
streamlit.hashing.UnhashableTypeError: Cannot hash object of type `_thread.RLock`, found in the body of `get_client()`.
While caching the body of `get_client()`, Streamlit encountered an
object of type `_thread.RLock`, which it does not know how to hash.
To address this, please try helping Streamlit understand how to hash that type
by passing the `hash_funcs` argument into `@st.cache`. For example:
@st.cache(hash_funcs={_thread.RLock: my_hash_func})
def my_func(...):
...
If you don't know where the object of type `_thread.RLock` is coming
from, try looking at the hash chain below for an object that you do recognize,
then pass that to `hash_funcs` instead:
Object of type _thread.RLock: <unlocked _thread.RLock object owner=0 count=0 at 0x7f2b088cedb0>
Object of type builtins.tuple: ('_lock', <unlocked _thread.RLock object owner=0 count=0 at 0x7f2b088cedb0>)
Object of type builtins.dict: {'_secrets': {'coiled_token': '<hidden>', 'coiled_account': '<hidden>'}, '_lock': <unlocked _thread.RLock object owner=0 count=0 at 0x7f2b088cedb0>, '_file_watcher_installed': True, '_file_path': '/app/streamlit/.streamlit/secrets.toml'}
Object of type streamlit.secrets.Secrets: {'coiled_token': '<hidden>', 'coiled_account': '<hidden>'}
Object of type builtins.function: <function get_client at 0x7f2b5b4e6ca0>
1 Like
Hi @rrpelgrim 
Are you including st.secrets[]
in your get_client()
function and decorating the function with @st.cache()
? If so, you can turn off hashing for the object of type _thread.RLock
by modifying the decorator to look like the following:
@st.cache(hash_funcs={"_thread.RLock": lambda _: None})
def get_client():
Happy Streamlit’ing! 
Snehan
1 Like
Hi @snehankekre, thanks for your response.
See my updated code below. This is still not working unfortunately.
Any pointers as to what I should be doing differently are very welcome!
@st.cache(allow_output_mutation=True, hash_funcs={"_thread.RLock": lambda _: None})
def get_client():
cluster_state.write("Starting or connecting to Coiled cluster...")
cluster = coiled.Cluster(
n_workers=10,
name="coiled-streamlit",
software="coiled-examples/streamlit",
account=st.secrets("coiled_account"),
)
client = Client(cluster)
return client
This fails with
CacheKeyNotFoundError("Key not found in mem cache")
streamlit.caching.CacheKeyNotFoundError: Key not found in mem cache
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/appuser/venv/lib/python3.8/site-packages/streamlit/script_runner.py", line 350, in _run_script
exec(code, module.__dict__)
File "/app/streamlit/coiled-streamlit-with-sharing.py", line 43, in <module>
client = get_client()
File "/home/appuser/venv/lib/python3.8/site-packages/streamlit/caching.py", line 543, in wrapped_func
return get_or_create_cached_value()
File "/home/appuser/venv/lib/python3.8/site-packages/streamlit/caching.py", line 527, in get_or_create_cached_value
return_value = func(*args, **kwargs)
File "/app/streamlit/coiled-streamlit-with-sharing.py", line 37, in get_client
account=st.secrets("coiled_account"),
TypeError: 'Secrets' object is not callable
Use square brackets instead of parenthesis 
st.secrets["coiled_account"]
Best, 
Snehan
hits himself on the head
Of course! Sorry to bother you with that one… 
Hi!
I’m having a similar problem where I’m trying to pass a boto3 session to a function that then runs a SQL query.
I get an error UnhashableTypeError: Cannot hash object of type _thread.lock, found in the arguments of load_trip_data().
How would I deal with this?
This is my code
@st.cache()
def load_trip_data(role_session: Session):
run_query_with_this_session
Hi @AditSanghvi94,
What does the load_trip_data()
function return? If the function returns the results of a SQL query, you can decorate the function with @st.experimental_memo
. If it returns a non-data object, such a boto3 session, decorate the function with @st.experimental_singleton
.
Read more about our new and improved cache primitives and when to use memo vs singleton here: Experimental cache primitives - Streamlit Docs
The following is not guaranteed to work, but if you want to continue using the slower @st.cache
, replace it with the following:
@st.cache(allow_output_mutation=True, hash_funcs={"_thread.RLock": lambda _: None})
Best, 
Snehan
The function runs a SQL query on athena, loads some data into a pandas dataframe and returns the dataframe
Thanks for the clarification. What you’re looking for is @st.experimental_memo
. If you receive a hashing related error after using memo, you can prefix the unhashable function argument with an underscore, like so:
@st.experimental_memo
def load_trip_data(_role_session: Session):
run_query_with_this_session
Any parameter whose name begins with _ will not be hashed. You can use this as an “escape hatch” for parameters that are not hashable.
Best, 
Snehan