๐Ÿ€NBA Game Day Notifications/ Live Sports Alerts โ›น๐Ÿพโ€โ™‚๏ธ (30 Days Dev Ops Challenge)

Felton PierreFelton Pierre
4 min read

NBA Game Day Notifications ๐Ÿ€

A step-by-step guide for developers to set up and run an NBA Game Day Notifications system that fetches real-time NBA game data (i.e scores) and sends updates to subscribers through SMS or email. It utilizes Python, an external API and cloud-based, server less, architecture (AWS Lambda, EventBridge, and SNS).

Prerequisites

Before starting, ensure you have the following:

  1. Python 3.7+ installed on your system ๐Ÿ

  2. AWS account with appropriate credentials ๐Ÿชช

  3. NBA API key (from your chosen provider) ๐Ÿ”‘

  4. Required Python packages: ๐Ÿ“ฆ

    • boto3

    • requests

    • python-dotenv

    • pytest (for testing)

Project Setup

1. Environment Configuration

Create a .env file in your project root directory with the following variables:

NBA_API_KEY=your_nba_api_key_here
SNS_TOPIC_ARN=your_sns_topic_arn_here
AWS_ACCESS_KEY_ID=your_aws_access_key_here
AWS_SECRET_ACCESS_KEY=your_aws_secret_key_here
AWS_REGION=your_aws_region_here

2. AWS Configuration

Configure your AWS credentials using one of these methods:

a. Using AWS CLI:

aws configure

b. Or by creating ~/.aws/credentials:

[default]
aws_access_key_id = your_access_key
aws_secret_access_key = your_secret_key

3. Project Structure

nba-game-notifications/
โ”‚
โ”œโ”€โ”€ .env
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ lambda_function.py
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ test_lambda.py
โ”œโ”€โ”€ iam/
โ”‚   โ”œโ”€โ”€ sns_policy.json
โ”‚   โ””โ”€โ”€ lambda_role.json
โ””โ”€โ”€ README.md

4. Dependencies Installation

Create a requirements.txt file:

boto3>=1.26.0
requests>=2.28.1
python-dotenv>=0.21.0
pytest>=7.1.3

Install dependencies:

pip install -r requirements.txt

AWS Service Setup

1. Create an SNS Topic

# Using AWS CLI
aws sns create-topic --name nba_notifications

# Save the Topic ARN
export SNS_TOPIC_ARN=$(aws sns create-topic --name nba_notifications --output text)

2. Add SNS Subscription(s)

# Email subscription
aws sns subscribe \
    --topic-arn $SNS_TOPIC_ARN \
    --protocol email \
    --notification-endpoint your.email@example.com

# SMS subscription
aws sns subscribe \
    --topic-arn $SNS_TOPIC_ARN \
    --protocol sms \
    --notification-endpoint +1234567890

3. Create an IAM Role

Create iam/lambda_role.json:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sns:Publish",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:sns:REGION:ACCOUNT_ID:nba_notifications",
                "arn:aws:logs:*:*:*"
            ]
        }
    ]
}

Create the role:

aws iam create-role \
    --role-name nba_lambda_role \
    --assume-role-policy-document file://iam/lambda_role.json

System Implementation:

Deploy the Lambda Function (in Python)

Create lambda_function.py:

import json
import os
import requests
import boto3
from datetime import datetime

def get_nba_games():
    """Fetch NBA games from external API"""
    api_key = os.environ['NBA_API_KEY']
    headers = {'Authorization': f'Bearer {api_key}'}

    response = requests.get('https://api.nba.api/v1/games', headers=headers)
    return response.json()

def format_game_update(game):
    """Format game data for notification"""
    return (
        f"๐Ÿ€ {game['homeTeam']} vs {game['awayTeam']}\n"
        f"Score: {game['homeScore']} - {game['awayScore']}\n"
        f"Status: {game['status']}\n"
        f"Time: {game['gameTime']}"
    )

def lambda_handler(event, context):
    try:
        sns = boto3.client('sns')
        topic_arn = os.environ['SNS_TOPIC_ARN']

        games = get_nba_games()

        for game in games:
            message = format_game_update(game)
            sns.publish(
                TopicArn=topic_arn,
                Message=message,
                Subject='NBA Game Update'
            )

        return {
            'statusCode': 200,
            'body': json.dumps('Notifications sent successfully')
        }

    except Exception as e:
        print(f"Error: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps('Error processing games')
        }

The main system is built around the Lambda function with these key components:

get_nba_games(): Fetches game data from NBA API

format_game_update(): Formats game data for notifications

lambda_handler(): Main function that processes events and sends notifications

or

Deploy the Lambda Function (in AWS):

  1. Go to AWS Lambda

  2. Create function:

    • Author from scratch

    • Name: nba_score_notifications

    • Runtime: Python 3.x

    • Role: Use the role created above

  3. Add environment variables:

    • NBA_API_KEY: Your chosen API key

    • SNS_TOPIC_ARN: Your SNS topic ARN

  4. Copy the function code from this repository's lambda_function.py

Create EventBridge Rule

# Create rule
aws events put-rule \
    --name nba_score_updates \
    --schedule-expression "rate(1 hour)"

# Add Lambda target
aws events put-targets \
    --rule nba_score_updates \
    --targets "Id"="1","Arn"="$LAMBDA_ARN"

System Testing:

Unit Testing (in Python)

Create tests/test_lambda.py:

import unittest
from unittest.mock import patch, MagicMock
from lambda_function import lambda_handler

class TestNBANotifications(unittest.TestCase):
    @patch('boto3.client')
    @patch('requests.get')
    def test_lambda_handler(self, mock_requests, mock_boto3):
        mock_requests.return_value.json.return_value = [{
            'homeTeam': 'Lakers',
            'awayTeam': 'Warriors',
            'homeScore': 100,
            'awayScore': 98,
            'status': 'Final',
            'gameTime': '2024-01-19T20:00:00Z'
        }]

        mock_sns = MagicMock()
        mock_boto3.return_value = mock_sns

        response = lambda_handler({}, {})
        self.assertEqual(response['statusCode'], 200)

Run tests:

pytest tests/

or

Manual Testing (in Lambda Console)

  1. In Lambda console, click "Test"

  2. Create a test event (i.e test1, or empty {} is fine)

  3. Run test and check:

    • CloudWatch Logs for errors

    • Your subscribed email/phone for notifications

Troubleshooting:

Common issues and solutions

  1. No notifications received:

    • Check SNS subscription confirmation

    • Verify Lambda execution role permissions

    • Check CloudWatch Logs for errors

  2. Lambda timeout/execution:

    • Check timeout settings

    • Monitor memory usage

    • Review error logs

  3. API Issues

    • Verify NBA API key is valid

    • Check API rate limits

    • Ensure proper API endpoint URL

Contributing:

To contribute to this project:

  1. Fork the repository

  2. Create a feature branch

  3. Make your changes

  4. Submit a pull request

License:

This project is licensed under the MIT License - see the LICENSE file for details.

0
Subscribe to my newsletter

Read articles from Felton Pierre directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Felton Pierre
Felton Pierre