Skip to content

Commit 7a0af20

Browse files
Liad NoamLiad Noam
Liad Noam
authored and
Liad Noam
committed
Fixed calendar grid test with game releases, added cached API call and changed requests to httpx
1 parent 9d4239f commit 7a0af20

File tree

5 files changed

+106
-29
lines changed

5 files changed

+106
-29
lines changed

app/config.py.example

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ WEBSITE_LANGUAGE = "en"
4040
# Get a free API KEY for Astronomy feature @ www.weatherapi.com/signup.aspx
4141
ASTRONOMY_API_KEY = os.getenv('ASTRONOMY_API_KEY')
4242
WEATHER_API_KEY = os.getenv('WEATHER_API_KEY')
43+
RAWG_API_KEY = os.getenv("RAWG_API_KEY")
4344

4445
# https://developers.google.com/calendar/quickstart/python -
4546
# follow instracions and make an env variable with the path to the file.

app/internal/game_releases_utils.py

+62-21
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
from collections import defaultdict
44
from datetime import datetime
5-
from typing import TYPE_CHECKING, DefaultDict, Dict, List
5+
from functools import lru_cache
6+
from typing import TYPE_CHECKING, Any, DefaultDict, Dict, List
67

7-
import requests
8+
import httpx
9+
from loguru import logger
810
from sqlalchemy.orm import Session
911

12+
from app import config
1013
from app.database.models import UserSettings
1114

