Skip to content
Closed
11 changes: 8 additions & 3 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
from .config import get_settings
from .data import data_source
from .routers import V1, V2
from .utils.httputils import setup_client_session, teardown_client_session
from .utils.httputils import Session

# ############
# Creating Session Object
# ############
clientSession = Session()

# ############
# FastAPI App
Expand All @@ -37,8 +42,8 @@
version="2.0.4",
docs_url="/",
redoc_url="/docs",
on_startup=[setup_client_session],
on_shutdown=[teardown_client_session],
on_startup=[clientSession.setup_client_session],
on_shutdown=[clientSession.teardown_client_session],
)

# #####################
Expand Down
11 changes: 9 additions & 2 deletions app/services/location/csbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
from ...utils import httputils
from . import LocationService

# ############
# Creating Session Object
# ############
clientSession = httputils.Session()


LOGGER = logging.getLogger("services.location.csbs")


Expand Down Expand Up @@ -52,7 +58,7 @@ async def get_locations():
locations = cache_results
else:
LOGGER.info(f"{data_id} shared cache empty")
async with httputils.CLIENT_SESSION.get(BASE_URL) as response:
async with clientSession.getClientSession().get(BASE_URL) as response:
text = await response.text()

LOGGER.debug(f"{data_id} Data received")
Expand Down Expand Up @@ -84,7 +90,8 @@ async def get_locations():
# Coordinates.
Coordinates(item["Latitude"], item["Longitude"]),
# Last update (parse as ISO).
datetime.strptime(last_update, "%Y-%m-%d %H:%M").isoformat() + "Z",
datetime.strptime(
last_update, "%Y-%m-%d %H:%M").isoformat() + "Z",
# Statistics.
int(item["Confirmed"] or 0),
int(item["Death"] or 0),
Expand Down
19 changes: 14 additions & 5 deletions app/services/location/jhu.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
from ...utils import httputils
from . import LocationService

# ############
# Creating Session Object
# ############
clientSession = httputils.Session()


LOGGER = logging.getLogger("services.location.jhu")
PID = os.getpid()

Expand Down Expand Up @@ -68,7 +74,7 @@ async def get_category(category):

# Request the data
LOGGER.info(f"{data_id} Requesting data...")
async with httputils.CLIENT_SESSION.get(url) as response:
async with clientSession.getClientSession().get(url) as response:
text = await response.text()

LOGGER.debug(f"{data_id} Data received")
Expand All @@ -82,10 +88,12 @@ async def get_category(category):

for item in data:
# Filter out all the dates.
dates = dict(filter(lambda element: date_util.is_date(element[0]), item.items()))
dates = dict(
filter(lambda element: date_util.is_date(element[0]), item.items()))

# Make location history from dates.
history = {date: int(float(amount or 0)) for date, amount in dates.items()}
history = {date: int(float(amount or 0))
for date, amount in dates.items()}

# Country for this location.
country = item["Country/Region"]
Expand All @@ -101,7 +109,7 @@ async def get_category(category):
"country_code": countries.country_code(country),
"province": item["Province/State"],
# Coordinates.
"coordinates": {"lat": item["Lat"], "long": item["Long"],},
"coordinates": {"lat": item["Lat"], "long": item["Long"], },
# History.
"history": history,
# Latest statistic.
Expand Down Expand Up @@ -178,7 +186,8 @@ async def get_locations():
location["country"],
location["province"],
# Coordinates.
Coordinates(latitude=coordinates["lat"], longitude=coordinates["long"]),
Coordinates(
latitude=coordinates["lat"], longitude=coordinates["long"]),
# Last update.
datetime.utcnow().isoformat() + "Z",
# Timelines (parse dates as ISO).
Expand Down
17 changes: 13 additions & 4 deletions app/services/location/nyt.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
from ...utils import httputils
from . import LocationService

# ############
# Creating Session Object
# ############
clientSession = httputils.Session()


LOGGER = logging.getLogger("services.location.nyt")


