import gradio as gr import requests import os import pandas as pd # ---------------------------- # ENV VARIABLES # ---------------------------- API_URL = os.getenv("API_URL") ODDS_API_KEY = os.getenv("ODDS_API_KEY") # ---------------------------- # TEAM LIST # ---------------------------- teams = [ "Collingwood", "Carlton", "Richmond", "Melbourne", "Hawthorn", "Geelong", "Sydney", "Brisbane Lions", "Adelaide", "Port Adelaide", "West Coast", "Fremantle", "Essendon", "St Kilda", "Western Bulldogs", "North Melbourne", "Gold Coast", "GWS" ] # ---------------------------- # TEAM NAME MAPPING # ---------------------------- TEAM_MAPPING = { "Fremantle": "Fremantle Dockers", "West Coast": "West Coast Eagles", "Gold Coast": "Gold Coast Suns", "GWS": "Greater Western Sydney Giants" } def map_team(team): return TEAM_MAPPING.get(team, team) # ---------------------------- # FETCH ODDS # ---------------------------- def fetch_odds(): if not ODDS_API_KEY: return [] url = "https://api.the-odds-api.com/v4/sports/aussierules_afl/odds" params = { "apiKey": ODDS_API_KEY, "regions": "au", "markets": "h2h" } try: response = requests.get(url, params=params) if response.status_code != 200: return [] return response.json() except: return [] # ---------------------------- # GET MATCH ODDS # ---------------------------- def get_match_odds(home_team, away_team): data = fetch_odds() api_home = map_team(home_team) api_away = map_team(away_team) for match in data: if match["home_team"] == api_home and match["away_team"] == api_away: prices = {} for bookmaker in match["bookmakers"]: try: outcomes = bookmaker["markets"][0]["outcomes"] for o in outcomes: prices[o["name"]] = o["price"] except: continue return prices return None # ---------------------------- # FORMAT ODDS TABLE # ---------------------------- def format_odds(data): rows = [] for match in data: home = match["home_team"] away = match["away_team"] home_prices = [] away_prices = [] for bookmaker in match["bookmakers"]: try: outcomes = bookmaker["markets"][0]["outcomes"] for o in outcomes: if o["name"] == home: home_prices.append(o["price"]) elif o["name"] == away: away_prices.append(o["price"]) except: continue if home_prices and away_prices: rows.append({ "Match": f"{home} vs {away}", "Best Home Odds": max(home_prices), "Best Away Odds": max(away_prices), "Avg Home Odds": round(sum(home_prices)/len(home_prices), 2), "Avg Away Odds": round(sum(away_prices)/len(away_prices), 2) }) return pd.DataFrame(rows) # ---------------------------- # MAIN PREDICT FUNCTION # ---------------------------- def predict(home_team, away_team): if home_team == away_team: return "⚠️ Please select two different teams", "", 0 payload = { "home_team": home_team, "away_team": away_team } try: response = requests.post(API_URL, json=payload) if response.status_code != 200: return f"❌ API Error: {response.status_code}", "", 0 result = response.json() winner = result["winner"] confidence = result["confidence"] reasons = result.get("reasons", []) # ---------------------------- # GET ODDS # ---------------------------- odds_data = get_match_odds(home_team, away_team) odds_text = "" ev_text = "" if odds_data: api_home = map_team(home_team) api_away = map_team(away_team) home_odds = odds_data.get(api_home) away_odds = odds_data.get(api_away) if winner == home_team and home_odds: ev = (confidence * home_odds) - 1 selected_odds = home_odds elif winner == away_team and away_odds: ev = (confidence * away_odds) - 1 selected_odds = away_odds else: ev = None selected_odds = None odds_text = f""" ### 💰 Market Odds - {home_team}: {home_odds} - {away_team}: {away_odds} """ if ev is not None: recommendation = "🟢 Bet" if ev > 0 else "🔴 Avoid" ev_text = f""" ### 📈 Expected Value (EV) Odds used: {selected_odds} EV: **{ev:.2f}** **Recommendation:** {recommendation} """ else: odds_text = "⚠️ No odds data available" result_text = f""" # 🏆 Prediction Result ## **{winner} expected to win** **Confidence:** {confidence*100:.1f}% {odds_text} {ev_text} """ if reasons: reasons_text = "### 📊 Model Insights\n" for r in reasons: reasons_text += f"- {r}\n" else: reasons_text = "" return result_text, reasons_text, confidence except Exception as e: return f"❌ Error: {str(e)}", "", 0 # ---------------------------- # UI # ---------------------------- with gr.Blocks(theme=gr.themes.Soft()) as app: gr.Markdown(""" # 📊 Betting Intelligence Platform ### Find the edge. Bet with probability, not emotion. This tool combines machine learning predictions with real-time market odds to identify high-value betting opportunities. """) # Prediction Section with gr.Group(): gr.Markdown("### 🔍 Select Match") with gr.Row(): home_team = gr.Dropdown(teams, label="🏠 Home Team") away_team = gr.Dropdown(teams, label="✈️ Away Team") predict_btn = gr.Button("Run Prediction", variant="primary") with gr.Group(): result_output = gr.Markdown() confidence_bar = gr.Slider( minimum=0, maximum=1, step=0.01, label="Model Confidence", interactive=False ) with gr.Group(): reason_output = gr.Markdown() predict_btn.click( fn=predict, inputs=[home_team, away_team], outputs=[result_output, reason_output, confidence_bar] ) # Odds Table Section with gr.Group(): gr.Markdown("### 📊 Live Market Odds (All Matches)") odds_btn = gr.Button("Load Market Odds") odds_table = gr.Dataframe() odds_btn.click( fn=lambda: format_odds(fetch_odds()), outputs=odds_table ) app.launch()