Spaces:
Running
Running
fixed automatic retry if some sheets are failed to load
Browse files
app.py
CHANGED
|
@@ -328,7 +328,6 @@ def get_sheet_data(spreadsheet, gid, sheet_name):
|
|
| 328 |
df = pd.DataFrame(data_rows, columns=clean_headers)
|
| 329 |
# Remove completely empty columns
|
| 330 |
df = df.loc[:, (df != '').any(axis=0)]
|
| 331 |
-
print(f"✅ Loaded {len(df)} rows from {sheet_name}")
|
| 332 |
return df
|
| 333 |
else:
|
| 334 |
print(f"⚠️ No data rows found in {sheet_name}")
|
|
@@ -685,7 +684,7 @@ data_cache = {
|
|
| 685 |
}
|
| 686 |
|
| 687 |
def load_all_data():
|
| 688 |
-
"""Load and cache all data from Google Sheets (
|
| 689 |
global data_cache
|
| 690 |
|
| 691 |
if data_cache["is_loading"]:
|
|
@@ -694,20 +693,64 @@ def load_all_data():
|
|
| 694 |
data_cache["details_info"], data_cache["reward_points_df"])
|
| 695 |
|
| 696 |
data_cache["is_loading"] = True
|
| 697 |
-
print(f"🔄 Loading
|
| 698 |
start_time = time.time()
|
| 699 |
|
| 700 |
try:
|
| 701 |
-
# Load all sheet data from main spreadsheet
|
| 702 |
all_dataframes = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 703 |
for config in sheet_configs:
|
| 704 |
df = get_sheet_data(main_spreadsheet, config["gid"], config["name"])
|
| 705 |
-
if
|
|
|
|
|
|
|
|
|
|
| 706 |
df['Source_Sheet'] = config["name"]
|
| 707 |
all_dataframes.append(df)
|
| 708 |
-
print(f"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 709 |
|
| 710 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 711 |
if all_dataframes:
|
| 712 |
try:
|
| 713 |
combined_df = pd.concat(all_dataframes, ignore_index=True, sort=False)
|
|
@@ -746,40 +789,47 @@ def load_all_data():
|
|
| 746 |
print(f"✅ Alternative approach successful: {len(combined_df)} records combined")
|
| 747 |
else:
|
| 748 |
combined_df = pd.DataFrame()
|
| 749 |
-
print("
|
| 750 |
|
| 751 |
-
# Load
|
|
|
|
| 752 |
studentwise_data = get_studentwise_data(studentwise_spreadsheet)
|
| 753 |
-
|
| 754 |
-
# Load details info from main spreadsheet
|
| 755 |
details_info = get_details_info(main_spreadsheet)
|
| 756 |
-
|
| 757 |
-
# Load reward points activity data
|
| 758 |
reward_points_df = load_reward_points_data()
|
| 759 |
-
|
| 760 |
-
# Update cache
|
| 761 |
-
data_cache
|
| 762 |
-
|
| 763 |
-
|
| 764 |
-
|
| 765 |
-
|
| 766 |
-
|
|
|
|
|
|
|
| 767 |
load_time = time.time() - start_time
|
| 768 |
-
print(f"⏱️ Data loaded and cached in {load_time:.2f} seconds")
|
| 769 |
-
print(f"📊 Next auto-refresh in {data_cache['cache_duration_hours']} hours")
|
| 770 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 771 |
return combined_df, studentwise_data, details_info, reward_points_df
|
| 772 |
-
|
| 773 |
except Exception as e:
|
| 774 |
-
print(f"❌
|
| 775 |
-
return (
|
| 776 |
-
|
| 777 |
-
|
| 778 |
-
|
| 779 |
-
|
|
|
|
|
|
|
| 780 |
finally:
|
| 781 |
data_cache["is_loading"] = False
|
| 782 |
|
|
|
|
| 783 |
def get_cached_data():
|
| 784 |
"""Get data from cache or refresh if 12 hours have passed"""
|
| 785 |
now = datetime.now()
|
|
@@ -1275,6 +1325,12 @@ with gr.Blocks(
|
|
| 1275 |
gr.Markdown("## 🎓 Student Reward Points Checker")
|
| 1276 |
gr.Markdown("##### Search for Student Details such as Reward Points, Redemption Dates and Innovative Practice (IP) Details")
|
| 1277 |
gr.Markdown("##### எல்லா புகழும் இறைவனுக்கே ✝ 🕉 ☪")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1278 |
gr.Markdown("💻 **Mode**: Use Desktop Mode in browser for Good UI and UX")
|
| 1279 |
gr.Markdown("🕒 **Auto-Updates**: Data automatically refreshes when there is a change in Reward Points Sheet")
|
| 1280 |
gr.Markdown("📝 **Issue/Feedback Form** : [Issue/Feedback Form](https://docs.google.com/forms/d/e/1FAIpQLScnl0udcN2pUDENHl45HIj5HZbvDuwZ0g2eepBbp8tJYg-NvQ/viewform)")
|
|
|
|
| 328 |
df = pd.DataFrame(data_rows, columns=clean_headers)
|
| 329 |
# Remove completely empty columns
|
| 330 |
df = df.loc[:, (df != '').any(axis=0)]
|
|
|
|
| 331 |
return df
|
| 332 |
else:
|
| 333 |
print(f"⚠️ No data rows found in {sheet_name}")
|
|
|
|
| 684 |
}
|
| 685 |
|
| 686 |
def load_all_data():
|
| 687 |
+
"""Load and cache all data from Google Sheets (auto-retries failed sheets with backoff)"""
|
| 688 |
global data_cache
|
| 689 |
|
| 690 |
if data_cache["is_loading"]:
|
|
|
|
| 693 |
data_cache["details_info"], data_cache["reward_points_df"])
|
| 694 |
|
| 695 |
data_cache["is_loading"] = True
|
| 696 |
+
print(f"🔄 Loading data from {len(sheet_configs)} Google Sheets + Reward Points sheet...")
|
| 697 |
start_time = time.time()
|
| 698 |
|
| 699 |
try:
|
|
|
|
| 700 |
all_dataframes = []
|
| 701 |
+
failed_sheets = []
|
| 702 |
+
max_retries = 5 # Prevent infinite recursion
|
| 703 |
+
retry_delay = 2 # Start with 2 seconds
|
| 704 |
+
|
| 705 |
+
# 1️⃣ First attempt to load each sheet
|
| 706 |
+
print("📋 Initial loading attempt...")
|
| 707 |
for config in sheet_configs:
|
| 708 |
df = get_sheet_data(main_spreadsheet, config["gid"], config["name"])
|
| 709 |
+
if df.empty:
|
| 710 |
+
print(f"⚠️ {config['name']} failed to load, will retry...")
|
| 711 |
+
failed_sheets.append(config)
|
| 712 |
+
else:
|
| 713 |
df['Source_Sheet'] = config["name"]
|
| 714 |
all_dataframes.append(df)
|
| 715 |
+
print(f"✅ Loaded {len(df)} rows from {config['name']}")
|
| 716 |
+
|
| 717 |
+
# 2️⃣ Retry failed sheets with exponential backoff
|
| 718 |
+
for attempt in range(1, max_retries + 1):
|
| 719 |
+
if not failed_sheets:
|
| 720 |
+
break
|
| 721 |
+
|
| 722 |
+
print(f"🔄 Retry attempt {attempt}/{max_retries} for {len(failed_sheets)} failed sheets...")
|
| 723 |
+
time.sleep(retry_delay)
|
| 724 |
+
|
| 725 |
+
retry_failed = []
|
| 726 |
+
for config in failed_sheets:
|
| 727 |
+
print(f" 🔄 Retrying {config['name']}...")
|
| 728 |
+
df = get_sheet_data(main_spreadsheet, config["gid"], config["name"])
|
| 729 |
+
if df.empty:
|
| 730 |
+
print(f" ❌ Still failed: {config['name']}")
|
| 731 |
+
retry_failed.append(config)
|
| 732 |
+
else:
|
| 733 |
+
df['Source_Sheet'] = config["name"]
|
| 734 |
+
all_dataframes.append(df)
|
| 735 |
+
print(f" ✅ Retry success: {config['name']} ({len(df)} rows)")
|
| 736 |
+
|
| 737 |
+
failed_sheets = retry_failed
|
| 738 |
+
retry_delay *= 2 # Exponential backoff: 2s, 4s, 8s
|
| 739 |
|
| 740 |
+
# 3️⃣ Handle permanently failed sheets
|
| 741 |
+
if failed_sheets:
|
| 742 |
+
failed_names = [config['name'] for config in failed_sheets]
|
| 743 |
+
print(f"⚠️ Warning: {len(failed_sheets)} sheets failed after {max_retries} retries: {', '.join(failed_names)}")
|
| 744 |
+
|
| 745 |
+
# Continue with available data instead of aborting
|
| 746 |
+
if all_dataframes:
|
| 747 |
+
print(f"✅ Continuing with {len(all_dataframes)} successfully loaded sheets")
|
| 748 |
+
else:
|
| 749 |
+
print("❌ Critical: No sheets loaded successfully!")
|
| 750 |
+
# Return empty data but don't crash
|
| 751 |
+
return pd.DataFrame(), None, None, None
|
| 752 |
+
|
| 753 |
+
# 4️⃣ Combine successfully loaded sheets
|
| 754 |
if all_dataframes:
|
| 755 |
try:
|
| 756 |
combined_df = pd.concat(all_dataframes, ignore_index=True, sort=False)
|
|
|
|
| 789 |
print(f"✅ Alternative approach successful: {len(combined_df)} records combined")
|
| 790 |
else:
|
| 791 |
combined_df = pd.DataFrame()
|
| 792 |
+
print("⚠️ No sheets loaded successfully")
|
| 793 |
|
| 794 |
+
# 5️⃣ Load supporting data (with error handling)
|
| 795 |
+
print("📊 Loading supporting data...")
|
| 796 |
studentwise_data = get_studentwise_data(studentwise_spreadsheet)
|
|
|
|
|
|
|
| 797 |
details_info = get_details_info(main_spreadsheet)
|
|
|
|
|
|
|
| 798 |
reward_points_df = load_reward_points_data()
|
| 799 |
+
|
| 800 |
+
# 6️⃣ Update cache
|
| 801 |
+
data_cache.update({
|
| 802 |
+
"combined_df": combined_df,
|
| 803 |
+
"studentwise_data": studentwise_data,
|
| 804 |
+
"details_info": details_info,
|
| 805 |
+
"reward_points_df": reward_points_df,
|
| 806 |
+
"last_update": datetime.now(),
|
| 807 |
+
})
|
| 808 |
+
|
| 809 |
load_time = time.time() - start_time
|
|
|
|
|
|
|
| 810 |
|
| 811 |
+
if failed_sheets:
|
| 812 |
+
print(f"⚠️ Partial load completed in {load_time:.2f} seconds")
|
| 813 |
+
print(f"✅ {len(all_dataframes)}/{len(sheet_configs)} sheets loaded successfully")
|
| 814 |
+
else:
|
| 815 |
+
print(f"⏱️ All data successfully loaded in {load_time:.2f} seconds")
|
| 816 |
+
print("✅ Application ready — all sheets verified")
|
| 817 |
+
|
| 818 |
return combined_df, studentwise_data, details_info, reward_points_df
|
| 819 |
+
|
| 820 |
except Exception as e:
|
| 821 |
+
print(f"❌ Critical error in load_all_data: {str(e)}")
|
| 822 |
+
return (
|
| 823 |
+
data_cache.get("combined_df", pd.DataFrame()),
|
| 824 |
+
data_cache.get("studentwise_data", None),
|
| 825 |
+
data_cache.get("details_info", None),
|
| 826 |
+
data_cache.get("reward_points_df", None),
|
| 827 |
+
)
|
| 828 |
+
|
| 829 |
finally:
|
| 830 |
data_cache["is_loading"] = False
|
| 831 |
|
| 832 |
+
|
| 833 |
def get_cached_data():
|
| 834 |
"""Get data from cache or refresh if 12 hours have passed"""
|
| 835 |
now = datetime.now()
|
|
|
|
| 1325 |
gr.Markdown("## 🎓 Student Reward Points Checker")
|
| 1326 |
gr.Markdown("##### Search for Student Details such as Reward Points, Redemption Dates and Innovative Practice (IP) Details")
|
| 1327 |
gr.Markdown("##### எல்லா புகழும் இறைவனுக்கே ✝ 🕉 ☪")
|
| 1328 |
+
# gr.Markdown("""
|
| 1329 |
+
# ***Available Features*** :
|
| 1330 |
+
# **🔍 Student Search Tab**,
|
| 1331 |
+
# **📚 IP Details Tab**,
|
| 1332 |
+
# **ℹ️ System Info Tab**
|
| 1333 |
+
# """)
|
| 1334 |
gr.Markdown("💻 **Mode**: Use Desktop Mode in browser for Good UI and UX")
|
| 1335 |
gr.Markdown("🕒 **Auto-Updates**: Data automatically refreshes when there is a change in Reward Points Sheet")
|
| 1336 |
gr.Markdown("📝 **Issue/Feedback Form** : [Issue/Feedback Form](https://docs.google.com/forms/d/e/1FAIpQLScnl0udcN2pUDENHl45HIj5HZbvDuwZ0g2eepBbp8tJYg-NvQ/viewform)")
|