diff --git a/days/021-024-quart-async/your_turn/day_4/cityscape_api/app.py b/days/021-024-quart-async/your_turn/day_4/cityscape_api/app.py index 4f88e501..4cec6844 100644 --- a/days/021-024-quart-async/your_turn/day_4/cityscape_api/app.py +++ b/days/021-024-quart-async/your_turn/day_4/cityscape_api/app.py @@ -5,8 +5,9 @@ import services.weather_service import services.sun_service import services.location_service +import quart -app = flask.Flask(__name__) +app = quart.Quart(__name__) is_debug = False app.register_blueprint(home.blueprint) diff --git a/days/021-024-quart-async/your_turn/day_4/cityscape_api/requirements.txt b/days/021-024-quart-async/your_turn/day_4/cityscape_api/requirements.txt index ae76cab5..0f903f25 100644 --- a/days/021-024-quart-async/your_turn/day_4/cityscape_api/requirements.txt +++ b/days/021-024-quart-async/your_turn/day_4/cityscape_api/requirements.txt @@ -1,5 +1,6 @@ # Web framework requirements flask +quart # Calling services requirements requests diff --git a/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/location_service.py b/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/location_service.py index 6a6bc918..d620aa8c 100644 --- a/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/location_service.py +++ b/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/location_service.py @@ -1,7 +1,9 @@ +import asyncio import random import time from typing import Tuple -import requests +# import requests +import aiohttp use_cached_data = True @@ -10,7 +12,7 @@ 0.535646, 0.527148, 0.533472, 0.53351, 0.523462] -def get_lat_long(zip_code: str, country: str) -> Tuple[float, float]: +async def get_lat_long(zip_code: str, country: str) -> Tuple[float, float]: key = f'{zip_code}, {country}' # Sadly, datasciencetoolkit.org seems to have gone out of existence. # I set the use cached data = true in the config to keep this section working @@ -18,15 +20,13 @@ def get_lat_long(zip_code: str, country: str) -> Tuple[float, float]: url = f'https://www.datasciencetoolkit.org/street2coordinates/{key.replace(" ", "+")}' if use_cached_data: - # TODO: Convert this to await asyncio.sleep() - - time.sleep(random.choice(measured_latency_in_sec)) + await asyncio.sleep(random.choice(measured_latency_in_sec)) return 45.50655, -122.733888 else: - resp = requests.get(url) - resp.raise_for_status() - - data = resp.json() + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + resp.raise_for_status() + data = resp.json() city_data = data.get(f'{zip_code}, {country}', dict()) return city_data.get('latitude', 0.00), city_data.get('longitude', 0.00) diff --git a/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/sun_service.py b/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/sun_service.py index 8cbeddd1..5a58d5ae 100644 --- a/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/sun_service.py +++ b/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/sun_service.py @@ -1,29 +1,34 @@ +import asyncio import datetime import random import time -import requests +# import requests +import aiohttp measured_latency_in_sec = [0.399203, 0.7046, 0.422959, 0.741911, 0.404674] use_cached_data = False -def for_today(latitude: float, longitude: float) -> dict: +async def for_today(latitude: float, longitude: float) -> dict: url = f'https://api.sunrise-sunset.org/json?lat={latitude}&lng={longitude}' if use_cached_data: # Set in config/dev.json or config/prod.json - # TODO: Convert this to await asyncio.sleep() - - time.sleep(random.choice(measured_latency_in_sec)) + await asyncio.sleep(random.choice(measured_latency_in_sec)) return {'sunrise': '06:04:09 AM', 'sunset': '08:28:48 PM', 'solar_noon': '01:16:28 PM', 'day_length': '14:24:39', 'civil_twilight_begin': '05:31:10 AM', 'civil_twilight_end': '09:01:47 PM', 'nautical_twilight_begin': '04:49:54 AM', 'nautical_twilight_end': '09:43:03 PM', 'astronomical_twilight_begin': '04:03:13 AM', 'astronomical_twilight_end': '10:29:44 PM'} else: - resp = requests.get(url) - resp.raise_for_status() + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + resp.raise_for_status() + data = await resp.json() + + # resp = requests.get(url) + # resp.raise_for_status() - sun_data = resp.json().get('results', {}) + sun_data = data.get('results', {}) for k, v in list(sun_data.items()): if 'AM' not in v and 'PM' not in v: continue diff --git a/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/weather_service.py b/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/weather_service.py index 63b37b2e..04ab704e 100644 --- a/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/weather_service.py +++ b/days/021-024-quart-async/your_turn/day_4/cityscape_api/services/weather_service.py @@ -1,6 +1,6 @@ import requests +import aiohttp -# TODO: Set your api.openweathermap.org API key here: __api_key = '' @@ -15,9 +15,12 @@ def global_init(api_key: str): print() -def get_current(zip_code: str, country_code: str) -> dict: +async def get_current(zip_code: str, country_code: str) -> dict: url = f'https://api.openweathermap.org/data/2.5/weather?zip={zip_code},{country_code}&appid={__api_key}' - resp = requests.get(url) - resp.raise_for_status() - - return resp.json() + # print(url) + # resp = requests.get(url) + # resp.raise_for_status() + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + resp.raise_for_status() + return await resp.json() diff --git a/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/city_api.py b/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/city_api.py index 076220e4..47fbc33b 100644 --- a/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/city_api.py +++ b/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/city_api.py @@ -1,34 +1,38 @@ -import flask +import asyncio + +import quart from services import weather_service, sun_service, location_service -blueprint = flask.blueprints.Blueprint(__name__.replace('.', '_'), __name__) +blueprint = quart.blueprints.Blueprint(__name__.replace('.', '_'), __name__) @blueprint.route('/api/events///', methods=['GET']) -def events(city: str, state: str, country: str): +async def events(city: str, state: str, country: str): player = { "name": "Jeff the player", "city": city, "state": state, "country": country, } + await asyncio.sleep(2) if not player: - flask.abort(404) - return flask.jsonify(player) + quart.abort(404) + return quart.jsonify(player) @blueprint.route('/api/weather//', methods=['GET']) -def weather(zip_code: str, country: str): - weather_data = weather_service.get_current(zip_code, country) +async def weather(zip_code: str, country: str): + weather_data = await weather_service.get_current(zip_code, country) if not weather_data: - flask.abort(404) - return flask.jsonify(weather_data) + quart.abort(404) + return quart.jsonify(weather_data) @blueprint.route('/api/sun//', methods=['GET']) -def sun(zip_code: str, country: str): - lat, long = location_service.get_lat_long(zip_code, country) - sun_data = sun_service.for_today(lat, long) +async def sun(zip_code: str, country: str): + lat, long = await location_service.get_lat_long(zip_code, country) + sun_data = await sun_service.for_today(lat, long) + await asyncio.sleep(2) if not sun_data: - flask.abort(404) - return flask.jsonify(sun_data) + quart.abort(404) + return quart.jsonify(sun_data) diff --git a/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/home.py b/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/home.py index 51352eb9..eb554472 100644 --- a/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/home.py +++ b/days/021-024-quart-async/your_turn/day_4/cityscape_api/views/home.py @@ -1,6 +1,7 @@ import flask +import quart -blueprint = flask.blueprints.Blueprint(__name__.replace('.', '_'), __name__) +blueprint = quart.blueprints.Blueprint(__name__.replace('.', '_'), __name__) @blueprint.route('/') @@ -10,4 +11,4 @@ def index(): @blueprint.errorhandler(404) def not_found(_): - return flask.Response("The page was not found.", status=404) + return quart.Response("The page was not found.", status=404)