1215
if TYPE_CHECKING:
@@ -17,16 +20,14 @@ def is_user_signed_up_for_game_releases(
1720
session: Session,
1821
current_user_id: int,
1922
) -> bool:
20-
is_signed_up = (
23+
is_signed_up = bool(
2124
session.query(UserSettings)
2225
.filter(UserSettings.user_id == current_user_id)
2326
.filter(UserSettings.video_game_releases.is_(True))
24-
.first()
27+
.first(),
2528
)
2629

27-
if is_signed_up:
28-
return True
29-
return False
30+
return is_signed_up
3031

3132

3233
def add_game_events_to_weeks(
@@ -41,11 +42,20 @@ def add_game_events_to_weeks(
4142
last_day: Day = last_week.days[-1]
4243
first_day_str = datetime.strptime(first_day.set_id(), "%d-%B-%Y")
4344
last_day_str = datetime.strptime(last_day.set_id(), "%d-%B-%Y")
44-
games_by_dates = get_games_data_separated_by_days(
45+
46+
output = get_games_data_by_dates_from_api(
4547
start_date=first_day_str.strftime("%Y-%m-%d"),
4648
end_date=last_day_str.strftime("%Y-%m-%d"),
4749
)
48-
formatted_games = get_formatted_games_in_days(games_by_dates)
50+
if not output["success"]:
51+
logger.exception("Unsuccessful RAWG API call")
52+
return weeks
53+
games_by_dates = output["results"]
54+
55+
unformatted_games_by_dates = get_games_data_separated_by_dates(
56+
games_by_dates,
57+
)
58+
formatted_games = get_formatted_games_in_days(unformatted_games_by_dates)
4959

5060
return insert_formatted_games_to_weeks(weeks, formatted_games)
5161

@@ -67,18 +77,47 @@ def insert_formatted_games_to_weeks(
6777
return weeks
6878

6979

70-
def get_games_data_separated_by_days(
71-
start_date: datetime,
72-
end_date: datetime,
73-
) -> DefaultDict[List[Dict]]:
80+
@lru_cache(maxsize=128)
81+
def get_games_data_by_dates_from_api(
82+
start_date: str,
83+
end_date: str,
84+
) -> Dict[str, Any]:
7485
API = "https://api.rawg.io/api/games"
75-
76-
current_day_games = requests.get(
77-
f"{API}?dates={start_date},{end_date}",
78-
)
79-
current_day_games = current_day_games.json()["results"]
86+
NO_API_RESPONSE = "The RAWG server did not response"
87+
input_query_string = {
88+
"dates": f"{start_date},{end_date}",
89+
"key": config.RAWG_API_KEY,
90+
}
91+
92+
output: Dict[str, Any] = {}
93+
try:
94+
response = httpx.get(
95+
API,
96+
params=input_query_string,
97+
)
98+
except httpx.HTTPError:
99+
output["success"] = False
100+
output["error"] = NO_API_RESPONSE
101+
return output
102+
103+
if response.status_code != httpx.codes.OK:
104+
output["success"] = False
105+
output["error"] = NO_API_RESPONSE
106+
return output
107+
108+
output["success"] = True
109+
try:
110+
output.update(response.json())
111+
return output
112+
except KeyError:
113+
output["success"] = False
114+
output["error"] = response.json()["error"]["message"]
115+
return output
116+
117+
118+
def get_games_data_separated_by_dates(api_data):
80119
games_data = defaultdict(list)
81-
for result in current_day_games:
120+
for result in api_data:
82121
current = {
83122
"name": result["name"],
84123
"platforms": [],
@@ -98,8 +137,9 @@ def get_formatted_games_in_days(
98137
formatted_games = defaultdict(list)
99138

100139
for date, game_data in separated_games_dict.items():
101-
formatted_game_str = format_single_game(game_data, with_platforms)
102-
formatted_games[date].append(formatted_game_str)
140+
for game in game_data:
141+
formatted_game_str = format_single_game(game, with_platforms)
142+
formatted_games[date].append(formatted_game_str)
103143
return formatted_games
104144

105145

@@ -110,6 +150,7 @@ def format_single_game(raw_game, with_platforms=False):
110150
formatted_game_str += "-Platforms-<br>"
111151
for platform in raw_game["platforms"]:
112152
formatted_game_str += f"{platform},"
153+
return formatted_game_str
113154

114155

115156
def translate_ymd_date_to_dby(ymd_str: str) -> str:

app/routers/calendar_grid.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def create_weeks(
194194
num_days: int = len(ndays)
195195
_weeks = [Week(ndays[i : i + length]) for i in range(0, num_days, length)]
196196

197-
return add_game_events_to_weeks(_weeks, is_active=False)
197+
return add_game_events_to_weeks(_weeks, is_active=True)
198198

199199

200200
def get_month_block(day: Day, n: int = MONTH_BLOCK) -> List[Week]:

tests/test_calendar_grid.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,19 @@ def test_create_weeks():
8080

8181
@staticmethod
8282
def test_get_month_block(Calendar):
83+
dates_iterator = Calendar.itermonthdates(1988, 5)
8384
month_weeks = cg.create_weeks(
84-
Calendar.itermonthdates(1988, 5),
85+
(cg.Day(date) for date in dates_iterator),
8586
WEEK_DAYS,
8687
)
8788
get_block = cg.get_month_block(cg.Day(DATE), n=len(month_weeks))
8889

8990
for i in range(len(month_weeks)):
9091
for j in range(cg.Week.WEEK_DAYS):
91-
assert get_block[i].days[j].date == month_weeks[i].days[j]
92+
assert (
93+
get_block[i].days[j].set_id()
94+
== month_weeks[i].days[j].set_id()
95+
)
9296

9397
@staticmethod
9498
def test_get_user_local_time():

tests/test_game_releases.py

+36-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
from collections import defaultdict
2+
13
from app.internal.game_releases_utils import (
2-
get_games_data_separated_by_days,
4+
get_formatted_games_in_days,
5+
get_games_data_by_dates_from_api,
6+
get_games_data_separated_by_dates,
37
translate_dby_date_to_ymd,
48
translate_ymd_date_to_dby,
59
)
@@ -68,7 +72,7 @@ def test_get_game_releases_month(client):
6872
game_release_router.url_path_for("get_game_releases_month"),
6973
)
7074
assert response.ok
71-
assert b"Prince" in response.content
75+
assert b"name" in response.content
7276

7377
@staticmethod
7478
def test_get_game_releases(client):
@@ -86,9 +90,24 @@ def test_get_game_releases(client):
8690
def test_get_games_data_separated_by_days():
8791
day_1 = "2020-12-10"
8892
day_2 = "2020-12-20"
89-
formatted = get_games_data_separated_by_days(day_1, day_2)
90-
assert isinstance(formatted, dict)
91-
assert "platforms" in formatted["10-December-2020"][0].keys()
93+
output = get_games_data_by_dates_from_api(
94+
start_date=day_1,
95+
end_date=day_2,
96+
)
97+
games_by_dates = output["results"]
98+
unformatted_games_by_dates = get_games_data_separated_by_dates(
99+
games_by_dates,
100+
)
101+
formatted_games = get_formatted_games_in_days(
102+
unformatted_games_by_dates,
103+
)
104+
105+
assert isinstance(unformatted_games_by_dates, defaultdict)
106+
assert isinstance(formatted_games, defaultdict)
107+
assert (
108+
"platforms"
109+
in unformatted_games_by_dates["10-December-2020"][0].keys()
110+
)
92111

93112
@staticmethod
94113
def test_ymd_to_dby():
@@ -99,3 +118,15 @@ def test_ymd_to_dby():
99118
def test_dby_to_ymd():
100119
dby_date = "12-December-2020"
101120
assert translate_dby_date_to_ymd(dby_date) == "2020-12-12"
121+
122+
@staticmethod
123+
def test_get_game_releases_async(client):
124+
day_1 = "2020-12-10"
125+
day_2 = "2020-12-20"
126+
dates = {"from-date": day_1, "to-date": day_2}
127+
response = client.post(
128+
game_release_router.url_path_for("fetch_released_games"),
129+
data=dates,
130+
)
131+
assert response.ok
132+
assert b"Xbox" in response.content

0 commit comments

Comments
 (0)