Upload folder using huggingface_hub
Browse files- streamlit_app.py +24 -16
streamlit_app.py
CHANGED
|
@@ -38,25 +38,22 @@ def load_models_local():
|
|
| 38 |
st.error(f"Failed to load models locally: {e}")
|
| 39 |
return None
|
| 40 |
|
|
|
|
|
|
|
| 41 |
def send_discord_notification(symbol, price, change_percent, prediction_dir):
|
| 42 |
-
"""Sends a formatted message to Discord."""
|
| 43 |
-
if not WEBHOOK_URL:
|
| 44 |
-
# print("No Webhook URL found.")
|
| 45 |
-
return
|
| 46 |
|
| 47 |
emoji = "π" if change_percent > 0 else "π»"
|
| 48 |
pred_emoji = "π’" if "UP" in prediction_dir else "π΄"
|
| 49 |
|
| 50 |
-
message
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
except Exception as e:
|
| 59 |
-
print(f"Failed to send Discord notification: {e}")
|
| 60 |
|
| 61 |
@st.cache_data(ttl=3600) # CACHE FOR 1 HOUR
|
| 62 |
def fetch_live_data(symbol):
|
|
@@ -189,8 +186,19 @@ if models:
|
|
| 189 |
# Discord Notification Trigger (Only if not mock and strictly if specific conditions met)
|
| 190 |
# To avoid spamming on every refresh, we rely on the fact that this function is only called
|
| 191 |
# when cache invalidates (once per hour) or user manually clears it.
|
| 192 |
-
|
| 193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
|
| 195 |
# 4. Footer
|
| 196 |
st.markdown("---")
|
|
|
|
| 38 |
st.error(f"Failed to load models locally: {e}")
|
| 39 |
return None
|
| 40 |
|
| 41 |
+
from src.orchestration.notifications import notify_discord
|
| 42 |
+
|
| 43 |
def send_discord_notification(symbol, price, change_percent, prediction_dir):
|
| 44 |
+
"""Sends a formatted message to Discord using the centralized module."""
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
emoji = "π" if change_percent > 0 else "π»"
|
| 47 |
pred_emoji = "π’" if "UP" in prediction_dir else "π΄"
|
| 48 |
|
| 49 |
+
# Format the message string
|
| 50 |
+
message = (f"**Hourly Stock Update** π\n"
|
| 51 |
+
f"**{symbol}**: ${price:.2f} {emoji} ({change_percent:.2f}%)\n"
|
| 52 |
+
f"**AI Prediction:** {prediction_dir} {pred_emoji}")
|
| 53 |
+
|
| 54 |
+
# Use the robust notification function
|
| 55 |
+
# It handles checking WEBHOOK_URL and printing errors
|
| 56 |
+
notify_discord(message)
|
|
|
|
|
|
|
| 57 |
|
| 58 |
@st.cache_data(ttl=3600) # CACHE FOR 1 HOUR
|
| 59 |
def fetch_live_data(symbol):
|
|
|
|
| 186 |
# Discord Notification Trigger (Only if not mock and strictly if specific conditions met)
|
| 187 |
# To avoid spamming on every refresh, we rely on the fact that this function is only called
|
| 188 |
# when cache invalidates (once per hour) or user manually clears it.
|
| 189 |
+
# Discord Notification Trigger
|
| 190 |
+
# Changed logic: Always attempt to send if webhook is present, or allow manual trigger.
|
| 191 |
+
# Note: Automatic sending on every refresh might be spammy, so we'll add a manual button for testing.
|
| 192 |
+
|
| 193 |
+
col_notify, _ = st.columns([1, 4])
|
| 194 |
+
with col_notify:
|
| 195 |
+
if st.button("π Send Discord Notification"):
|
| 196 |
+
send_discord_notification(symbol, data['price'], data['change'], direction)
|
| 197 |
+
st.success("Notification sent! (Check Discord)")
|
| 198 |
+
|
| 199 |
+
# Auto-send (optional - leaving disabled for now to prevent spam loop on refresh, user can click button)
|
| 200 |
+
# if not data['is_mock']:
|
| 201 |
+
# send_discord_notification(symbol, data['price'], data['change'], direction)
|
| 202 |
|
| 203 |
# 4. Footer
|
| 204 |
st.markdown("---")
|