-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpipeline.py
More file actions
107 lines (87 loc) · 4.5 KB
/
Copy pathpipeline.py
File metadata and controls
107 lines (87 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import os
import requests
from datetime import datetime, timedelta, timezone
from typing import List, Dict, Optional
import time
class TheOddsAPIPipeline:
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key or os.getenv("ODDS_API_KEY", "")
self.base_url = "https://api.the-odds-api.com/v4/sports"
self.session = requests.Session()
def fetch_pipeline(self, sport_key: str, regions: str = "us,eu,uk", include_props: bool = False) -> List[Dict]:
if not self.api_key:
return []
print(f" [API] Fetching live odds for {sport_key} across '{regions}' bookmakers...")
endpoint = f"{self.base_url}/{sport_key}/odds"
markets = "h2h,spreads,totals"
time_to = (datetime.now(timezone.utc) + timedelta(days=3)).strftime("%Y-%m-%dT%H:%M:%SZ")
try:
params = {
"apiKey": self.api_key,
"regions": regions,
"markets": markets,
"oddsFormat": "decimal",
"commenceTimeTo": time_to
}
response = self.session.get(endpoint, params=params, timeout=15)
if response.status_code == 401:
print(" [API Error] Invalid API Key or Out of Credits.")
return []
elif response.status_code != 200:
print(f" [API Error] HTTP {response.status_code}: {response.text}")
return []
games = response.json()
print(f" [API] Found {len(games)} {sport_key} games scheduled within the next 72 hours.")
enriched = []
for game in games:
game_id = game.get("id", "Unknown")
start_time = datetime.fromisoformat(game["commence_time"].replace("Z", "+00:00"))
home = game.get("home_team", "Unknown")
away = game.get("away_team", "Unknown")
best_market_odds = {}
for bookmaker in game.get("bookmakers", []):
for market in bookmaker.get("markets", []):
m_key = market["key"]
for outcome in market.get("outcomes", []):
price = float(outcome.get("price", 0.0))
point = outcome.get("point", None)
name = outcome.get("name", "")
desc = outcome.get("description", None)
key_tuple = (m_key, desc, name)
if key_tuple not in best_market_odds or price > best_market_odds[key_tuple]["price"]:
best_market_odds[key_tuple] = {"price": price, "point": point}
parsed_markets = []
for (m_key, out_desc, out_name), data in best_market_odds.items():
parsed_markets.append({
"market_type": m_key,
"outcome_name": out_name,
"price": data["price"],
"player_name": out_desc,
"point_threshold": data["point"]
})
if not any(m["market_type"] == "h2h" for m in parsed_markets):
continue
enriched.append(
{
"sport": "basketball" if "basketball" in sport_key else "football",
"league": sport_key,
"home_team": home,
"away_team": away,
"fixture_date": start_time,
"market_odds": parsed_markets,
"api_predictions": {},
}
)
print(f" [Summary] {sport_key} fully parsed: {len(enriched)} bettable games extracted.")
return enriched
except requests.exceptions.RequestException as e:
print(f" [API Error] Failed to fetch odds: {e}")
return []
def fetch_soccer_argentina():
return TheOddsAPIPipeline().fetch_pipeline("soccer_argentina_primera_division", include_props=True)
def fetch_soccer_libertadores():
return TheOddsAPIPipeline().fetch_pipeline("soccer_conmebol_copa_libertadores", include_props=True)
def fetch_basketball_nba():
return TheOddsAPIPipeline().fetch_pipeline("basketball_nba", include_props=True)
def fetch_soccer_brazil():
return TheOddsAPIPipeline().fetch_pipeline("soccer_brazil_serie_a", include_props=True)