zjpiazza commited on
Commit
3f27d87
·
1 Parent(s): efbaacf

Added image service

Browse files
Files changed (3) hide show
  1. handler.py +55 -12
  2. image_service.py +25 -0
  3. requirements.txt +6 -1
handler.py CHANGED
@@ -2,6 +2,7 @@ import tensorflow as tf
2
  from typing import Dict, Any
3
  from predictor import FightPredictor
4
  from config import MODEL_PATH
 
5
  import os
6
 
7
  class CustomLSTM(tf.keras.layers.LSTM):
@@ -35,34 +36,76 @@ class EndpointHandler:
35
  Expected keys: "fighter1" and "fighter2".
36
 
37
  Returns:
38
- A dictionary with prediction results.
39
  """
40
  inputs = data.get("inputs")
41
- fighter1 = inputs.get("fighter1")
42
- fighter2 = inputs.get("fighter2")
43
 
44
  # Validate inputs
45
- if not fighter1 or not fighter2:
46
  return {"error": "Both 'fighter1' and 'fighter2' must be provided."}
47
 
48
  try:
49
  # Get prediction using FightPredictor
50
  f1_prob, f2_prob, details = self.predictor.get_prediction(
51
- fighter1,
52
- fighter2,
53
  verbose=True
54
  )
55
 
56
  if f1_prob is None:
57
  return {"error": "Prediction failed"}
58
 
 
 
 
 
59
  return {
60
- "fighter1": fighter1,
61
- "fighter2": fighter2,
62
- "fighter1_win_probability": f1_prob,
63
- "fighter2_win_probability": f2_prob,
64
- "details": details
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
66
 
67
  except Exception as e:
68
- return {"error": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  from typing import Dict, Any
3
  from predictor import FightPredictor
4
  from config import MODEL_PATH
5
+ from image_service import get_fighter_image_url
6
  import os
7
 
8
  class CustomLSTM(tf.keras.layers.LSTM):
 
36
  Expected keys: "fighter1" and "fighter2".
37
 
38
  Returns:
39
+ A dictionary with prediction results and fighter images.
40
  """
41
  inputs = data.get("inputs")
42
+ fighter1_name = inputs.get("fighter1")
43
+ fighter2_name = inputs.get("fighter2")
44
 
45
  # Validate inputs
46
+ if not fighter1_name or not fighter2_name:
47
  return {"error": "Both 'fighter1' and 'fighter2' must be provided."}
48
 
49
  try:
50
  # Get prediction using FightPredictor
51
  f1_prob, f2_prob, details = self.predictor.get_prediction(
52
+ fighter1_name,
53
+ fighter2_name,
54
  verbose=True
55
  )
56
 
57
  if f1_prob is None:
58
  return {"error": "Prediction failed"}
59
 
60
+ # Get fighter images
61
+ f1_image = get_fighter_image_url(fighter1_name)
62
+ f2_image = get_fighter_image_url(fighter2_name)
63
+
64
  return {
65
+ "fighter1": {
66
+ "name": fighter1_name,
67
+ "image_url": f1_image,
68
+ "probability": f1_prob,
69
+ "details": {
70
+ "form_score": float(details.get(f"{fighter1_name}_form_score", 0)),
71
+ "total_fights": int(details.get(f"{fighter1_name}_total_fights", 0))
72
+ }
73
+ },
74
+ "fighter2": {
75
+ "name": fighter2_name,
76
+ "image_url": f2_image,
77
+ "probability": f2_prob,
78
+ "details": {
79
+ "form_score": float(details.get(f"{fighter2_name}_form_score", 0)),
80
+ "total_fights": int(details.get(f"{fighter2_name}_total_fights", 0))
81
+ }
82
+ },
83
+ "details": {
84
+ "age_difference": float(details.get("age_difference", 0))
85
+ }
86
  }
87
 
88
  except Exception as e:
89
+ return {
90
+ "fighter1": {
91
+ "name": fighter1_name,
92
+ "image_url": "/default-fighter.png",
93
+ "probability": None,
94
+ "details": {
95
+ "form_score": 0,
96
+ "total_fights": 0
97
+ }
98
+ },
99
+ "fighter2": {
100
+ "name": fighter2_name,
101
+ "image_url": "/default-fighter.png",
102
+ "probability": None,
103
+ "details": {
104
+ "form_score": 0,
105
+ "total_fights": 0
106
+ }
107
+ },
108
+ "details": {
109
+ "age_difference": 0
110
+ }
111
+ }
image_service.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+ import logging
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ def get_fighter_image_url(fighter_name: str) -> str:
8
+ """Get the UFC profile image URL for a fighter"""
9
+ try:
10
+ url = f'https://www.ufc.com/athlete/{fighter_name.replace(" ", "-").lower()}'
11
+ response = requests.get(url)
12
+ response.raise_for_status()
13
+
14
+ soup = BeautifulSoup(response.content, 'html.parser')
15
+ img_tags = soup.find_all('img', class_='hero-profile__image')
16
+
17
+ if not img_tags:
18
+ # Return a default image URL if no fighter image is found
19
+ return "/default-fighter.png"
20
+
21
+ return img_tags[0]['src']
22
+
23
+ except requests.RequestException as e:
24
+ print(f"Error fetching image for {fighter_name}: {str(e)}")
25
+ raise Exception(f"Could not fetch image for {fighter_name}")
requirements.txt CHANGED
@@ -1,2 +1,7 @@
1
  tensorflow
2
- tf-keras
 
 
 
 
 
 
1
  tensorflow
2
+ tf-keras
3
+ beautifulsoup4
4
+ requests
5
+ numpy>=1.19.2
6
+ pandas>=1.2.0
7
+ scikit-learn>=0.24.0