Expand Down Expand Up @@ -85,7 +91,7 @@ async def get_locations():
locations = cache_results
else:
LOGGER.info(f"{data_id} shared cache empty")
async with httputils.CLIENT_SESSION.get(BASE_URL) as response:
async with clientSession.getClientSession().get(BASE_URL) as response:
text = await response.text()

LOGGER.debug(f"{data_id} Data received")
Expand All @@ -104,18 +110,21 @@ async def get_locations():
# Make location history for confirmed and deaths from dates.
# List is tuples of (date, amount) in order of increasing dates.
confirmed_list = histories["confirmed"]
confirmed_history = {date: int(amount or 0) for date, amount in confirmed_list}
confirmed_history = {date: int(amount or 0)
for date, amount in confirmed_list}

deaths_list = histories["deaths"]
deaths_history = {date: int(amount or 0) for date, amount in deaths_list}
deaths_history = {date: int(amount or 0)
for date, amount in deaths_list}

# Normalize the item and append to locations.
locations.append(
NYTLocation(
id=idx,
state=county_state[1],
county=county_state[0],
coordinates=Coordinates(None, None), # NYT does not provide coordinates
# NYT does not provide coordinates
coordinates=Coordinates(None, None),
last_updated=datetime.utcnow().isoformat() + "Z", # since last request
timelines={
"confirmed": Timeline(
Expand Down
44 changes: 25 additions & 19 deletions app/utils/httputils.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
"""app.utils.httputils.py"""
import logging

from aiohttp import ClientSession

# Singleton aiohttp.ClientSession instance.
CLIENT_SESSION: ClientSession


LOGGER = logging.getLogger(__name__)
class Session:
# Singleton aiohttp.ClientSession instance.
def __init__(self):
self.__CLIENT_SESSION: ClientSession
self.__LOGGER = logging.getLogger(__name__)

def getClientSession(self):
"""returns value in __CLIENT_SESSION"""
return self.__CLIENT_SESSION

async def setup_client_session():
"""Set up the application-global aiohttp.ClientSession instance.
def getLogger(self):
"""returns value in __LOGGER"""
return self.__LOGGER

aiohttp recommends that only one ClientSession exist for the lifetime of an application.
See: https://docs.aiohttp.org/en/stable/client_quickstart.html#make-a-request
async def setup_client_session(self):
"""Set up the application-global aiohttp.ClientSession instance.

"""
global CLIENT_SESSION # pylint: disable=global-statement
LOGGER.info("Setting up global aiohttp.ClientSession.")
CLIENT_SESSION = ClientSession()
aiohttp recommends that only one ClientSession exist for the lifetime of an application.
See: https://docs.aiohttp.org/en/stable/client_quickstart.html#make-a-request

"""
# global CLIENT_SESSION # pylint: disable=global-statement
self.getLogger().info("Setting up global aiohttp.ClientSession.")
self.__CLIENT_SESSION = ClientSession()

async def teardown_client_session():
"""Close the application-global aiohttp.ClientSession.
"""
global CLIENT_SESSION # pylint: disable=global-statement
LOGGER.info("Closing global aiohttp.ClientSession.")
await CLIENT_SESSION.close()
async def teardown_client_session(self):
"""Close the application-global aiohttp.ClientSession.
"""
# global CLIENT_SESSION # pylint: disable=global-statement
self.getLogger().info("Closing global aiohttp.ClientSession.")
await self.getClientSession().close()
12 changes: 6 additions & 6 deletions tests/test_httputils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
async def test_setup_teardown_client_session():
with pytest.raises(AttributeError):
# Ensure client_session is undefined prior to setup
httputils.CLIENT_SESSION
testSession = httputils.Session()

await httputils.setup_client_session()
await testSession.setup_client_session()

assert httputils.CLIENT_SESSION
assert testSession.getClientSession()

await httputils.teardown_client_session()
assert httputils.CLIENT_SESSION.closed
await testSession.teardown_client_session()
assert testSession.getClientSession().closed

del httputils.CLIENT_SESSION
del testSession