from typing import Union, cast
import solara
import traitlets
import asyncio
from anyio import to_thread
import httpx
import solara._stores
import logging
logger = logging.getLogger("app")
btc = solara.Reactive(solara._stores.SharedStore(cast(Union[float, None], None)))
clicks = solara.Reactive(solara._stores.SharedStore(0))
def increase_clicks():
clicks.value += 1
async def fetch_price():
while 1:
await asyncio.sleep(1)
try:
async with httpx.AsyncClient() as client:
url = "https://api.binance.com/api/v1/ticker/price?symbol=BTCUSDT"
response = await client.get(url)
btc.value = float(response.json()["price"])
print("btc.value", btc.value)
except Exception as e:
logger.exception("error in fetch_price")
asyncio.create_task(fetch_price())
@solara.component
def Page():
print("render btc.value", btc.value)
# make this component update when clicks changes
with solara.Card("BTC price"):
# if we do not make it conditional, like:
# solara.Preformatted(f"$ {btc.value:,}" if btc.value else "loading...")
# it does not crash
if btc.value is not None:
solara.Preformatted(f"$ {btc.value:,}")
else:
solara.ProgressLinear()
with solara.Card("Button clicks"):
solara.Text(f"{clicks.value:,} clicks")
with solara.CardActions():
solara.Button("Increase", on_click=increase_clicks, text=True)