Repository navigation
Expand file tree
/
Copy pathesports_app.py
More file actions
437 lines (368 loc) · 20.5 KB
/
Copy pathesports_app.py
File metadata and controls
437 lines (368 loc) · 20.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
import streamlit as st
import requests
import google.generativeai as genai
import urllib3
import re
import json
import csv
import os
from bs4 import BeautifulSoup
# ----------------------------------------------------------------------------
# STREAMLIT CONFIG: Must be the first Streamlit command
# ----------------------------------------------------------------------------
st.set_page_config(page_title="EsportsBot AI", layout="centered")
# ----------------------------------------------------------------------------
# CONFIG & KEYS
# ----------------------------------------------------------------------------
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Replace these with your own keys
GEMINI_API_KEY = "AIzaSyAmTrwak5aM6WCTAqoPrL_XCM1VkzvS64E"
ESPORTS_API_KEY = "04ccf967a4efb358193fa74801d5151ae92526ed003f10ebc6b28e94d07a1284"
genai.configure(api_key=GEMINI_API_KEY)
BASE_URL = "https://api.esportsearnings.com/v0/"
# ----------------------------------------------------------------------------
# OPTIONAL: CSV-BASED GAME ID MAPPING
# ----------------------------------------------------------------------------
CSV_FILENAME = "esports_games.csv"
def load_game_ids(csv_file=CSV_FILENAME):
"""
Reads game IDs from a CSV file of format:
game_id,game_name
(or gameid,gamename)
Returns a dictionary mapping lowercased name -> game_id (string).
"""
game_map = {}
if not os.path.exists(csv_file):
return game_map
try:
with open(csv_file, "r", encoding="utf-8") as f:
# Attempt to figure out header
reader = csv.DictReader(f)
headers = [h.lower() for h in reader.fieldnames]
# Expect something like ["game_id", "game_name"] or ["gameid","gamename"]
col_id = None
col_name = None
for h in headers:
if "id" in h:
col_id = h
if "name" in h:
col_name = h
for row in reader:
raw_id = row[col_id].strip()
raw_name = row[col_name].strip().lower()
game_map[raw_name] = raw_id
return game_map
except Exception as e:
st.error(f"Failed to parse {csv_file}: {e}")
return {}
# Load the map once at startup
GAME_ID_MAP = load_game_ids()
# ----------------------------------------------------------------------------
# GEMINI LLM CALL
# ----------------------------------------------------------------------------
def gemini_flash(prompt: str) -> str:
"""
Uses Google Gemini 2.0 Flash to generate a content response.
"""
# Return the generated text (often found at `response.generations[0].text`)
model = genai.GenerativeModel("gemini-2.0-flash")
response = model.generate_content(prompt)
return response.text
# ----------------------------------------------------------------------------
# ESPORTS API CALL
# ----------------------------------------------------------------------------
def call_esports_api(endpoint: str, params: dict) -> dict:
"""
Calls Esports Earnings API with specified endpoint and parameters.
Expects JSON output (default).
"""
params["apikey"] = ESPORTS_API_KEY
try:
response = requests.get(f"{BASE_URL}{endpoint}", params=params, verify=False)
if not response.text.strip():
return {"error": "Empty response from the API. Possibly invalid parameters."}
return response.json()
except Exception as e:
return {"error": str(e)}
# ----------------------------------------------------------------------------
# IMAGE URL EXTRACTOR
# ----------------------------------------------------------------------------
def extract_image_urls(text: str):
"""
Finds any image URLs (jpg, png, gif) in 'text' and returns them as a list.
"""
return re.findall(r'(https?://\S+\.(?:jpg|jpeg|png|gif))', text)
# ----------------------------------------------------------------------------
# STREAMLIT UI
# ----------------------------------------------------------------------------
st.title("🎮 EsportsBot AI powered by Gemini 2.0 Flash")
user_query = st.text_input("Enter your query about esports earnings:")
if st.button("Get Information") and user_query:
# 2) Use Gemini to decide the endpoint + params
with st.spinner("🔍 Interpreting your request..."):
prompt_api_format = f"""
You are a smart API assistant for an Esports data app.
Given the user query: \"{user_query}\"
You must choose the most relevant API method from this list:
- LookupPlayerById (use only if a specific player ID or name is known)
- LookupPlayerTournaments
- LookupHighestEarningPlayers
- LookupHighestEarningPlayersByGame
- LookupHighestEarningTeams
- LookupHighestEarningTeamsByGame
- LookupGameById
- LookupRecentTournaments
- LookupTournamentById
- LookupTournamentResultsByTournamentId
- LookupTournamentTeamResultsByTournamentId
- LookupTournamentTeamPlayersByTournamentId
LookupPlayerById
LookupPlayerById returns earnings for a single player.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
playerid - The unique ID associated with the player on the website.
Output:
NameFirst - Player's first name.
NameLast - Player's last name.
CurrentHandle - Player's currently used in-game handle or ID.
CountryCode - Two-letter country code based on the ISO 3166-1 alpha-2 standard.
WorldRanking - Worldwide prize money ranking.
CountryRanking - Country-specific prize money ranking determined by the player's country code.
TotalUSDPrize - Total prize money won by the player in US Dollars.
TotalTournaments - Number of tournaments the player has recorded results in.
LookupPlayerTournaments
LookupPlayerTournaments returns a list of 100 tournament results for a single player, sorted by date.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
playerid - The unique ID associated with the player on the website.
offset - The number of tournaments to skip before returning results. (default: 0)
Output:
RankText - Text associated with the player's placement in the tournament.
Prize - Raw value of the prize money issued in its original currency.
ExchangeRate - Exchange Rate to US Dollars on the date the tournament ended. Used to calculate value of prize money in USD.
CurrencyCode - Three-letter currency code based on the ISO 4217 standard.
TournamentName - Short-hand name of the tournament. (or full name if it's short enough)
EndDate - Date the tournament ended.
GameId - Unique identification number associated with a game on the site.
Note - Additional notes describing the curcumstances of the tournament result.
TeamPlayers - Number of players on the team, if applicable. Used to divide the prize money in earning calculations.
LookupHighestEarningPlayers
LookupHighestEarningPlayers returns a list of 100 players with the highest overall prize money won.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
offset - The number of players to skip before returning results. (default: 0)
Output:
PlayerId - Unique identification number associated with a player on the site.
NameFirst - Player's first name.
NameLast - Player's last name.
CurrentHandle - Player's currently used in-game handle or ID.
CountryCode - Two-letter country code based on the ISO 3166-1 alpha-2 standard.
TotalUSDPrize - Total prize money won by the player in US Dollars.
LookupGameById
LookupGameById returns the prize money for a single game.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
gameid - The unique ID associated with the game on the website.
Output:
GameName - Name of the game.
TotalUSDPrize - Total prize money awarded for the game in US Dollars.
TotalTournaments - Number of recorded tournaments for the game.
TotalPlayers - Number of players with records in the game.
LookupHighestEarningPlayersByGame
LookupHighestEarningPlayersByGame returns a list of 100 players with the highest overall prize money won.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
gameid - The unique ID associated with the game on the website.
offset - The number of players to skip before returning results. (default: 0)
Output:
PlayerId - Unique identification number associated with a player on the site.
NameFirst - Player's first name.
NameLast - Player's last name.
CurrentHandle - Player's currently used in-game handle or ID.
CountryCode - Two-letter country code based on the ISO 3166-1 alpha-2 standard.
TotalUSDPrize - Total prize money won by the player in US Dollars.
LookupRecentTournaments
LookupRecentTournaments returns a list of the latest 100 tournaments that ended chronologically.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
offset - The number of players to skip before returning results. (default: 0)
Output:
TournamentId - Unique identification number associated with a tournament on the site.
GameId - Unique identification number associated with a game on the site.
TournamentName - TournamentName - Short-hand name of the tournament. (or full name if it's short enough)
StartDate - Date the tournament started.
EndDate - Date the tournament ended.
Location - Town or city that the event took place (or "online" if it was held online).
Teamplay - Boolean determining whether the tournament was held between individuals (1v1, FFA) or teams (2v2, 3v3, 4v4, 5v5, etc.).
TotalUSDPrize - Total prize money awarded in the tournament in US Dollars.
Notes:
If "Teamplay" is false, use "LookupTournamentResultsByTournamentId" to retrieve results.
If "Teamplay" is true, use "LookupTournamentTeamResultsByTournamentId" to retrieve results, and "LookupTournamentTeamPlayersByTournamentId" to retrieve players.
LookupTournamentById
LookupTournamentById returns the prize money and other information for a single tournament.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
tournamentid - The unique ID associated with the tournament on the website.
Output:
GameId - Unique identification number associated with a game on the site.
TournamentName - TournamentName - Short-hand name of the tournament. (or full name if it's short enough)
StartDate - Date the tournament started.
EndDate - Date the tournament ended.
Location - Town or city that the event took place (or "online" if it was held online).
Teamplay - Boolean determining whether the tournament was held between individuals (1v1, FFA) or teams (2v2, 5v5, etc.).
TotalUSDPrize - Total prize money awarded in the tournament in US Dollars.
Notes:
If "Teamplay" is false, use "LookupTournamentResultsByTournamentId" to retrieve results.
If "Teamplay" is true, use "LookupTournamentTeamResultsByTournamentId" to retrieve results, and "LookupTournamentTeamPlayersByTournamentId" to retrieve players for those results.
Individual-based tournaments and team-based tournaments have two completely different methods of accounting for unknown players. See the notes of those methods for more information.
LookupTournamentResultsByTournamentId
LookupTournamentResultsByTournamentId returns a list of tournament placements for tournaments held between individuals (1v1, FFA). Use this method if "Teamplay" is set to false.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
tournamentid - The unique ID associated with the tournament on the website.
Output:
Ranking - Number that determines ordering on the list. Ranks 1, 2 and 3 are also used to show a gold, silver and bronze background respectively.
RankText - Formatted text associated with the player's placement in the tournament.
TeamId - Unique identification number associated with a team on the site.
TeamName - Name of the player's associated team.
PlayerId - Unique identification number associated with a player on the site.
CountryCode - Two-letter country code based on the ISO 3166-1 alpha-2 standard.
NameFirst - Player's first name.
NameLast - Player's last name.
CurrentHandle - Player's currently used in-game handle or ID.
ShowLastNameFirst - Boolean determining whether or not the last name should be displayed before the first name.
PrizeUSD - Prize money awarded to the player in US Dollars.
Notes:
For v0 of the API, "TeamId" and "TeamName" may not work as intended. The site currently has an unreliable method of determining team associations from individual and team earnings. This will be rectified in v1.
If a placement is associated with an unknown player, the "CurrentHandle" will be "##UNKNOWN##". "PlayerId" in this instance is only used to return a unique row for each unknown player and can be discarded.
LookupTournamentTeamResultsByTournamentId
LookupTournamentTeamResultsByTournamentId returns a list of tournament placements for tournaments held between teams (2v2, 5v5, etc.). Use this method if "Teamplay" is set to true.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
tournamentid - The unique ID associated with the tournament on the website.
Output:
Ranking - Number that determines ordering on the list. Ranks 1, 2 and 3 are also used to show a gold, silver and bronze background respectively.
RankText - Formatted text associated with the player's placement in the tournament.
TeamId - Unique identification number associated with a team on the site.
TeamName - Name of the player's associated team.
TournamentTeamId - Unique identification number associated with a team earning on the site. Not to be confused with "TeamId".
TournamentTeamName - Name of the team associated with the team placement.
PrizeUSD - Prize money awarded to the team in US Dollars. Divide this value by the number of players + UnknownPlayerCount to get the prize per player.
UnknownPlayerCount - Number of unknown players on the team. Used if the full roster of the team is not known to correct division with PrizeUSD.
Notes:
For v0 of the API, "TeamId" and "TeamName" may not work as intended. The site currently has an unreliable method of determining team associations for individual and team earnings. This will be rectified in v1.
"TournamentTeamId" refers to a team earning for a single tournament, while "TeamId" refers to a team record on the site.
"TournamentTeamName" is the name of the team specifically for the associated tournament. It may include the title sponsor where appropriate (Fnatic.MSI for Fnatic), or may not be associated with a team at all, such as an all-stars match or two players pairing up for a 2v2 tournament.
The "LookupTournamentTeamResultsByTournamentId" method should be called along with "LookupTournamentTeamPlayersByTournamentId". Use "TournamentTeamId" to associate players with their respective team earning.
Formula for calculating prize money for each player: PrizeUSD / (Number of known players + UnknownPlayerCount)
Number of known players retrieved from the "LookupTournamentTeamPlayersByTournamentId" method may be zero for some tournaments, and "UnknownPlayerCount" is usually zero. Ensure that you are not dividing by zero!
LookupTournamentTeamPlayersByTournamentId
LookupTournamentTeamPlayersByTournamentId returns a list of players associated with the "tournament teams" of a tournament. Use this method if "Teamplay" is set to true.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
tournamentid - The unique ID associated with the tournament on the website.
Output:
TournamentTeamId - Unique identification number associated with a team earning on the site. Used to group players with their associated team earning.
PlayerId - Unique identification number associated with a player on the site.
CountryCode - Two-letter country code based on the ISO 3166-1 alpha-2 standard.
NameFirst - Player's first name.
NameLast - Player's last name.
CurrentHandle - Player's currently used in-game handle or ID.
ShowLastNameFirst - Boolean determining whether or not the last name should be displayed before the first name.
Notes:
The "LookupTournamentTeamPlayersByTournamentId" method should be called along with "LookupTournamentTeamResultsByTournamentId". Use "TournamentTeamId" to associate players with their respective team earning.
Some team-based tournaments will return team earnings, but not players for those team earnings. This is because information on player rosters for those tournaments have not been added yet.
LookupHighestEarningTeams
LookupHighestEarningTeams returns a list of 100 teams with the highest overall prize money won.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
offset - The number of teams to skip before returning results. (default: 0)
Output:
TeamId - Unique identification number associated with a team on the site.
TeamName - Name of the team.
TotalUSDPrize - Total prize won by the team in US Dollars.
TotalTournaments - Total number of tournaments that a team received prize money in.
LookupHighestEarningTeamsByGame
LookupHighestEarningTeamsByGame returns a list of 100 teams with the highest prize money won for a specific game.
Parameters:
apikey - The unique API Key associated with your account.
format - Format of the output. (default: JSON)
gameid - The unique ID associated with the game on the website.
offset - The number of teams to skip before returning results. (default: 0)
Output:
TeamId - Unique identification number associated with a team on the site.
TeamName - Name of the team.
TotalUSDPrize - Total prize won by the team for the game in US Dollars.
TotalTournaments - Total number of tournaments for the game that a team received prize money in.
If the query mentions a player name (e.g., 'TenZ'), prioritize LookupPlayerById or LookupPlayerTournaments and set 'playerid' to the player name.
If the query references a game name, set 'gameid' to that name (e.g., 'valorant').
For match history, prefer LookupPlayerTournaments to get the latest tournament.
If the user references a game name, set \"gameid\" to that name (e.g. \"valorant\"), and we will resolve it from the csv.
If the user references a player name use LookupPlayerById.
Return ONLY a valid JSON object in this format:
{{
\"endpoint\": \"<API_METHOD>\",
\"params\": {{
\"gameid\": \"valorant\",
\"offset\": 0,
\"tournamentid\": \"1234\"
}}
}}
"""
raw_output = gemini_flash(prompt_api_format)
match = re.search(r'\{[\s\S]+\}', raw_output)
if not match:
st.error("Gemini did not produce a valid JSON format. Try rephrasing your query.")
st.stop()
try:
api_request = json.loads(match.group())
endpoint = api_request["endpoint"]
params = api_request["params"]
# If user typed a textual game name, map it using the CSV-based dictionary
if "gameid" in params:
potential_game_name = str(params["gameid"]).strip().lower()
# If it's not numeric, try to map from CSV
if not potential_game_name.isdigit() and potential_game_name:
if potential_game_name in GAME_ID_MAP:
params["gameid"] = GAME_ID_MAP[potential_game_name]
else:
st.warning(f"Could not find game '{potential_game_name}' in CSV. We only have {len(GAME_ID_MAP)} games.")
st.stop()
except json.JSONDecodeError:
st.error("Failed to parse JSON from Gemini. Try again.")
st.stop()
# 3) Call the Esports Earnings API
with st.spinner(f"📡 Fetching data from Esports API ({endpoint})..."):
api_data = call_esports_api(endpoint, params)
if "error" in api_data:
st.error(f"API Error: {api_data['error']}")
st.stop()
# 4) Summarize with Gemini
with st.spinner("🧠 Summarizing..."):
summarization_prompt = f"""
User asked: \"{user_query}\"
Here is the data from the API:
{json.dumps(api_data, indent=2)}
Summarize this info for a general user. If there's no direct match for age or certain fields,
please clarify the limitation. If any image URLs appear, mention them.
"""
summary = gemini_flash(summarization_prompt)
st.success("✅ Here's your answer:")
st.write(summary)
# 5) Check for any image URLs
images = extract_image_urls(summary)
if images:
st.subheader("🖼️ Related Images:")
for url in images:
st.image(url, use_column_width=True)