import json import os import gradio as gr import pandas as pd import plotly.express as px def get_data(*args, **kwargs): file_path = "predictions.json" table_columns = ["Repository", "Language", "Trend Probability"] if not os.path.exists(file_path): return ( pd.DataFrame(columns=table_columns), "📅 Status: Waiting for data sync...", None, ) try: with open(file_path, "r") as f: # Handle empty file case content = f.read() if not content: return ( pd.DataFrame(columns=table_columns), "📅 Status: predictions.json is empty.", None, ) raw_data = json.loads(content) predictions_list = raw_data.get("predictions", []) date = raw_data.get("prediction_date", "Unknown Date") # Handle case where 'predictions' key is missing or not a list if not isinstance(predictions_list, list): return ( pd.DataFrame(columns=table_columns), f"### ⚠️ Error: 'predictions' format is invalid.", None, ) df = pd.DataFrame(predictions_list) if not df.empty and all(col in df.columns for col in ['repo_name', 'language', 'probability']): # Sort for Chart (Ascending for horizontal Plotly layout) chart_df = df.sort_values(by="probability", ascending=True) fig = px.bar( chart_df, x="probability", y="repo_name", orientation="h", color="language", title="Trend Probability by Repository", labels={ "probability": "Probability", "repo_name": "Repository", "language": "Language", }, template="plotly_dark", ) fig.update_layout( paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)", font_color="#8b949e", margin=dict(l=20, r=20, t=40, b=20), ) # Prepare Table (Descending for the list view) table_df = df.sort_values(by="probability", ascending=False).copy() table_df["repo_name"] = table_df["repo_name"].apply( lambda x: f'🔗 {x}' ) table_df["probability"] = table_df["probability"].apply( lambda x: f"{x:.1%}" ) table_df = table_df[["repo_name", "language", "probability"]] table_df.columns = table_columns return table_df, f"### 📅 Last Prediction Run: {date}", fig else: return ( pd.DataFrame(columns=table_columns), f"### 📅 Last Prediction Run: {date} (No valid data)", None, ) except (json.JSONDecodeError, Exception) as e: return ( pd.DataFrame(columns=table_columns), f"### ⚠️ Error loading data: {e}", None, ) # CSS to center the markdown text since 'style' is no longer allowed in components custom_css = """ #date-container { text-align: center; margin-bottom: 20px; } .gradio-container { background-color: #0d1117 !important; } """ with gr.Blocks() as demo: gr.HTML( '

📈 GitHub Trend Predictor

' ) # Use a container to handle alignment via CSS with gr.Column(elem_id="date-container"): date_display = gr.Markdown(value="Syncing...") with gr.Tabs() as tabs: with gr.Tab("📋 Detailed Rankings"): table = gr.Dataframe(datatype=["html", "str", "str"], interactive=False) with gr.Tab("📊 Visual Forecast"): chart = gr.Plot() refresh_btn = gr.Button("🔄 Sync Latest Predictions", variant="primary") # Listeners demo.load(fn=get_data, outputs=[table, date_display, chart]) tabs.select(fn=get_data, outputs=[table, date_display, chart]) refresh_btn.click(fn=get_data, outputs=[table, date_display, chart]) if __name__ == "__main__": # Parameters moved to launch() for Gradio 6.0 compatibility demo.launch(theme=gr.themes.Soft(primary_hue="blue"), css=custom_css)