Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,7 +4,7 @@ import pytz
|
|
4 |
import yaml
|
5 |
import os
|
6 |
from typing import Dict, Union
|
7 |
-
|
8 |
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
|
9 |
from tools.final_answer import FinalAnswerTool
|
10 |
from Gradio_UI import GradioUI
|
@@ -17,162 +17,103 @@ BASE_URL = "https://api.cricketdata.org/v1"
|
|
17 |
# Custom Tool: Analyze Cricketer Form
|
18 |
@tool
|
19 |
def analyze_cricketer_form(player_name: str, role: str) -> str:
|
20 |
-
"""
|
21 |
-
|
22 |
Args:
|
23 |
-
player_name: The name of the cricketer
|
24 |
-
role: The player
|
25 |
-
|
26 |
-
Returns:
|
27 |
-
A string summary of the player's career stats and recent form.
|
28 |
"""
|
29 |
-
|
30 |
-
|
31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
-
player_id = get_player_id(player_name)
|
34 |
-
if not player_id:
|
35 |
-
return f"Error: Player '{player_name}' not found."
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
40 |
|
41 |
-
recent_matches = get_recent_matches(player_id)
|
42 |
-
|
43 |
-
response = f"Analysis of {player_name} ({role.capitalize()}):\n\n"
|
44 |
-
response += "Career Stats:\n" + format_career_stats(career_stats, role) + "\n\n"
|
45 |
-
response += "Recent Form (Last 5 Matches):\n" + analyze_recent_form(recent_matches, role, player_name)
|
46 |
-
|
47 |
-
return response
|
48 |
|
49 |
-
def
|
50 |
-
|
51 |
-
|
52 |
-
response = requests.get(url)
|
53 |
-
response.raise_for_status()
|
54 |
-
data = response.json()
|
55 |
-
if data.get("data") and len(data["data"]) > 0:
|
56 |
-
return data["data"][0]["id"]
|
57 |
-
return None
|
58 |
-
except requests.RequestException as e:
|
59 |
-
print(f"Error fetching player ID: {e}")
|
60 |
-
return None
|
61 |
-
|
62 |
-
def get_career_stats(player_id: str) -> Union[Dict, None]:
|
63 |
-
url = f"{BASE_URL}/players/{player_id}/stats?apikey={API_KEY}"
|
64 |
-
try:
|
65 |
-
response = requests.get(url)
|
66 |
-
response.raise_for_status()
|
67 |
return response.json()
|
68 |
-
|
69 |
-
print(f"Error fetching career stats: {e}")
|
70 |
-
return None
|
71 |
|
72 |
-
|
73 |
-
|
|
|
74 |
try:
|
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 |
-
output += f"Matches: {bowling.get('matches', 'N/A')}\n"
|
100 |
-
output += f"Wickets: {bowling.get('wickets', 'N/A')}\n"
|
101 |
-
output += f"Economy: {bowling.get('economy', 'N/A')}\n"
|
102 |
-
output += f"Best: {bowling.get('best', {}).get('figures', 'N/A')}\n"
|
103 |
-
|
104 |
-
elif role == "wicket_keeper":
|
105 |
-
fielding = data.get("fielding", {})
|
106 |
-
output += f"Catches: {fielding.get('catches', 'N/A')}\n"
|
107 |
-
output += f"Stumpings: {fielding.get('stumpings', 'N/A')}\n"
|
108 |
-
|
109 |
-
elif role == "fielder":
|
110 |
-
fielding = data.get("fielding", {})
|
111 |
-
output += f"Catches: {fielding.get('catches', 'N/A')}\n"
|
112 |
-
output += f"Run Outs: {fielding.get('run_outs', 'N/A')}\n"
|
113 |
-
|
114 |
-
return output
|
115 |
|
116 |
-
def analyze_recent_form(matches: list, role: str, player_name: str) -> str:
|
117 |
-
if not matches:
|
118 |
-
return "No recent match data available."
|
119 |
-
|
120 |
-
output = ""
|
121 |
-
if role == "batter":
|
122 |
-
total_runs = 0
|
123 |
-
games = len(matches)
|
124 |
-
for match in matches:
|
125 |
-
batting = match.get("batting", {})
|
126 |
-
runs = batting.get("runs", 0)
|
127 |
-
total_runs += runs
|
128 |
-
output += f"Match vs {match.get('opponent', 'Unknown')}: {runs} runs\n"
|
129 |
-
avg = total_runs / games if games > 0 else 0
|
130 |
-
output += f"Recent Average: {avg:.2f}\n"
|
131 |
-
output += f"Form Comment: {'Strong' if avg > 30 else 'Inconsistent'} batting form."
|
132 |
-
|
133 |
-
elif role == "bowler":
|
134 |
-
total_wickets = 0
|
135 |
-
games = len(matches)
|
136 |
-
for match in matches:
|
137 |
-
bowling = match.get("bowling", {})
|
138 |
-
wickets = bowling.get("wickets", 0)
|
139 |
-
total_wickets += wickets
|
140 |
-
output += f"Match vs {match.get('opponent', 'Unknown')}: {wickets} wickets\n"
|
141 |
-
avg_wickets = total_wickets / games if games > 0 else 0
|
142 |
-
output += f"Recent Wickets per Game: {avg_wickets:.2f}\n"
|
143 |
-
output += f"Form Comment: {'Strong' if avg_wickets > 1 else 'Inconsistent'} bowling form."
|
144 |
-
|
145 |
-
elif role == "wicket_keeper":
|
146 |
-
total_stumpings = sum(m.get("fielding", {}).get("stumpings", 0) for m in matches)
|
147 |
-
total_catches = sum(m.get("fielding", {}).get("catches", 0) for m in matches)
|
148 |
-
output += f"Stumpings: {total_stumpings}, Catches: {total_catches}\n"
|
149 |
-
output += f"Form Comment: {'Reliable' if total_stumpings + total_catches > 3 else 'Average'} keeping."
|
150 |
-
|
151 |
-
elif role == "fielder":
|
152 |
-
total_catches = sum(m.get("fielding", {}).get("catches", 0) for m in matches)
|
153 |
-
total_run_outs = sum(m.get("fielding", {}).get("run_outs", 0) for m in matches)
|
154 |
-
output += f"Catches: {total_catches}, Run Outs: {total_run_outs}\n"
|
155 |
-
output += f"Form Comment: {'Sharp' if total_catches + total_run_outs > 3 else 'Average'} fielding."
|
156 |
-
|
157 |
-
return output
|
158 |
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
|
|
|
|
|
|
|
|
165 |
"""
|
166 |
-
try:
|
167 |
-
tz = pytz.timezone(timezone)
|
168 |
-
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
|
169 |
-
return f"The current local time in {timezone} is: {local_time}"
|
170 |
-
except Exception as e:
|
171 |
-
return f"Error fetching time for timezone '{timezone}': {str(e)}"
|
172 |
|
173 |
# Initialize tools
|
174 |
final_answer = FinalAnswerTool()
|
175 |
-
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
|
176 |
|
177 |
# Model setup
|
178 |
model = HfApiModel(
|
@@ -189,7 +130,7 @@ with open("prompts.yaml", 'r') as stream:
|
|
189 |
# Initialize the agent
|
190 |
agent = CodeAgent(
|
191 |
model=model,
|
192 |
-
tools=[final_answer, analyze_cricketer_form
|
193 |
max_steps=6,
|
194 |
verbosity_level=1,
|
195 |
grammar=None,
|
|
|
4 |
import yaml
|
5 |
import os
|
6 |
from typing import Dict, Union
|
7 |
+
from bs4 import BeautifulSoup
|
8 |
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
|
9 |
from tools.final_answer import FinalAnswerTool
|
10 |
from Gradio_UI import GradioUI
|
|
|
17 |
# Custom Tool: Analyze Cricketer Form
|
18 |
@tool
|
19 |
def analyze_cricketer_form(player_name: str, role: str) -> str:
|
20 |
+
"""Analyzes the recent form of a cricketer based on their role.
|
|
|
21 |
Args:
|
22 |
+
player_name: The name of the cricketer.
|
23 |
+
role: The role of the player (batter, bowler, wicketkeeper, fielder).
|
|
|
|
|
|
|
24 |
"""
|
25 |
+
try:
|
26 |
+
# Fetch player ID from API
|
27 |
+
player_id = get_player_id(player_name)
|
28 |
+
if not player_id:
|
29 |
+
return f"Player '{player_name}' not found."
|
30 |
+
|
31 |
+
# Fetch basic player details
|
32 |
+
player_details = get_player_details(player_id)
|
33 |
+
|
34 |
+
# Scrape detailed stats
|
35 |
+
detailed_stats = scrape_cricketer_stats(player_name, role)
|
36 |
+
|
37 |
+
# Generate form analysis
|
38 |
+
return format_analysis(player_name, role, player_details, detailed_stats)
|
39 |
+
|
40 |
+
except Exception as e:
|
41 |
+
return f"Error analyzing cricketer's form: {str(e)}"
|
42 |
|
|
|
|
|
|
|
43 |
|
44 |
+
def get_player_id(player_name: str):
|
45 |
+
response = requests.get(f"{BASE_URL}/players?name={player_name}", headers={"Authorization": f"Bearer {API_KEY}"})
|
46 |
+
if response.status_code == 200:
|
47 |
+
data = response.json()
|
48 |
+
return data.get("id")
|
49 |
+
return None
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
+
def get_player_details(player_id: str):
|
53 |
+
response = requests.get(f"{BASE_URL}/player/{player_id}", headers={"Authorization": f"Bearer {API_KEY}"})
|
54 |
+
if response.status_code == 200:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
return response.json()
|
56 |
+
return {}
|
|
|
|
|
57 |
|
58 |
+
|
59 |
+
def scrape_cricketer_stats(player_name: str, role: str):
|
60 |
+
"""Scrapes recent performance stats from an online cricket stats website."""
|
61 |
try:
|
62 |
+
search_url = f"https://stats.espncricinfo.com/ci/engine/player/{player_name.replace(' ', '_')}.html"
|
63 |
+
headers = {"User-Agent": "Mozilla/5.0"}
|
64 |
+
response = requests.get(search_url, headers=headers)
|
65 |
+
|
66 |
+
if response.status_code != 200:
|
67 |
+
return {"error": "Failed to fetch data from ESPN Cricinfo"}
|
68 |
+
|
69 |
+
soup = BeautifulSoup(response.text, "html.parser")
|
70 |
+
|
71 |
+
if role.lower() == "batter":
|
72 |
+
stats = {
|
73 |
+
"last_50_scores": extract_batting_scores(soup),
|
74 |
+
"batting_avg": extract_batting_average(soup),
|
75 |
+
"strike_rate": extract_strike_rate(soup),
|
76 |
+
}
|
77 |
+
elif role.lower() == "bowler":
|
78 |
+
stats = {
|
79 |
+
"last_50_wickets": extract_wickets(soup),
|
80 |
+
"bowling_economy": extract_bowling_economy(soup),
|
81 |
+
"bowling_speed": extract_bowling_speed(soup),
|
82 |
+
}
|
83 |
+
elif role.lower() == "wicketkeeper":
|
84 |
+
stats = {
|
85 |
+
"catches": extract_catches(soup),
|
86 |
+
"stumpings": extract_stumpings(soup),
|
87 |
+
"missed_stumpings": extract_missed_stumpings(soup),
|
88 |
+
}
|
89 |
+
elif role.lower() == "fielder":
|
90 |
+
stats = {
|
91 |
+
"catches": extract_fielder_catches(soup),
|
92 |
+
"direct_runouts": extract_direct_runouts(soup),
|
93 |
+
}
|
94 |
+
else:
|
95 |
+
stats = {"error": "Invalid role specified"}
|
96 |
+
|
97 |
+
return stats
|
98 |
|
99 |
+
except Exception as e:
|
100 |
+
return {"error": f"Error scraping data: {str(e)}"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
|
103 |
+
def format_analysis(player_name, role, player_details, detailed_stats):
|
104 |
+
return f"""
|
105 |
+
Cricketer: {player_name}
|
106 |
+
Role: {role}
|
107 |
+
Country: {player_details.get('country', 'Unknown')}
|
108 |
+
Batting Style: {player_details.get('battingStyle', 'Unknown')}
|
109 |
+
Bowling Style: {player_details.get('bowlingStyle', 'Unknown')}
|
110 |
+
|
111 |
+
Recent Performance:
|
112 |
+
{detailed_stats}
|
113 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
|
115 |
# Initialize tools
|
116 |
final_answer = FinalAnswerTool()
|
|
|
117 |
|
118 |
# Model setup
|
119 |
model = HfApiModel(
|
|
|
130 |
# Initialize the agent
|
131 |
agent = CodeAgent(
|
132 |
model=model,
|
133 |
+
tools=[final_answer, analyze_cricketer_form],
|
134 |
max_steps=6,
|
135 |
verbosity_level=1,
|
136 |
grammar=None,
|