Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ app/data/MLB/pitching/pitching_data_combined.csv filter=lfs diff=lfs merge=lfs -
app/data/MLB/batting/batting_data_combined.csv filter=lfs diff=lfs merge=lfs -text
*.pkl filter=lfs diff=lfs merge=lfs -text
*.joblib filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
3 changes: 2 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ jobs:
cd /home/paperspace/jsulima/GameAIAPI
git fetch origin
git reset --hard origin/main
/home/paperspace/jsulima/GameAIAPI/.venv/bin/pip install -r requirements.txt
git lfs pull
/home/paperspace/jsulima/GameAIAPI/.venv/bin/uv sync
sudo systemctl restart jsulima
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ ENV/
.venv/
.env
.python-version
# player_images/


# FastAPI specific
instance/
Expand Down
220 changes: 220 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# GameAI API

A FastAPI-based sports analytics and prediction API that provides machine learning-powered insights for MLB (Major League Baseball) and NFL (National Football League) games.

## Features

### MLB (Major League Baseball)
- **Game Predictions**: Predict outcomes of upcoming MLB games
- **Lineup Predictions**: Optimize team lineups for better performance
- **Head-to-Head Analysis**: Compare teams and predict matchup outcomes
- **Top Performer Analysis**: Identify best batters and pitchers
- **Win Percentage Calculations**: Calculate team win probabilities
- **Batter/Pitcher Performance**: Predict individual player statistics

### NFL (National Football League)
- **Win Predictions**: Predict NFL game outcomes
- **Lineup Optimization**: Suggest optimal player lineups
- **Top Performer Predictions**: Identify key players for upcoming games
- **Head-to-Head Comparisons**: Analyze team matchups
- **Win Percentage Analysis**: Calculate team win probabilities
- **Upcoming Games**: Get schedule information for upcoming NFL games

## Technology Stack

- **Framework**: FastAPI
- **Machine Learning**: scikit-learn, XGBoost
- **Data Processing**: pandas, numpy
- **HTTP Client**: httpx, requests
- **Scheduling**: APScheduler
- **Web Server**: uvicorn, gunicorn
- **Data Visualization**: matplotlib, seaborn
- **Environment Management**: python-dotenv

## Installation

### Prerequisites
- Python 3.8+
- pip package manager

### Setup Instructions

1. **Clone the repository**
```bash
git clone https://github.com/Roksana18cse04/GameAIAPI.git
cd GameAIAPI
```

2. **Create and activate virtual environment**
```bash
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
```

3. **Install dependencies**
```bash
pip install -r requirements.txt
```

4. **Install the package in development mode**
```bash
pip install -e .
```

5. **Set up environment variables**
Create a `.env` file in the root directory:
```env
GOALSERVE_API_KEY=your_goalserve_api_key_here
GOALSERVE_BASE_URL=https://www.goalserve.com/getfeed/
```

## Running the Application

### Development Mode
```bash
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```

### Production Mode
```bash
gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
```

The API will be available at:
- **API Base URL**: `http://localhost:8000`
- **Interactive API Documentation**: `http://localhost:8000/docs`
- **ReDoc Documentation**: `http://localhost:8000/redoc`

## API Endpoints

### MLB Endpoints
- `GET /` - Welcome message and API information
- `POST /predict/mlb/games` - Predict MLB game outcomes
- `POST /predict/mlb/lineup` - Get optimal MLB lineup predictions
- `POST /predict/mlb/head-to-head` - MLB head-to-head team analysis
- `POST /predict/mlb/top_batter_pitcher` - Get top batter and pitcher predictions
- `GET /predict/mlb/win-percentages` - Calculate MLB team win percentages

### NFL Endpoints
- `POST /predict/nfl/win-prediction` - Predict NFL game outcomes
- `POST /predict/nfl/lineup` - Get optimal NFL lineup predictions
- `POST /predict/nfl/top-performers` - Predict top NFL performers
- `POST /predict/nfl/head-to-head` - NFL head-to-head team analysis
- `GET /predict/nfl/win-percentages` - Calculate NFL team win percentages
- `GET /predict/nfl/upcoming-games` - Get upcoming NFL games

## Usage Examples

### Get MLB Win Percentages
```bash
curl -X GET "http://localhost:8000/predict/mlb/win-percentages"
```

