From f28c264f7bff127d881ceb12cfdd8803feee75fb Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 00:36:55 +0100 Subject: [PATCH 01/10] Core changes + /v2/ --- app/__init__.py | 3 +- app/{ => config}/settings.py | 0 app/coordinates.py | 20 +++++++ app/location.py | 49 ++++++++++++++++ app/models/location.py | 4 -- app/routes/__init__.py | 9 +-- app/routes/{ => v1}/all.py | 8 +-- app/routes/{ => v1}/confirmed.py | 4 +- app/routes/{ => v1}/deaths.py | 4 +- app/routes/{ => v1}/recovered.py | 4 +- app/routes/v2/latest.py | 18 ++++++ app/routes/v2/locations.py | 32 +++++++++++ app/services/__init__.py | 4 ++ app/services/location/__init__.py | 26 +++++++++ .../__init__.py => services/location/jhu.py} | 57 +++++++++++++++++-- app/timeline.py | 33 +++++++++++ 16 files changed, 249 insertions(+), 26 deletions(-) rename app/{ => config}/settings.py (100%) create mode 100644 app/coordinates.py create mode 100644 app/location.py delete mode 100644 app/models/location.py rename app/routes/{ => v1}/all.py (72%) rename app/routes/{ => v1}/confirmed.py (52%) rename app/routes/{ => v1}/deaths.py (52%) rename app/routes/{ => v1}/recovered.py (52%) create mode 100644 app/routes/v2/latest.py create mode 100644 app/routes/v2/locations.py create mode 100644 app/services/__init__.py create mode 100644 app/services/location/__init__.py rename app/{data/__init__.py => services/location/jhu.py} (50%) create mode 100644 app/timeline.py diff --git a/app/__init__.py b/app/__init__.py index dc2a691e..6414cb3e 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,6 +1,5 @@ from flask import Flask from flask_cors import CORS -from . import settings def create_app(): """ @@ -12,7 +11,7 @@ def create_app(): CORS(app) # Set app config from settings. - app.config.from_pyfile('settings.py'); + app.config.from_pyfile('config/settings.py'); with app.app_context(): # Import routes. diff --git a/app/settings.py b/app/config/settings.py similarity index 100% rename from app/settings.py rename to app/config/settings.py diff --git a/app/coordinates.py b/app/coordinates.py new file mode 100644 index 00000000..0243e637 --- /dev/null +++ b/app/coordinates.py @@ -0,0 +1,20 @@ +class Coordinates: + """ + A position on earth using decimal coordinates (latitude and longitude). + """ + + def __init__(self, latitude, longitude): + self.latitude = latitude + self.longitude = longitude + + def serialize(self): + """ + Serializes the coordinates into a dict. + """ + return { + 'latitude' : self.latitude, + 'longitude': self.longitude + } + + def __str__(self): + return 'lat: %s, long: %s' % (self.latitude, self.longitude) \ No newline at end of file diff --git a/app/location.py b/app/location.py new file mode 100644 index 00000000..e348c697 --- /dev/null +++ b/app/location.py @@ -0,0 +1,49 @@ +from .coordinates import Coordinates +from .utils import countrycodes + +class Location: + """ + A location in the world affected by the coronavirus. + """ + + def __init__(self, id, country, province, coordinates, confirmed, deaths, recovered): + # General info. + self.id = id + self.country = country.strip() + self.province = province.strip() + self.coordinates = coordinates + + # Data. + self.confirmed = confirmed + self.deaths = deaths + self.recovered = recovered + + + @property + def country_code(self): + """ + Gets the alpha-2 code represention of the country. Returns 'XX' if none is found. + """ + return (countrycodes.country_code(self.country) or countrycodes.default_code).upper() + + def serialize(self): + """ + Serializes the location into a dict. + """ + return { + # General info. + 'id' : self.id, + 'country' : self.country, + 'province' : self.province, + 'country_code': self.country_code, + + # Coordinates. + 'coordinates': self.coordinates.serialize(), + + # Latest data. + 'latest': { + 'confirmed': self.confirmed.latest, + 'deaths' : self.deaths.latest, + 'recovered': self.recovered.latest + } + } \ No newline at end of file diff --git a/app/models/location.py b/app/models/location.py deleted file mode 100644 index 5f202b3c..00000000 --- a/app/models/location.py +++ /dev/null @@ -1,4 +0,0 @@ -class Location(): - """ - A location in the world affected by the coronavirus. - """ \ No newline at end of file diff --git a/app/routes/__init__.py b/app/routes/__init__.py index 0e2e3c2c..b2bc5b73 100644 --- a/app/routes/__init__.py +++ b/app/routes/__init__.py @@ -1,4 +1,5 @@ -from . import confirmed -from . import deaths -from . import recovered -from . import all \ No newline at end of file +# API version 1. +from .v1 import confirmed, deaths, recovered, all + +# API version 2. +from .v2 import locations, latest \ No newline at end of file diff --git a/app/routes/all.py b/app/routes/v1/all.py similarity index 72% rename from app/routes/all.py rename to app/routes/v1/all.py index f80e289f..735b4d10 100644 --- a/app/routes/all.py +++ b/app/routes/v1/all.py @@ -1,13 +1,13 @@ from flask import jsonify from flask import current_app as app -from ..data import get_data +from ...services.location.jhu import get_category @app.route('/all') def all(): # Get all the categories. - confirmed = get_data('confirmed') - deaths = get_data('deaths') - recovered = get_data('recovered') + confirmed = get_category('confirmed') + deaths = get_category('deaths') + recovered = get_category('recovered') return jsonify({ # Data. diff --git a/app/routes/confirmed.py b/app/routes/v1/confirmed.py similarity index 52% rename from app/routes/confirmed.py rename to app/routes/v1/confirmed.py index dfa3346d..52fcf7e0 100644 --- a/app/routes/confirmed.py +++ b/app/routes/v1/confirmed.py @@ -1,7 +1,7 @@ from flask import jsonify from flask import current_app as app -from ..data import get_data +from ...services.location.jhu import get_category @app.route('/confirmed') def confirmed(): - return jsonify(get_data('confirmed')) \ No newline at end of file + return jsonify(get_category('confirmed')) \ No newline at end of file diff --git a/app/routes/deaths.py b/app/routes/v1/deaths.py similarity index 52% rename from app/routes/deaths.py rename to app/routes/v1/deaths.py index 61ef7546..76913b6d 100644 --- a/app/routes/deaths.py +++ b/app/routes/v1/deaths.py @@ -1,7 +1,7 @@ from flask import jsonify from flask import current_app as app -from ..data import get_data +from ...services.location.jhu import get_category @app.route('/deaths') def deaths(): - return jsonify(get_data('deaths')) \ No newline at end of file + return jsonify(get_category('deaths')) \ No newline at end of file diff --git a/app/routes/recovered.py b/app/routes/v1/recovered.py similarity index 52% rename from app/routes/recovered.py rename to app/routes/v1/recovered.py index 1abdef26..ded8eb7c 100644 --- a/app/routes/recovered.py +++ b/app/routes/v1/recovered.py @@ -1,7 +1,7 @@ from flask import jsonify from flask import current_app as app -from ..data import get_data +from ...services.location.jhu import get_category @app.route('/recovered') def recovered(): - return jsonify(get_data('recovered')) \ No newline at end of file + return jsonify(get_category('recovered')) \ No newline at end of file diff --git a/app/routes/v2/latest.py b/app/routes/v2/latest.py new file mode 100644 index 00000000..0f3ba265 --- /dev/null +++ b/app/routes/v2/latest.py @@ -0,0 +1,18 @@ +from flask import jsonify, current_app as app +from ...services import jhu + +@app.route('/v2/latest') +def latest(): + # Get the serialized version of all the locations. + locations = [ location.serialize() for location in jhu.get_all() ] + + # All the latest information. + latest = list(map(lambda location: location['latest'], locations)) + + return jsonify({ + 'latest': { + 'confirmed': sum(map(lambda latest: latest['confirmed'], latest)), + 'deaths' : sum(map(lambda latest: latest['deaths'], latest)), + 'recovered': sum(map(lambda latest: latest['recovered'], latest)), + } + }) \ No newline at end of file diff --git a/app/routes/v2/locations.py b/app/routes/v2/locations.py new file mode 100644 index 00000000..c4efb92f --- /dev/null +++ b/app/routes/v2/locations.py @@ -0,0 +1,32 @@ +from flask import jsonify, request, current_app as app +from ...services import jhu + +@app.route('/v2/locations') +def locations(): + # Query parameters. + country_code = request.args.get('country_code') + + # Serialize each location and return. + return jsonify({ + 'locations': [ + location.serialize() for location in jhu.get_all(country_code=country_code) + ] + }) + +@app.route('/v2/locations/') +def location(id): + # Retrieve location with the provided id. + location = jhu.get(id) + + # Fetch the timelines. + timelines = { + 'confirmed': location.confirmed.serialize(), + 'deaths' : location.deaths.serialize(), + 'recovered': location.recovered.serialize(), + } + + # Serialize the location, add timelines, and then return. + return jsonify({ + 'location': { + **jhu.get(id).serialize(), **{ 'history': timelines } } + }) \ No newline at end of file diff --git a/app/services/__init__.py b/app/services/__init__.py new file mode 100644 index 00000000..0c5b206c --- /dev/null +++ b/app/services/__init__.py @@ -0,0 +1,4 @@ +from .location.jhu import JhuLocationService + +# Instances of the services. +jhu = JhuLocationService() \ No newline at end of file diff --git a/app/services/location/__init__.py b/app/services/location/__init__.py new file mode 100644 index 00000000..2312283a --- /dev/null +++ b/app/services/location/__init__.py @@ -0,0 +1,26 @@ +from abc import ABC, abstractmethod + +class LocationService(ABC): + """ + Service for retrieving locations. + """ + + @abstractmethod + def get_all(self): + """ + Gets and returns all of the locations. + + :returns: The locations. + :rtype: Location + """ + raise NotImplementedError + + @abstractmethod + def get(self, id): + """ + Gets and returns location with the provided id. + + :returns: The location. + :rtype: Location + """ + raise NotImplementedError \ No newline at end of file diff --git a/app/data/__init__.py b/app/services/location/jhu.py similarity index 50% rename from app/data/__init__.py rename to app/services/location/jhu.py index c3d5ffa1..14365ba9 100644 --- a/app/data/__init__.py +++ b/app/services/location/jhu.py @@ -1,18 +1,63 @@ +from . import LocationService +from ...location import Location +from ...coordinates import Coordinates +from ...timeline import Timeline + +class JhuLocationService(LocationService): + """ + Service for retrieving locations from Johns Hopkins CSSE (https://github.com/CSSEGISandData/COVID-19). + """ + + def get_all(self, **kwargs): + # Get all of the data categories locations. + confirmed = get_category('confirmed')['locations'] + deaths = get_category('deaths')['locations'] + recovered = get_category('recovered')['locations'] + + # Final locations to return. + locations = [] + + # Go through confirmed locations. + for index, location in enumerate(confirmed): + # Grab coordinates. + coordinates = location['coordinates'] + + # Create location and append. + locations.append(Location( + # General info. + index, location['country'], location['province'], Coordinates(coordinates['lat'], coordinates['long']), + + # TODO: date key as ISO format. + # { datetime.strptime(date, '%m/%d/%y').isoformat() + 'Z': int(amount or 0) for date, amount in history.items() } + + # Timelines. + Timeline(confirmed[index]['history']), + Timeline(deaths[index]['history']), + Timeline(recovered[index]['history']) + )) + + # Finally, return the locations. + return locations + + def get(self, id): + # Get location at the index equal to provided id. + return self.get_all()[id] + import requests import csv from datetime import datetime from cachetools import cached, TTLCache -from ..utils import countrycodes, date as date_util +from ...utils import countrycodes, date as date_util """ -Base URL for fetching data. +Base URL for fetching category. """ base_url = 'https://raw.githubusercontent.com/CSSEGISandData/2019-nCoV/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-%s.csv'; @cached(cache=TTLCache(maxsize=1024, ttl=3600)) -def get_data(category): +def get_category(category): """ - Retrieves the data for the provided type. The data is cached for 1 hour. + Retrieves the data for the provided category. The data is cached for 1 hour. """ # Adhere to category naming standard. @@ -39,7 +84,7 @@ def get_data(category): country = item['Country/Region'] # Latest data insert value. - latest = list(history.values())[-1]; + latest = list(sorted(history.values()))[-1]; # Normalize the item and append to locations. locations.append({ @@ -70,4 +115,4 @@ def get_data(category): 'latest': latest, 'last_updated': datetime.utcnow().isoformat() + 'Z', 'source': 'https://github.com/ExpDev07/coronavirus-tracker-api', - } + } \ No newline at end of file diff --git a/app/timeline.py b/app/timeline.py new file mode 100644 index 00000000..48af1ac5 --- /dev/null +++ b/app/timeline.py @@ -0,0 +1,33 @@ +from datetime import datetime +from collections import OrderedDict + +class Timeline: + """ + Timeline with history of data. + """ + + def __init__(self, history = {}): + self.__timeline = history + + @property + def timeline(self): + """ + Gets the history sorted by date (key). + """ + return OrderedDict(sorted(self.__timeline.items())) + + @property + def latest(self): + """ + Gets the latest available history value. + """ + return list(self.timeline.values())[-1] or 0 + + def serialize(self): + """ + Serializes the data into a dict. + """ + return { + 'latest' : self.latest, + 'timeline': self.timeline + } \ No newline at end of file From bcf32c29336d1837854646ed084a8e0883e3df25 Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 00:46:20 +0100 Subject: [PATCH 02/10] Added filtering by /v2/locations?country_code=XX --- app/routes/v2/locations.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/routes/v2/locations.py b/app/routes/v2/locations.py index c4efb92f..8be1b26d 100644 --- a/app/routes/v2/locations.py +++ b/app/routes/v2/locations.py @@ -4,12 +4,19 @@ @app.route('/v2/locations') def locations(): # Query parameters. - country_code = request.args.get('country_code') + country_code = request.args.get('country_code', type=str) + + # Retrieve all the locations. + locations = jhu.get_all() + + # Filtering my country code if provided. + if not country_code is None: + locations = list(filter(lambda location: location.country_code == country_code.upper(), locations)) # Serialize each location and return. return jsonify({ 'locations': [ - location.serialize() for location in jhu.get_all(country_code=country_code) + location.serialize() for location in locations ] }) From d628268232e64843f4c7adde398e43c07dd42963 Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 00:47:42 +0100 Subject: [PATCH 03/10] removed **kwargs from JhuLocationService#get_all() --- app/services/location/jhu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/location/jhu.py b/app/services/location/jhu.py index 14365ba9..1c5a9d39 100644 --- a/app/services/location/jhu.py +++ b/app/services/location/jhu.py @@ -8,7 +8,7 @@ class JhuLocationService(LocationService): Service for retrieving locations from Johns Hopkins CSSE (https://github.com/CSSEGISandData/COVID-19). """ - def get_all(self, **kwargs): + def get_all(self): # Get all of the data categories locations. confirmed = get_category('confirmed')['locations'] deaths = get_category('deaths')['locations'] From 77254f0aa7828e5e9036f3c6ede9b84ea5d31082 Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 01:13:30 +0100 Subject: [PATCH 04/10] formatting error --- app/routes/v2/locations.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/routes/v2/locations.py b/app/routes/v2/locations.py index 8be1b26d..4c586ef8 100644 --- a/app/routes/v2/locations.py +++ b/app/routes/v2/locations.py @@ -35,5 +35,6 @@ def location(id): # Serialize the location, add timelines, and then return. return jsonify({ 'location': { - **jhu.get(id).serialize(), **{ 'history': timelines } } - }) \ No newline at end of file + **jhu.get(id).serialize(), **{ 'timelines': timelines } + } + }) \ No newline at end of file From 3b1ddd4b9d18ed4fcd6f3462142922f0ea80b3fd Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 01:15:45 +0100 Subject: [PATCH 05/10] comment --- app/routes/v2/locations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/routes/v2/locations.py b/app/routes/v2/locations.py index 4c586ef8..eb50e251 100644 --- a/app/routes/v2/locations.py +++ b/app/routes/v2/locations.py @@ -25,7 +25,7 @@ def location(id): # Retrieve location with the provided id. location = jhu.get(id) - # Fetch the timelines. + # Get all the timelines. timelines = { 'confirmed': location.confirmed.serialize(), 'deaths' : location.deaths.serialize(), From e2b6630fc4d93bd92e47334e157f266fb4e39731 Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 02:51:13 +0100 Subject: [PATCH 06/10] cached locations --- app/services/location/__init__.py | 2 +- app/services/location/jhu.py | 81 +++++++++++++++++++------------ 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/app/services/location/__init__.py b/app/services/location/__init__.py index 2312283a..3338b3d3 100644 --- a/app/services/location/__init__.py +++ b/app/services/location/__init__.py @@ -11,7 +11,7 @@ def get_all(self): Gets and returns all of the locations. :returns: The locations. - :rtype: Location + :rtype: List[Location] """ raise NotImplementedError diff --git a/app/services/location/jhu.py b/app/services/location/jhu.py index 1c5a9d39..7fc719cb 100644 --- a/app/services/location/jhu.py +++ b/app/services/location/jhu.py @@ -9,35 +9,8 @@ class JhuLocationService(LocationService): """ def get_all(self): - # Get all of the data categories locations. - confirmed = get_category('confirmed')['locations'] - deaths = get_category('deaths')['locations'] - recovered = get_category('recovered')['locations'] - - # Final locations to return. - locations = [] - - # Go through confirmed locations. - for index, location in enumerate(confirmed): - # Grab coordinates. - coordinates = location['coordinates'] - - # Create location and append. - locations.append(Location( - # General info. - index, location['country'], location['province'], Coordinates(coordinates['lat'], coordinates['long']), - - # TODO: date key as ISO format. - # { datetime.strptime(date, '%m/%d/%y').isoformat() + 'Z': int(amount or 0) for date, amount in history.items() } - - # Timelines. - Timeline(confirmed[index]['history']), - Timeline(deaths[index]['history']), - Timeline(recovered[index]['history']) - )) - - # Finally, return the locations. - return locations + # Get the locations. + return get_locations() def get(self, id): # Get location at the index equal to provided id. @@ -58,6 +31,9 @@ def get(self, id): def get_category(category): """ Retrieves the data for the provided category. The data is cached for 1 hour. + + :returns: The data for category. + :rtype: dict """ # Adhere to category naming standard. @@ -73,7 +49,7 @@ def get_category(category): # The normalized locations. locations = [] - for item in data: + for i, item in enumerate(data): # Filter out all the dates. dates = dict(filter(lambda element: date_util.is_date(element[0]), item.items())) @@ -115,4 +91,47 @@ def get_category(category): 'latest': latest, 'last_updated': datetime.utcnow().isoformat() + 'Z', 'source': 'https://github.com/ExpDev07/coronavirus-tracker-api', - } \ No newline at end of file + } + +@cached(cache=TTLCache(maxsize=1024, ttl=3600)) +def get_locations(): + """ + Retrieves the locations from the categories. The locations are cached for 1 hour. + + :returns: The locations. + :rtype: List[Location] + """ + # Get all of the data categories locations. + confirmed = get_category('confirmed')['locations'] + deaths = get_category('deaths')['locations'] + recovered = get_category('recovered')['locations'] + + # Final locations to return. + locations = [] + + # Go through locations. + for index, location in enumerate(confirmed): + # Get the timelines. + timelines = { + 'confirmed' : confirmed[index]['history'], + 'deaths' : deaths[index]['history'], + 'recovered' : recovered[index]['history'], + } + + # Grab coordinates. + coordinates = location['coordinates'] + + # Create location and append. + locations.append(Location( + # General info. + index, location['country'], location['province'], Coordinates(coordinates['lat'], coordinates['long']), + + # Timelines (parse dates as ISO). + Timeline({ datetime.strptime(date, '%m/%d/%y').isoformat() + 'Z': amount for date, amount in timelines['confirmed'].items() }), + Timeline({ datetime.strptime(date, '%m/%d/%y').isoformat() + 'Z': amount for date, amount in timelines['deaths'].items() }), + Timeline({ datetime.strptime(date, '%m/%d/%y').isoformat() + 'Z': amount for date, amount in timelines['recovered'].items() }) + )) + + # Finally, return the locations. + return locations + \ No newline at end of file From 9b7808d1bfe34ef8542708ea837da8837e6c6729 Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 03:10:38 +0100 Subject: [PATCH 07/10] updated doc --- README.md | 88 ++++++++++++++++++++++++++++++------ app/services/location/jhu.py | 2 +- app/utils/countrycodes.py | 3 +- 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 02caa8d7..0f7f694b 100644 --- a/README.md +++ b/README.md @@ -12,37 +12,95 @@ ## Endpoints -All requests must be made to the base url: ``https://coronavirus-tracker-api.herokuapp.com`` (e.g: https://coronavirus-tracker-api.herokuapp.com/all). You can try them out in your browser to further inspect responses. +All requests must be made to the base url: ``https://coronavirus-tracker-api.herokuapp.com/v2/`` (e.g: https://coronavirus-tracker-api.herokuapp.com/v2/locations). You can try them out in your browser to further inspect responses. -Getting confirmed cases, deaths, and recoveries: +### Getting latest amount of total confirmed cases, deaths, and recoveries. ```http -GET /all +GET /v2/latest ``` ```json -{ "latest": { ... }, "confirmed": { ... }, "deaths": { ... }, "recovered": { ... } } +{ + "latest": { + "confirmed": 197146, + "deaths": 7905, + "recovered": 80840 + } +} ``` -Getting just confirmed: +### Getting all locations. ```http -GET /confirmed +GET /v2/locations ``` ```json { - "latest": 42767, - "locations": [ ... ], - "last_updated": "2020-03-07T18:08:58.432242Z", - "source": "https://github.com/ExpDev07/coronavirus-tracker-api" + "locations": [ + { + "id": 0, + "country": "Thailand", + "country_code": "TH", + "province": "", + "coordinates": { + "latitude": "15", + "longitude": "101" + }, + "latest": { + "confirmed": 177, + "deaths": 1, + "recovered": 41 + } + }, + { + "id": 39, + "country": "Norway", + "country_code": "NO", + "province": "", + "coordinates": { + "latitude": "60.472", + "longitude": "8.4689" + }, + "latest": { + "confirmed": 1463, + "deaths": 3, + "recovered": 1 + } + } + ] } ``` -Getting just deaths: +Additionally, you can also filter by country ([alpha-2 country_code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)). ```http -GET /deaths +GET /v2/locations?country_code=US ``` -Getting just recoveries: +### Getting a specific location (includes timeline). ```http -GET /recovered +GET /v2/locations/:id +``` +```json +{ + "location": { + "id": 39, + "country": "Norway", + "country_code": "NO", + "province": "", + "coordinates": { }, + "latest": { }, + "timelines": { + "confirmed": { + "latest": 1463, + "timeline": { + "2020-03-16T00:00:00Z": 1333, + "2020-03-17T00:00:00Z": 1463 + } + }, + "deaths": { }, + "recovered": { } + } + } + } +} ``` ## Data @@ -112,5 +170,5 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d ## License -The data is available to the public strictly for educational and academic research purposes. Please link to this repo somewhere in your project if you can (not required) :). +The data is available to the public strictly for educational and academic research purposes. Please link to this repo somewhere in your project :). diff --git a/app/services/location/jhu.py b/app/services/location/jhu.py index 7fc719cb..b30ba6a7 100644 --- a/app/services/location/jhu.py +++ b/app/services/location/jhu.py @@ -49,7 +49,7 @@ def get_category(category): # The normalized locations. locations = [] - for i, item in enumerate(data): + for item in data: # Filter out all the dates. dates = dict(filter(lambda element: date_util.is_date(element[0]), item.items())) diff --git a/app/utils/countrycodes.py b/app/utils/countrycodes.py index 07d067d8..4215d62c 100644 --- a/app/utils/countrycodes.py +++ b/app/utils/countrycodes.py @@ -346,8 +346,7 @@ def country_code(country): """ - Return two letter country code (Alpha-2) according to - https://en.wikipedia.org/wiki/ISO_3166-1 + Return two letter country code (Alpha-2) according to https://en.wikipedia.org/wiki/ISO_3166-1 Defaults to "XX". """ if country in is_3166_1: From 8959cd0ec3fc31ebcd2efc6e36c3d818d307990a Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 03:12:22 +0100 Subject: [PATCH 08/10] note to doc --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0f7f694b..d913615c 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ All requests must be made to the base url: ``https://coronavirus-tracker-api.herokuapp.com/v2/`` (e.g: https://coronavirus-tracker-api.herokuapp.com/v2/locations). You can try them out in your browser to further inspect responses. +**Note:** The "latest" data may differ between the legacy API (v1) and v2, although only by a tiny amount. The second version (v2) is more accurate. + ### Getting latest amount of total confirmed cases, deaths, and recoveries. ```http GET /v2/latest From d8c0903ef2be7af6e64c15ff3ddb8f11d457dc12 Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 03:29:01 +0100 Subject: [PATCH 09/10] fixed bug where latest show different values in legacy API and v2 --- app/services/location/jhu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/location/jhu.py b/app/services/location/jhu.py index b30ba6a7..621c56ca 100644 --- a/app/services/location/jhu.py +++ b/app/services/location/jhu.py @@ -60,7 +60,7 @@ def get_category(category): country = item['Country/Region'] # Latest data insert value. - latest = list(sorted(history.values()))[-1]; + latest = list(history.values())[-1]; # Normalize the item and append to locations. locations.append({ From a0327d4d0221a45e6f98dc779c8035e0dc3a8b0c Mon Sep 17 00:00:00 2001 From: ExpDev07 Date: Wed, 18 Mar 2020 03:30:04 +0100 Subject: [PATCH 10/10] Removed some dov --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index d913615c..0f7f694b 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ All requests must be made to the base url: ``https://coronavirus-tracker-api.herokuapp.com/v2/`` (e.g: https://coronavirus-tracker-api.herokuapp.com/v2/locations). You can try them out in your browser to further inspect responses. -**Note:** The "latest" data may differ between the legacy API (v1) and v2, although only by a tiny amount. The second version (v2) is more accurate. - ### Getting latest amount of total confirmed cases, deaths, and recoveries. ```http GET /v2/latest