diff --git a/.all-contributorsrc b/.all-contributorsrc
index de07f666..e0c81180 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -110,6 +110,15 @@
"contributions": [
"doc"
]
+ },
+ {
+ "login": "carmelag",
+ "name": "carmelag",
+ "avatar_url": "https://avatars0.githubusercontent.com/u/5394906?v=4",
+ "profile": "http://www.carmelagreco.dev",
+ "contributions": [
+ "doc"
+ ]
}
],
"contributorsPerLine": 7,
diff --git a/README.md b/README.md
index 4dce4c45..2c1b3304 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,6 @@
-
- coronavirus-tracker (API)
-
-
-> This is a fast (< 200ms) and basic API for tracking development of the new coronavirus (COVID-19, SARS-CoV-2). It's written in python using 🍼 Flask. Supports multiple sources!
+## Coronavirus Tracker API
+Provides up-to-date data about Coronavirus outbreak. Includes numbers about confirmed cases, deaths and recovered.
+Support multiple data-sources.

[](LICENSE.md)
@@ -20,26 +18,63 @@


-## Endpoints
+## Available data-sources:
+
+Currently 2 different data-sources are available to retrieve the data:
-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.
+* **jhu** - https://github.com/CSSEGISandData/COVID-19 - Worldwide Data repository operated by the Johns Hopkins University Center for Systems Science and Engineering (JHU CSSE).
-### Picking data source
+* **csbs** - https://www.csbs.org/information-covid-19-coronavirus - U.S. County data that comes from the Conference of State Bank Supervisors.
-We provide multiple data-sources you can pick from, simply add the query parameter ``?source=your_source_of_choice`` to your requests. JHU will be used as a default if you don't provide one.
+__jhu__ data-source will be used as a default source if you don't specify a *source parameter* in your request.
-#### Available sources:
-* **jhu** - https://github.com/CSSEGISandData/COVID-19 - Data repository operated by the Johns Hopkins University Center for Systems Science and Engineering (JHU CSSE).
+## API Reference
-* **csbs** - https://www.csbs.org/information-covid-19-coronavirus - U.S. County data that comes from the Conference of State Bank Supervisors.
+All endpoints are located at ``coronavirus-tracker-api.herokuapp.com/v2/`` and are accessible via https. For instance: you can get data per location by using this URL:
+*[https://coronavirus-tracker-api.herokuapp.com/v2/locations](https://coronavirus-tracker-api.herokuapp.com/v2/locations)*
+
+You can open the URL in your browser to further inspect the response. Or you can make this curl call in your terminal to see the prettified response:
+
+```
+curl https://coronavirus-tracker-api.herokuapp.com/v2/locations | json_pp
+```
+
+
+## API Endpoints
+
+### Sources Endpoint
+
+Getting the data-sources that are currently available to Coronavirus Tracker API to retrieve the data of the pandemic.
+
+```http
+GET /v2/sources
+```
+
+__Sample response__
+```json
+{
+ "sources": [
+ "jhu",
+ "csbs"
+ ]
+}
+```
-* **... more to come later**.
+### Latest Endpoint
+
+Getting latest amount of total confirmed cases, deaths, and recovered.
-### Getting latest amount of total confirmed cases, deaths, and recoveries.
```http
GET /v2/latest
```
+
+__Query String Parameters__
+| __Query string parameter__ | __Description__ | __Type__ |
+| -------------------------- | -------------------------------------------------------------------------------- | -------- |
+| source | The data-source where data will be retrieved from *(jhu/csbs)*. Default is *jhu* | String |
+
+__Sample response__
```json
{
"latest": {
@@ -50,10 +85,69 @@ GET /v2/latest
}
```
-### Getting all locations.
+### Locations Endpoint
+
+Getting latest amount of confirmed cases, deaths, and recovered per location.
+
+#### The Location Object
+```http
+GET /v2/locations/:id
+```
+
+__Path Parameters__
+| __Path parameter__ | __Required/Optional__ | __Description__ | __Type__ |
+| ------------------ | --------------------- | ------------------------------------------------------------------------- | -------- |
+| id | OPTIONAL | The unique location id for which you want to call the Locations Endpoint. | Integer |
+
+__Query String Parameters__
+| __Query string parameter__ | __Description__ | __Type__ |
+| -------------------------- | -------------------------------------------------------------------------------- | -------- |
+| source | The data-source where data will be retrieved from *(jhu/csbs)*. Default is *jhu* | String |
+
+#### Example Request
+```http
+GET /v2/locations/39
+```
+
+__Sample response__
+```json
+{
+ "location": {
+ "id": 39,
+ "country": "Norway",
+ "country_code": "NO",
+ "province": "",
+ "last_updated": "2020-03-21T06:59:11.315422Z",
+ "coordinates": { },
+ "latest": { },
+ "timelines": {
+ "confirmed": {
+ "latest": 1463,
+ "timeline": {
+ "2020-03-16T00:00:00Z": 1333,
+ "2020-03-17T00:00:00Z": 1463
+ }
+ },
+ "deaths": { },
+ "recovered": { }
+ }
+ }
+}
+```
+
+#### List of all locations
```http
GET /v2/locations
```
+
+__Query String Parameters__
+| __Query string parameter__ | __Description__ | __Type__ |
+| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
+| source | The data-source where data will be retrieved from.
__Value__ can be: *jhu/csbs*. __Default__ is *jhu* | String |
+| country_code | The ISO ([alpha-2 country_code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)) to the Country/Province for which you're calling the Endpoint | String |
+| timelines | To set the visibility of timelines (*daily tracking*).
__Value__ can be: *0/1*. __Default__ is *0* (timelines are not visible) | Integer |
+
+__Sample response__
```json
{
"latest": {
@@ -98,54 +192,76 @@ GET /v2/locations
}
```
-Additionally, you can also filter by any attribute, including province and country ([alpha-2 country_code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)).
-```http
-GET /v2/locations?country_code=US
-```
+__Response definitions__
+| __Response Item__ | __Description__ | __Type__ |
+| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
+| {latest} | The total amount of confirmed cases, deaths and recovered for all the locations | Object |
+| {latest}/confirmed | The up-to-date total number of confirmed cases for all the locations within the data-source | Integer |
+| {latest}/deaths | The up-to-date total amount of deaths for all the locations within the data-source | Integer |
+| {latest}/recovered | The up-to-date total amount of recovered for all the locations within the data-source | Integer |
+| {locations} | The collection of locations contained within the data-source | Object |
+| {location} | Information that identifies a location | Object |
+| {latest} | The amount of confirmed cases, deaths and recovered related to the specific location | Object |
+| {locations}/{location}/{latest}/confirmed | The up-to-date number of confirmed cases related to the specific location | Integer |
+| {locations}/{location}/{latest}/deaths | The up-to-date number of deaths related to the specific location | Integer |
+| {locations}/{location}/{latest}/recovered | The up-to-date number of recovered related to the specific location | Integer |
+| {locations}/{location}/id | The location id. This unique id is assigned to the location by the data-source. | Integer |
+| {locations}/{location}/country | The Country name | String |
+| {locations}/{location}/country_code | The [ISO alpha-2 country_code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) Country code for the location. | String |
+| {locations}/{location}/province | The province where the location belongs to. (Used for US locations coming from __csbs data-source__.
__Empty__ when *jhu data-source* is used | String |
+| {locations}/{location}/{coordinates}/latitude | The location latitude | Float |
+| {locations}/{location}/{coordinates}/longitude | The location longitude | Float |
+
+
+### Example Requests with parameters
+
+__Parameter: country_code__
+
+Getting data for the Country specified by the *country_code parameter*, in this case Italy - IT
-Include timelines.
```http
-GET /v2/locations?timelines=1
+GET /v2/locations?country_code=IT
```
-### Getting a specific location (includes timelines by default).
-```http
-GET /v2/locations/:id
-```
+__Sample Response__
```json
{
- "location": {
- "id": 39,
- "country": "Norway",
- "country_code": "NO",
- "province": "",
- "last_updated": "2020-03-21T06:59:11.315422Z",
- "coordinates": { },
- "latest": { },
- "timelines": {
- "confirmed": {
- "latest": 1463,
- "timeline": {
- "2020-03-16T00:00:00Z": 1333,
- "2020-03-17T00:00:00Z": 1463
+ "latest": {
+ "confirmed": 59138,
+ "deaths": 5476,
+ "recovered": 7024
+ },
+ "locations": [
+ {
+ "coordinates": {
+ "latitude": "43",
+ "longitude": "12"
+ },
+ "country": "Italy",
+ "country_code": "IT",
+ "id": 16,
+ "last_updated": "2020-03-23T13:32:23.913872Z",
+ "latest": {
+ "confirmed": 59138,
+ "deaths": 5476,
+ "recovered": 7024
+ },
+ "province": ""
}
- },
- "deaths": { },
- "recovered": { }
- }
- }
+ ]
}
```
-Exclude timelines.
-```http
-GET /v2/locations?timelines=0
-```
+__Parameter: source__
+
+Getting the data from the data-source specified by the *source parameter*, in this case [csbs](https://www.csbs.org/information-covid-19-coronavirus)
+
-### Getting US per county information.
```http
GET /v2/locations?source=csbs
```
+
+__Sample Response__
```json
{
"latest": {
@@ -194,6 +310,23 @@ GET /v2/locations?source=csbs
}
```
+__Parameter: timelines__
+
+Getting the data for all the locations including the daily tracking of confirmed cases, deaths and recovered per location.
+
+```http
+GET /v2/locations?timelines=1
+```
+Explore the response by opening the URL in your browser [https://coronavirus-tracker-api.herokuapp.com/v2/locations?timelines=1](https://coronavirus-tracker-api.herokuapp.com/v2/locations?timelines=1) or make the following curl call in your terminal:
+
+```
+curl https://coronavirus-tracker-api.herokuapp.com/v2/locations?timelines=1 | json_pp
+```
+
+__NOTE:__ Timelines tracking starts from day 22nd January 2020 and ends to the last available day in the data-source.
+
+
+
## Wrappers
These are the available API wrappers created by the community. They are not necessarily maintained by any of this project's authors or contributors.
@@ -284,6 +417,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
 Abdirahiim Yassin 📖 |
 Darío Hereñú 📖 |
 Oliver 📖 |
+  carmelag 📖 |
diff --git a/app/routes/__init__.py b/app/routes/__init__.py
index b890a031..8d1f45eb 100644
--- a/app/routes/__init__.py
+++ b/app/routes/__init__.py
@@ -1,4 +1,4 @@
-from flask import Blueprint, redirect, request, current_app as app
+from flask import Blueprint, redirect, request, abort, current_app as app
from ..data import data_source
# Follow the import order to avoid circular dependency
@@ -6,7 +6,7 @@
api_v2 = Blueprint('api_v2', __name__, url_prefix='/v2')
# API version 2.
-from .v2 import locations, latest
+from .v2 import locations, latest, sources
# API version 1.
from .v1 import confirmed, deaths, recovered, all
@@ -23,8 +23,12 @@ def datasource():
Attaches the datasource to the request.
"""
# Retrieve the datas ource from query param.
- source = request.args.get('source', type=str, default='jhu')
+ source = data_source(request.args.get('source', type=str, default='jhu'))
+
+ # Abort with 404 if source cannot be found.
+ if not source:
+ return abort(404, description='The provided data-source was not found.')
# Attach source to request and return it.
- request.source = data_source(source)
+ request.source = source
pass
diff --git a/app/routes/v2/locations.py b/app/routes/v2/locations.py
index f9104015..5a222b90 100644
--- a/app/routes/v2/locations.py
+++ b/app/routes/v2/locations.py
@@ -17,7 +17,7 @@ def locations():
try:
locations = [j for j in locations if getattr(j, i) == args.get(i, type=str)]
except AttributeError:
- print('TimelinedLocation object does not have attribute {}.'.format(i))
+ print('Location does not have attribute {}.'.format(i))
# Serialize each location and return.
return jsonify({
diff --git a/app/routes/v2/sources.py b/app/routes/v2/sources.py
new file mode 100644
index 00000000..749e3b70
--- /dev/null
+++ b/app/routes/v2/sources.py
@@ -0,0 +1,12 @@
+from flask import jsonify
+from ...data import data_sources
+from ...routes import api_v2 as api
+
+@api.route('/sources')
+def sources():
+ """
+ Retrieves a list of data-sources that are availble to use.
+ """
+ return jsonify({
+ 'sources': list(data_sources.keys())
+ })
diff --git a/app/services/location/csbs.py b/app/services/location/csbs.py
index e63804af..f6140b75 100644
--- a/app/services/location/csbs.py
+++ b/app/services/location/csbs.py
@@ -38,28 +38,41 @@ def get_locations():
locations = []
for i, item in enumerate(data):
+ # General info.
state = item['State Name']
county = item['County Name']
+
+ # Ensure country is specified.
if county == "Unassigned" or county == "Unknown":
continue
- confirmed = int(item['Confirmed'] or 0)
- death = int(item['Death'] or 0)
- coordinates = Coordinates(float(item['Latitude']), float(item['Longitude']))
+ # Coordinates.
+ coordinates = Coordinates(
+ item['Latitude'],
+ item['Longitude']
+ )
+
+ # Date string without "EDT" at end.
+ last_update = ' '.join(item['Last Update'].split(' ')[0:2])
- # Parse time to ISO format
- last_update = item['Last Update']
- date = last_update.split("-")
- year = int(date[0])
- month = int(date[1])
- date = date[2].split(" ")
- day = int(date[0])
- time = date[1].split(":")
- hour = int(time[0])
- minute = int(time[1])
- d = datetime(year=year, month=month, day=day, hour=hour, minute=minute)
- last_update = d.isoformat() + 'Z'
+ # Append to locations.
+ locations.append(CSBSLocation(
+ # General info.
+ i, state, county,
+
+ # Coordinates.
+ Coordinates(
+ item['Latitude'],
+ item['Longitude']
+ ),
- locations.append(CSBSLocation(i, state, county, coordinates, last_update, confirmed, death))
+ # Last update (parse as ISO).
+ datetime.strptime(last_update, '%Y/%m/%d %H:%M').isoformat() + 'Z',
+
+ # Statistics.
+ int(item['Confirmed'] or 0),
+ int(item['Death'] or 0)
+ ))
+ # Return the locations.
return locations
diff --git a/tests/example_data/sample_covid19_county.csv b/tests/example_data/sample_covid19_county.csv
index ee972c59..9f89341d 100644
--- a/tests/example_data/sample_covid19_county.csv
+++ b/tests/example_data/sample_covid19_county.csv
@@ -1,33 +1,33 @@
County Name,State Name,Confirmed,New,Death,Fatality Rate,Latitude,Longitude,Last Update
-New York,New York,4408,454,26,0.6%,40.71455,-74.00714,2020-03-20 13:58 EDT
-Westchester,New York,1091,293,0,0%,41.16319759,-73.7560629,2020-03-20 13:58 EDT
-Nassau,New York,754,382,4,0.5%,40.74165225,-73.58899619,2020-03-20 13:58 EDT
-Yakima,Washington,7,0,0,0%,46.60448,-120.50721,2020-03-20 13:58 EDT
-Thurston,Washington,6,0,0,0%,46.91980578,-122.8298691,2020-03-20 13:58 EDT
-Jefferson,Washington,4,0,0,0%,47.74810608,-123.6000095,2020-03-20 13:58 EDT
-Douglas,Kansas,1,0,0,0%,38.88462907,-95.29255463,2020-03-20 13:58 EDT
-Cherokee,Kansas,1,0,0,0%,37.16926692,-94.8462675759999,2020-03-20 13:58 EDT
-Jackson,Kansas,1,0,0,0%,39.4168027220001,-95.793674403,2020-03-20 13:58 EDT
-Twin Falls,Idaho,1,0,0,0%,42.55619,-114.4696,2020-03-20 13:58 EDT
-Kootenai,Idaho,1,0,0,0%,47.6775872760001,-116.697131928,2020-03-20 13:58 EDT
-Chittenden,Vermont,4,0,1,25%,44.45799511,-73.05404973,2020-03-20 13:58 EDT
-Bennington,Vermont,3,0,0,0%,42.87672,-73.19818,2020-03-20 13:58 EDT
-Windsor,Vermont,3,0,1,33.3%,43.48115,-72.38581,2020-03-20 13:58 EDT
-Washington,Vermont,1,0,0,0%,44.27344561,-72.61485925,2020-03-20 13:58 EDT
-Orange,Vermont,1,0,0,0%,44.14854,-72.40233,2020-03-20 13:58 EDT
-Addison,Vermont,1,0,0,0%,44.0280736,-73.13152876,2020-03-20 13:58 EDT
-Burleigh,North Dakota,11,0,0,0%,46.97801044,-100.4669442,2020-03-20 13:58 EDT
-Tucker,West Virginia,2,0,0,0%,39.1135508250001,-79.56492129,2020-03-20 13:58 EDT
-Mercer,West Virginia,1,0,0,0%,37.40556515,-81.11143231,2020-03-20 13:58 EDT
-Monongalia,West Virginia,1,0,0,0%,39.630233859,-80.0465546289999,2020-03-20 13:58 EDT
-Unassigned,New York,166,149,4,2.4%,42.165726,-74.948051,2020-03-20 13:58 EDT
-Unassigned,Washington,151,0,0,0%,47.400902,-121.490494,2020-03-20 13:58 EDT
-Unassigned,Colorado,57,0,0,0%,39.059811,-105.311104,2020-03-20 13:58 EDT
-Unknown,Pennsylvania,55,55,0,0%,40.590752,-77.209755,2020-03-20 13:58 EDT
-Unassigned,Pennsylvania,0,0,0,NaN%,40.590752,-77.209755,2020-03-20 13:58 EDT
-Franklin,Pennsylvania,1,1,0,0%,39.927495836,-77.721161869,2020-03-20 13:58 EDT
-Franklin,North Carolina,4,4,0,0%,36.0827448150001,-78.285600305,2020-03-20 13:58 EDT
-Lee,North Carolina,1,1,0,0%,35.475059921,-79.17154054,2020-03-20 13:58 EDT
-Clay,Minnesota,1,1,0,0%,46.892347886,-96.490737839,2020-03-20 13:58 EDT
-Yuma,Arizona,1,1,0,0%,32.768956524,-113.905830295,2020-03-20 13:58 EDT
-Dunklin,Missouri,1,1,0,0%,36.105848973,-90.16563,2020-03-20 13:58 EDT
+New York,New York,4408,454,26,0.6%,40.71455,-74.00714,2020/03/20 13:58 EDT
+Westchester,New York,1091,293,0,0%,41.16319759,-73.7560629,2020/03/20 13:58 EDT
+Nassau,New York,754,382,4,0.5%,40.74165225,-73.58899619,2020/03/20 13:58 EDT
+Yakima,Washington,7,0,0,0%,46.60448,-120.50721,2020/03/20 13:58 EDT
+Thurston,Washington,6,0,0,0%,46.91980578,-122.8298691,2020/03/20 13:58 EDT
+Jefferson,Washington,4,0,0,0%,47.74810608,-123.6000095,2020/03/20 13:58 EDT
+Douglas,Kansas,1,0,0,0%,38.88462907,-95.29255463,2020/03/20 13:58 EDT
+Cherokee,Kansas,1,0,0,0%,37.16926692,-94.8462675759999,2020/03/20 13:58 EDT
+Jackson,Kansas,1,0,0,0%,39.4168027220001,-95.793674403,2020/03/20 13:58 EDT
+Twin Falls,Idaho,1,0,0,0%,42.55619,-114.4696,2020/03/20 13:58 EDT
+Kootenai,Idaho,1,0,0,0%,47.6775872760001,-116.697131928,2020/03/20 13:58 EDT
+Chittenden,Vermont,4,0,1,25%,44.45799511,-73.05404973,2020/03/20 13:58 EDT
+Bennington,Vermont,3,0,0,0%,42.87672,-73.19818,2020/03/20 13:58 EDT
+Windsor,Vermont,3,0,1,33.3%,43.48115,-72.38581,2020/03/20 13:58 EDT
+Washington,Vermont,1,0,0,0%,44.27344561,-72.61485925,2020/03/20 13:58 EDT
+Orange,Vermont,1,0,0,0%,44.14854,-72.40233,2020/03/20 13:58 EDT
+Addison,Vermont,1,0,0,0%,44.0280736,-73.13152876,2020/03/20 13:58 EDT
+Burleigh,North Dakota,11,0,0,0%,46.97801044,-100.4669442,2020/03/20 13:58 EDT
+Tucker,West Virginia,2,0,0,0%,39.1135508250001,-79.56492129,2020/03/20 13:58 EDT
+Mercer,West Virginia,1,0,0,0%,37.40556515,-81.11143231,2020/03/20 13:58 EDT
+Monongalia,West Virginia,1,0,0,0%,39.630233859,-80.0465546289999,2020/03/20 13:58 EDT
+Unassigned,New York,166,149,4,2.4%,42.165726,-74.948051,2020/03/20 13:58 EDT
+Unassigned,Washington,151,0,0,0%,47.400902,-121.490494,2020/03/20 13:58 EDT
+Unassigned,Colorado,57,0,0,0%,39.059811,-105.311104,2020/03/20 13:58 EDT
+Unknown,Pennsylvania,55,55,0,0%,40.590752,-77.209755,2020/03/20 13:58 EDT
+Unassigned,Pennsylvania,0,0,0,NaN%,40.590752,-77.209755,2020/03/20 13:58 EDT
+Franklin,Pennsylvania,1,1,0,0%,39.927495836,-77.721161869,2020/03/20 13:58 EDT
+Franklin,North Carolina,4,4,0,0%,36.0827448150001,-78.285600305,2020/03/20 13:58 EDT
+Lee,North Carolina,1,1,0,0%,35.475059921,-79.17154054,2020/03/20 13:58 EDT
+Clay,Minnesota,1,1,0,0%,46.892347886,-96.490737839,2020/03/20 13:58 EDT
+Yuma,Arizona,1,1,0,0%,32.768956524,-113.905830295,2020/03/20 13:58 EDT
+Dunklin,Missouri,1,1,0,0%,36.105848973,-90.16563,2020/03/20 13:58 EDT