### Predict NFL Game Outcome
```bash
curl -X POST "http://localhost:8000/predict/nfl/win-prediction" \
-H "Content-Type: application/json" \
-d '{
"home_team": "Kansas City Chiefs",
"away_team": "Buffalo Bills"
}'
```

### Get MLB Top Performers
```bash
curl -X POST "http://localhost:8000/predict/mlb/top_batter_pitcher" \
-H "Content-Type: application/json" \
-d '{
"hometeam": "New York Yankees",
"awayteam": "Boston Red Sox"
}'
```

## Project Structure

```
GameAIAPI/
├── app/
│ ├── api/
│ │ └── v1/
│ │ └── endpoints/ # API route handlers
│ ├── data/ # Data storage
│ │ ├── MLB/ # MLB datasets and notebooks
│ │ └── NFL/ # NFL datasets and notebooks
│ ├── services/ # Business logic and ML models
│ │ ├── MLB/ # MLB-specific services
│ │ └── NFL/ # NFL-specific services
│ ├── schemas/ # Pydantic data models
│ ├── tests/ # Unit tests
│ ├── utils/ # Utility functions
│ ├── config.py # Configuration settings
│ ├── main.py # FastAPI application entry point
│ └── scheduler.py # Background task scheduler
├── models/ # Trained ML models
├── requirements.txt # Python dependencies
├── setup.py # Package setup configuration
└── README.md # Project documentation
```

## Machine Learning Models

The API uses various machine learning algorithms for predictions:

- **XGBoost**: For win percentage calculations and game outcome predictions
- **Random Forest**: For player performance predictions
- **Linear Regression**: For statistical analysis and projections
- **Ensemble Methods**: Combining multiple models for improved accuracy

## Data Sources

- **GoalServe API**: Live scores, player stats, team information
- **Automated Data Collection**: Scheduled data fetching and model retraining
- **Historical Data**: Historical game data for model training

## Configuration

The application uses environment variables for configuration:

- `GOALSERVE_API_KEY`: API key for GoalServe sports data
- `GOALSERVE_BASE_URL`: Base URL for GoalServe API
- `PORT`: Server port (defaults to 8000)

## Testing

Run tests using:
```bash
python -m pytest app/tests/
```

## Development

### Adding New Features

1. Create new endpoint in `app/api/v1/endpoints/`
2. Add business logic in `app/services/`
3. Define data schemas in `app/schemas/`
4. Update routing in `app/main.py`

### Model Training

Models are automatically retrained on a schedule. Manual training can be triggered through the respective service modules in `app/services/`.

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

This project is developed by Softvence Omega.

## Support

For support and questions, please refer to the API documentation at `/docs` when running the application.

---

**Welcome to GameAI API!** 🏈⚾ Use the `/docs` endpoint to explore all available endpoints and start making predictions!
13 changes: 11 additions & 2 deletions app/api/v1/endpoints/mlb_batter_pitcher_top_performer.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from app.schemas.mlb_schemas import MLBTeams
import joblib
import os
from app.config import IMAGE_URL


router = APIRouter()
Expand Down Expand Up @@ -51,6 +52,7 @@ def pitcher_to_py(pitcher_dict):
return None
return {k: to_py(v) for k, v in pitcher_dict.items()}


@router.post("/top_batter_pitcher", response_model=Dict[str, Any])
async def get_top_batter_pitcher(request: MLBTeams):
# Top Batter Home
Expand All @@ -64,7 +66,8 @@ async def get_top_batter_pitcher(request: MLBTeams):
'runs': int(best_batsman_home['runs']),
'hits': int(best_batsman_home['hits']),
'performance_score': float(best_batsman_home['predicted_batting_average']),
'confidence_score': float(r2)
'confidence_score': float(r2),
'player_photo': f"{IMAGE_URL[:-1]}-mlb/{int(best_batsman_home['player_id'])}.png"
}
except ValueError as e:
raise HTTPException(status_code=404, detail=f"Batter: {str(e)}")
Expand All @@ -80,7 +83,8 @@ async def get_top_batter_pitcher(request: MLBTeams):
'runs': int(best_batsman_away['runs']),
'hits': int(best_batsman_away['hits']),
'performance_score': float(best_batsman_away['predicted_batting_average']),
'confidence_score': float(r2)
'confidence_score': float(r2),
'player_photo': f"{IMAGE_URL[:-1]}-mlb/{int(best_batsman_away['player_id'])}.png"
}
except ValueError as e:
raise HTTPException(status_code=404, detail=f"Batter: {str(e)}")
Expand All @@ -93,6 +97,11 @@ async def get_top_batter_pitcher(request: MLBTeams):
home_pitcher = pitcher_to_py(pitcher_result.get('home_team_pitcher'))
away_pitcher = pitcher_to_py(pitcher_result.get('away_team_pitcher'))

