I've run into an issue writing a PyShiny app that I can't seem to find the answer to and I'm hoping someone here might be able to help. The app I'm writing needs to stream data from a SQL database (I'm using pandas.read_sql for this) but the database path will be specified by the user as a UI input (ui.input_file). I'd like to do this using invalidateLater.
The code below is a simple demonstration of the same issue without using my app's specific code. In this bit of code, I'm looking to initiate the process with a single click of an action button, then periodically recalculate the shape of the database every 5 seconds.
import pandas as pd
import sqlite3
from shiny import App, render, ui, reactive
app_ui = ui.page_fluid(
ui.input_file("file1", "Choose a file to upload:", multiple=False),
ui.input_action_button(id="go", label="Go", class_="btn-warning"),
ui.output_text("output_txt"),
)
def server(input, output, session):
def get_data():
if input.go() > 0:
reactive.invalidate_later(5)
cnx = sqlite3.connect(input.file1()[0]["datapath"])
df = pd.read_sql("SELECT * FROM table1", cnx)
cnx.close()
return df
@output(id="output_txt")
@render.text
def output():
d = get_data()
print(d.shape)
return d.shape
app = App(app_ui, server)
Instead, the app seems to be getting the same original shape of the database (the shape first calculated upon clicking the action button), even if I add or remove rows from the database while its running... Why is this happening? I'm fairly experienced with Python but am relatively new to Shiny so I haven't fully grasped the idea of reactively - I'd really appreciate any tips. Thank you!