Hi, I am creating a support web app to help the support team at my company, at the moment is running locally.
Is a simple application, will receive a number and execute a ‘select’ on database and show to user. After this, I want a second button be enabled when the query is shown on the screen.
So is a button to consult and other (to delete a line in db). But I can’t make it work, any help is welcome I’m open to advice.
Python 3.12.3
Streamlit, version 1.34.0
Hi @bentohiago, welcome to the forum!
Can you give a simplified example showing what you’ve tried, and what has gone wrong?
Here’s a very simple example that might be helpful using st.session_state as a fake database.
import streamlit as st
if "fake_db" not in st.session_state:
st.session_state["fake_db"] = [
{"id": 1, "name": "John Doe", "email": "john@doe.com"},
{"id": 2, "name": "Jane Doe", "email": "jane@doe.com"},
]
def get_all_usernames():
return [user["name"] for user in st.session_state["fake_db"]]
def get_user_by_name(name):
return next(
(user for user in st.session_state["fake_db"] if user["name"] == name), None
)
def delete_user(user_id):
st.session_state["fake_db"] = [
user for user in st.session_state["fake_db"] if user["id"] != user_id
]
@st.experimental_dialog("Add user")
def add_user():
name = st.text_input("Name")
email = st.text_input("Email")
if st.button("Add"):
st.session_state["fake_db"].append(
{"id": len(st.session_state["fake_db"]) + 1, "name": name, "email": email}
)
st.rerun()
selected_user = st.selectbox("Select a user", [None] + get_all_usernames())
selected_user_data = get_user_by_name(selected_user)
if selected_user_data:
st.write(f"Name: {selected_user_data['name']}")
st.write(f"Email: {selected_user_data['email']}")
st.button("Delete user", on_click=delete_user, args=(selected_user_data["id"],))
else:
if st.button("Add user"):
add_user()
Hi, thanks man!
In below a simple example, a part of the full code.
I realize that the delete button ( btns[1] ) only activates when I click Two times on the first button.
[up there is the conection with database]
# start state
if 'botao_ativo' not in st.session_state:
st.session_state.botao_ativo = False
# if 'resultados_exibidos' not in st.session_state:
# st.session_state.resultados_exibidos = False
# Title
st.title('Consulta Imagem GED')
# Caixa de texto para o campo EMPRESA DO CTE
emp = st.text_input('Digite a EMPRESA DO CTE:', placeholder= "Qualquer empresa do Sistema Senior")
# Caixa de texto para o campo NUM
num = st.text_input('Digite o NUMERO DO CTE:', placeholder="EX: '4665656' ou '4665656, 4665657'")
# Botoes para Consultar e deletar
btns = st.columns((3,3,7))
with btns[0]:
consultar_bt = st.button('Consultar')
with btns[1]:
deletar_bt = st.button("Deletar", key="del", type="primary", disabled=not st.session_state.botao_ativo)
# Botão para iniciar a consulta
if consultar_bt:
# verifica se o campo empresa está preenchido
if emp == "" and num != "":
# Separa itens por vírgula
lista_num = num.split(",")
resultados = []
# Verifica se possui apenas 1 número e executa a consulta se sim
if len(lista_num) == 1:
resultado = consult_ged_emp(lista_num[0])
resultados.extend(resultado)
else:
# Se tiver mais de 1 número
for num_cte in lista_num:
resultado = consult_ged_emp(num_cte)
resultados.extend(resultado)
# Show Results to user
if resultados:
st.markdown('<h2>Resultado da consulta:</h2>', unsafe_allow_html=True)
for resultado in resultados:
#st.write(resultado)
st.markdown(f"""
<div style="background-color: #708090; padding: 10px; margin: 10px 0; border-radius: 5px; color: #000;">
<strong>Empresa:</strong> {resultado["empresa"]}<br>
<strong>Usuário:</strong> {resultado["usuario"]}<br>
<strong>Data e Arquivo:</strong> {resultado["data_arq"]}
</div>
""", unsafe_allow_html=True)
st.session_state.botao_ativo = True # Atualiza o estado para indicar que os resultados foram exibidos
elif resultado:
st.markdown('<h2>Resultado da consulta:</h2>', unsafe_allow_html=True)
st.write(resultado)
st.session_state.botao_ativo = True # Atualiza o estado para indicar que os resultados foram exibidos
else:
st.error('Nenhum resultado encontrado para os valores fornecidos.')
st.session_state.botao_ativo = False # atualiza o estado para indicar que os resultados nao foram exibidos
That’s because the streamlit script runs from top to bottom on any input, so in this case what happens is, if I’m reading your code correctly:
- You push btns[0]
- You check to see if
butao_ativo
is true, it’s not, so btns[1] stays disabled
- You check btns[0] and do a bunch of stuff if it’s clicked, including changing
butao_ativo
.
Note that 3 happens after 2, so it won’t be until the next time the script runs that btns[1] is active.
There are two ways around this:
- Move the code that should run if btns[0] is clicked into a function, and do
on_click=that_function
. on_click
functions like that always run as if they were at the top of the script, so if you change butao_ativo
inside of that function, it will be changed by the time the script gets to btns[1].
- After you change
butao_ativo
in your current script, call st.rerun()
to rerun the script from top to bottom.
Ok, I will try.
I hope to do this in the best way.
I think its solved.
In addition to create a function to if btns, I turn the list resultados in a st.session_state.resultados = [...]
, help me a use better the list.
Now I have problems to use @st.experimental_dialog
conditionaly, but I that is problem to annother topic.
Thanks a lot for the help.
1 Like