if home_pitcher:
home_pitcher['player_photo'] = f"{IMAGE_URL[:-1]}-mlb/{home_pitcher['id']}.png"
if away_pitcher:
away_pitcher['player_photo'] = f"{IMAGE_URL[:-1]}-mlb/{away_pitcher['id']}.png"

# Structure response
response = {
'home_team': {
Expand Down
48 changes: 26 additions & 22 deletions app/api/v1/endpoints/mlb_games_prediction_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,28 @@ def get_future_matches():

response = requests.get(url)
if response.status_code == 200:
data = response.json()
ret = []
for matches in data['fixtures']['category']['matches']:
for match in _force_list(matches['match']):
try:
data = response.json()
ret = []
for matches in data['fixtures']['category']['matches']:
for match in _force_list(matches['match']):

info = {
'date' : matches['@date'],
'timezone' : matches['@timezone'],
'seasonType' : matches['@seasonType'],
'venue': match['@venue_name'],
'formatted_date': match['@formatted_date'],
'datetime_utc': match['@datetime_utc'],
'hometeam' : match['hometeam']['@name'],
'awayteam' : match['awayteam']['@name']
}
info = {
'date' : matches['@date'],
'timezone' : matches['@timezone'],
'seasonType' : matches['@seasonType'],
'venue': match['@venue_name'],
'formatted_date': match['@formatted_date'],
'datetime_utc': match['@datetime_utc'],
'hometeam' : match['hometeam']['@name'],
'awayteam' : match['awayteam']['@name']
}

ret.append(info)

return ret
ret.append(info)

return ret
except json.JSONDecodeError:
raise Exception("Failed to parse JSON response")
else:
raise Exception(f"Failed to fetch matches: {response.status_code} - {response.text}")

Expand All @@ -71,9 +74,10 @@ def get_win_pred(n : int ):


@router.post("/head-to-head-win-prediction")
async def games_prediction_endpoint(n: int = 0):

res = get_win_pred(n)

return res
async def games_prediction_endpoint(n: int = 10):
try:
res = get_win_pred(n)
return res
except Exception as e:
raise Exception(f"Error fetching win predictions: {str(e)}")

33 changes: 31 additions & 2 deletions app/api/v1/endpoints/mlb_win_percentage_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,34 @@ def get_team_win_percentages():
model = joblib.load(MODEL_PATH)
# Load the data
data = pd.read_csv(GAMES_CSV_PATH)
data = data[(data['date'].str.endswith(str(current_year))) & (data['status'] == 'Final')]
#data = data[data['status'] == 'Final']


data['date'] = pd.to_datetime(data['date'], format='%d.%m.%Y')


today = datetime.now()
season_start = datetime(today.year, 3, 25) # Approximate late March
season_end = datetime(today.year, 10, 1) # Approximate early October



if season_start <= today <= season_end:
data = data[data['date'] >= season_start]

else:
if today.month <= 12:
# i) Filter from 1 Sept to current date
start = datetime(today.year, 10, 1)
end = today
df = data[(data['date'] >= start) & (data['date'] <= end)]

if today.month < 4:
# ii) Filter from previous year's Sept 1 to current date
start = datetime(today.year - 1, 10, 1)
end = today
df = data[(data['date'] >= start) & (data['date'] <= end)]


# Create home perspective rows
home_df = data[['home_team', 'away_team', 'home_score', 'away_score', 'home_hits', 'home_errors',
Expand Down Expand Up @@ -70,4 +97,6 @@ def get_team_win_percentages():
'loss_count': int(loss_count),
'average_score': float(team_games['team_score'].mean()) if total_matches > 0 else None
})
return results

results.sort(key=lambda x: x['win_count'], reverse=True)
return results
Loading