Spaces:
Runtime error
Runtime error
import gradio as gr | |
import requests | |
import time | |
import datetime | |
import threading | |
# Function to fetch cryptocurrency prices from CoinGecko | |
def get_crypto_prices(crypto_ids, vs_currency="usd"): | |
try: | |
ids = ",".join(crypto_ids) | |
url = f"https://api.coingecko.com/api/v3/simple/price?ids={ids}&vs_currencies={vs_currency}" | |
response = requests.get(url) | |
response.raise_for_status() | |
data = response.json() | |
prices = {} | |
for crypto_id in crypto_ids: | |
if crypto_id in data: | |
prices[crypto_id] = data[crypto_id][vs_currency] | |
else: | |
prices[crypto_id] = "N/A" # Indicate if price is not available | |
return prices | |
except requests.exceptions.RequestException as e: | |
return {crypto_id: f"Error: {e}" for crypto_id in crypto_ids} | |
except Exception as e: | |
return {crypto_id: f"Error: {e}" for crypto_id in crypto_ids} | |
# Function to get the current time as a string | |
def get_current_time(): | |
now = datetime.datetime.now() | |
return now.strftime("%Y-%m-%d %H:%M:%S") | |
# Function to calculate the countdown to the next minute | |
def get_countdown(): | |
now = datetime.datetime.now() | |
seconds_to_next_minute = 60 - now.second | |
return f"Next Update in: {seconds_to_next_minute} seconds" | |
# Shared data (prices) | |
shared_prices = {} # This is the "Prices" that is shown to the GUI. | |
def scheduled_update(): # schedule a thread to trigger every minute. | |
global shared_prices # import the global shared prices so we can apply changes. | |
crypto_ids = ["bitcoin", "ethereum", "binancecoin", "ripple", "litecoin", "dash"] | |
shared_prices = get_crypto_prices(crypto_ids) # Apply the new prices | |
now = datetime.datetime.now() | |
seconds_to_next_minute = 60 - now.second # get correct timing, it triggers in 1 minute. | |
threading.Timer(seconds_to_next_minute, scheduled_update).start() # Schedule the next update | |
# Gradio Interface | |
def update_all(): # runs the GUI clock. | |
global shared_prices | |
crypto_ids = ["bitcoin", "ethereum", "binancecoin", "ripple", "litecoin", "dash"] # we want it as one function. | |
price_strings = [] | |
for crypto_id in crypto_ids: | |
if crypto_id not in shared_prices: # when it loads the price might not be there, show some error message instead, make it more user friendy. | |
price_strings.append("Loading, Please wait.") # give a warning state that something is going on. | |
continue | |
price = shared_prices[crypto_id] # it might come as error | |
if isinstance(price, str): # means an error string. | |
price_strings.append(f"Current {crypto_id.upper()} Price: {price}") | |
else: | |
price_strings.append(f"Current {crypto_id.upper()} Price: ${price:.2f}") # apply it to the UI. | |
return get_current_time(), get_countdown(), *price_strings | |
with gr.Blocks() as demo: | |
clock_output = gr.Textbox(label="Current Time") # put it before the row. | |
countdown_output = gr.Textbox(label="Next Update") | |
with gr.Row(): # prices are in these objects now. | |
with gr.Column(): | |
output_btc = gr.Textbox(label="BTC Price") | |
output_eth = gr.Textbox(label="ETH Price") | |
output_bnb = gr.Textbox(label="BNB Price") | |
with gr.Column(): | |
output_xrp = gr.Textbox(label="XRP Price") | |
output_ltc = gr.Textbox(label="LTC Price") | |
output_dash = gr.Textbox(label="DASH Price") | |
demo.load(update_all, None, [clock_output, countdown_output, output_btc, output_eth, output_bnb, output_xrp, output_ltc, output_dash], every=1) # Update clock every second, the timer runs every second. Might be bad, as it updates more frequent. | |
# Start the scheduled updates and fetch the initial data | |
now = datetime.datetime.now() # so it can run for a bit before setting. | |
seconds_to_next_minute = 60 - now.second | |
time.sleep(seconds_to_next_minute) # wait for start, you may want to do this to display what you want in the GUI so you can debug. | |
scheduled_update() # start it, get new results | |
if __name__ == "__main__": | |
demo.launch() |