diff --git a/app/main.py b/app/main.py index b9aff949..049b6588 100644 --- a/app/main.py +++ b/app/main.py @@ -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 @@ -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], ) # ##################### diff --git a/app/services/location/csbs.py b/app/services/location/csbs.py index 444ebad6..466125c0 100644 --- a/app/services/location/csbs.py +++ b/app/services/location/csbs.py @@ -12,6 +12,12 @@ from ...utils import httputils from . import LocationService +# ############ +# Creating Session Object +# ############ +clientSession = httputils.Session() + + LOGGER = logging.getLogger("services.location.csbs") @@ -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") @@ -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), diff --git a/app/services/location/jhu.py b/app/services/location/jhu.py index ebed3960..1de9a7a5 100644 --- a/app/services/location/jhu.py +++ b/app/services/location/jhu.py @@ -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() @@ -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") @@ -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"] @@ -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. @@ -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). diff --git a/app/services/location/nyt.py b/app/services/location/nyt.py index 1f25ec34..cd37c23e 100644 --- a/app/services/location/nyt.py +++ b/app/services/location/nyt.py @@ -13,6 +13,12 @@ from ...utils import httputils from . import LocationService +# ############ +# Creating Session Object +# ############ +clientSession = httputils.Session() + + LOGGER = logging.getLogger("services.location.nyt") @@ -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") @@ -104,10 +110,12 @@ 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( @@ -115,7 +123,8 @@ async def get_locations(): 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( diff --git a/app/utils/httputils.py b/app/utils/httputils.py index a0793170..7b412fdf 100644 --- a/app/utils/httputils.py +++ b/app/utils/httputils.py @@ -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() diff --git a/tests/test_httputils.py b/tests/test_httputils.py index 547f3725..bcc6b12e 100644 --- a/tests/test_httputils.py +++ b/tests/test_httputils.py @@ -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