Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor sports.py to use NamedTuple, fix mypy errors #201

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 42 additions & 30 deletions pittapi/sports.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,39 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""

from __future__ import annotations

import requests

from typing import Any, NamedTuple

JSON = dict[str, Any]

FOOTBALL_URL = "http://site.api.espn.com/apis/site/v2/sports/football/college-football/teams/pitt"
MENS_BASKETBALL_URL = "http://site.api.espn.com/apis/site/v2/sports/basketball/mens-college-basketball/teams/pittsburgh"


class GameInfo(NamedTuple):
timestamp: str | None = None
opponent: dict[str, str] | None = None
home_away: str | None = None
location: dict[str, str] | None = None
status: str | None = None


def get_mens_basketball_record() -> str:
"""returns the current record of the men's basketball team"""
basketball_data = _get_mens_basketball_data()

try:
record_summary = basketball_data["team"]["record"]["items"][0]["summary"]

record_summary: str = basketball_data["team"]["record"]["items"][0]["summary"]
except KeyError:
record_summary = "There's no record right now."

return record_summary


def get_next_mens_basketball_game() -> dict:
def get_next_mens_basketball_game() -> GameInfo:
"""returns a dict containing details of the next scheduled men's basketball game."""
basketball_data = _get_mens_basketball_data()
next_game = None
Expand All @@ -55,30 +68,29 @@ def get_next_mens_basketball_game() -> dict:
else:
opponent = next_game["competitions"][0]["competitors"][1]
homeaway = next_game["competitions"][0]["competitors"][1]["homeAway"]
return {
"timestamp": next_game["date"],
"opponent": {
return GameInfo(
timestamp=next_game["date"],
opponent={
"id": opponent["team"]["id"],
"school": opponent["team"]["nickname"],
"name": opponent["team"]["displayName"],
},
"home_away": homeaway,
"location": {
home_away=homeaway,
location={
"full_name": next_game["competitions"][0]["venue"]["fullName"],
"address": next_game["competitions"][0]["venue"]["address"],
},
"status": status,
}
status=status,
)
except IndexError:
# IndexError occurs when a next game on the schedule is not present
return {"status": "NO_GAME_SCHEDULED"}
return GameInfo(status="NO_GAME_SCHEDULED")


def get_mens_basketball_standings() -> str:
"""returns a string describing the placement of the men's basketball team. eg: '14th in ACC'"""
basketball_data = _get_mens_basketball_data()

return_value = basketball_data["team"]["standingSummary"]
return_value: str = basketball_data["team"]["standingSummary"]
return return_value


Expand All @@ -87,15 +99,14 @@ def get_football_record() -> str:
football_data = _get_football_data()

try:
record_summary = football_data["team"]["record"]["items"][0]["summary"]

record_summary: str = football_data["team"]["record"]["items"][0]["summary"]
except KeyError:
record_summary = "There's no record right now."

return record_summary


def get_next_football_game() -> dict:
def get_next_football_game() -> GameInfo:
football_data = _get_football_data()
next_game = None
try:
Expand All @@ -113,36 +124,37 @@ def get_next_football_game() -> dict:
else:
opponent = next_game["competitions"][0]["competitors"][0]
homeaway = next_game["competitions"][0]["competitors"][1]["homeAway"]
return {
"timestamp": next_game["date"],
"opponent": {
return GameInfo(
timestamp=next_game["date"],
opponent={
"id": opponent["team"]["id"],
"school": opponent["team"]["nickname"],
"name": opponent["team"]["displayName"],
},
"home_away": homeaway,
"location": {
home_away=homeaway,
location={
"full_name": next_game["competitions"][0]["venue"]["fullName"],
"address": next_game["competitions"][0]["venue"]["address"],
},
"status": status,
}
status=status,
)
except IndexError:
# IndexError occurs when a next game on the schedule is not present
return {"status": "NO_GAME_SCHEDULED"}
return GameInfo(status="NO_GAME_SCHEDULED")


def get_football_standings() -> str:
"""returns a string describing the placement of the football team. eg: '14th in ACC'"""
football_data = _get_football_data()

return_value = football_data["team"]["standingSummary"]
return_value: str = football_data["team"]["standingSummary"]
return return_value


def _get_mens_basketball_data() -> dict:
return requests.get(MENS_BASKETBALL_URL).json()
def _get_mens_basketball_data() -> JSON:
json_data: JSON = requests.get(MENS_BASKETBALL_URL).json()
return json_data


def _get_football_data() -> dict:
return requests.get(FOOTBALL_URL).json()
def _get_football_data() -> JSON:
json_data: JSON = requests.get(FOOTBALL_URL).json()
return json_data
30 changes: 12 additions & 18 deletions tests/sports_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,36 +170,30 @@ def test_get_football_standings(self):

def test_get_next_mens_basketball_game(self):
next_game_details = sports.get_next_mens_basketball_game()
self.assertIn("timestamp", next_game_details)
self.assertIn("opponent", next_game_details)
self.assertIn("home_away", next_game_details)
self.assertIn("location", next_game_details)
self.assertIn("status", next_game_details)
self.assertNotEqual("NO_GAME_SCHEDULED", next_game_details["status"])
self.assertNotEqual("NO_GAME_SCHEDULED", next_game_details.status)

def test_get_next_football_game(self):
next_game_details = sports.get_next_football_game()
self.assertIn("timestamp", next_game_details)
self.assertIn("opponent", next_game_details)
self.assertIn("home_away", next_game_details)
self.assertIn("location", next_game_details)
self.assertIn("status", next_game_details)
self.assertNotEqual("NO_GAME_SCHEDULED", next_game_details["status"])
self.assertNotEqual("NO_GAME_SCHEDULED", next_game_details.status)

def test_get_next_mens_basketball_game_offseason(self):
offseason_data = {"team": {"nextEvent": []}}
sports._get_mens_basketball_data = MagicMock(return_value=offseason_data)

next_game_details = sports.get_next_mens_basketball_game()
self.assertEqual(1, len(next_game_details))
self.assertIn("status", next_game_details)
self.assertEqual("NO_GAME_SCHEDULED", next_game_details["status"])
self.assertIsNone(next_game_details.timestamp)
self.assertIsNone(next_game_details.opponent)
self.assertIsNone(next_game_details.home_away)
self.assertIsNone(next_game_details.location)
self.assertEqual("NO_GAME_SCHEDULED", next_game_details.status)

def test_get_next_football_game_offseason(self):
offseason_data = {"team": {"nextEvent": []}}
sports._get_football_data = MagicMock(return_value=offseason_data)

next_game_details = sports.get_next_football_game()
self.assertEqual(1, len(next_game_details))
self.assertIn("status", next_game_details)
self.assertEqual("NO_GAME_SCHEDULED", next_game_details["status"])
self.assertIsNone(next_game_details.timestamp)
self.assertIsNone(next_game_details.opponent)
self.assertIsNone(next_game_details.home_away)
self.assertIsNone(next_game_details.location)
self.assertEqual("NO_GAME_SCHEDULED", next_game_details.status)