Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ install:
- "pip install pipenv"
- "pipenv install --dev --skip-lock"
script:
- "make test lint"
- "make test lint check-fmt"
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,11 @@ test:

lint:
pylint $(APP) || true

fmt:
isort -rc --atomic
black .

check-fmt:
isort -rc --check
black . --check --diff
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new fmt and check-fmt commands

2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ verify_ssl = true

[dev-packages]
bandit = "*"
black = "==19.10b0"
isort = "*"
pytest = "*"
pylint = "*"

Expand Down
91 changes: 90 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Support multiple data-sources.
[![GitHub last commit](https://img.shields.io/github/last-commit/ExpDev07/coronavirus-tracker-api)](https://github.com/ExpDev07/coronavirus-tracker-api/commits/master)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/ExpDev07/coronavirus-tracker-api)](https://github.com/ExpDev07/coronavirus-tracker-api/pulls)
[![GitHub issues](https://img.shields.io/github/issues/ExpDev07/coronavirus-tracker-api)](https://github.com/ExpDev07/coronavirus-tracker-api/issues)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Tweet](https://img.shields.io/twitter/url?url=https%3A%2F%2Fgithub.com%2FExpDev07%2Fcoronavirus-tracker-api)](https://twitter.com/intent/tweet?text=COVID19%20Live%20Tracking%20API:%20&url=https%3A%2F%2Fgithub.com%2FExpDev07%2Fcoronavirus-tracker-api)

**Live global stats (provided by [fight-covid19/bagdes](https://github.com/fight-covid19/bagdes)) from this API:**
Expand Down
2 changes: 1 addition & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# See PEP396.
__version__ = '2.0'
__version__ = "2.0"

from .core import create_app
3 changes: 2 additions & 1 deletion app/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

# Load enviroment variables from .env file.
from dotenv import load_dotenv

load_dotenv()

"""
The port to serve the app application on.
"""
PORT = int(os.getenv('PORT', 5000))
PORT = int(os.getenv("PORT", 5000))
7 changes: 2 additions & 5 deletions app/coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ def serialize(self):
:returns: The serialized coordinates.
:rtype: dict
"""
return {
'latitude' : self.latitude,
'longitude': self.longitude
}
return {"latitude": self.latitude, "longitude": self.longitude}

def __str__(self):
return 'lat: %s, long: %s' % (self.latitude, self.longitude)
return "lat: %s, long: %s" % (self.latitude, self.longitude)
3 changes: 2 additions & 1 deletion app/core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from flask import Flask
from flask_cors import CORS


def create_app():
"""
Construct the core application.
Expand All @@ -10,7 +11,7 @@ def create_app():
CORS(app)

# Set app config from settings.
app.config.from_pyfile('config/settings.py');
app.config.from_pyfile("config/settings.py")

with app.app_context():
# Import routes.
Expand Down
10 changes: 4 additions & 6 deletions app/data/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from ..services.location.jhu import JhuLocationService
from ..services.location.csbs import CSBSLocationService
from ..services.location.jhu import JhuLocationService

# Mapping of services to data-sources.
data_sources = {
'jhu': JhuLocationService(),
'csbs': CSBSLocationService()
}
data_sources = {"jhu": JhuLocationService(), "csbs": CSBSLocationService()}


def data_source(source):
"""
Expand All @@ -14,4 +12,4 @@ def data_source(source):
:returns: The service.
:rtype: LocationService
"""
return data_sources.get(source.lower())
return data_sources.get(source.lower())
6 changes: 4 additions & 2 deletions app/enums/sources.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from enum import Enum


class Sources(str, Enum):
"""
A source available for retrieving data.
"""
jhu = 'jhu'
csbs = 'csbs'

jhu = "jhu"
csbs = "csbs"
55 changes: 29 additions & 26 deletions app/location/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from ..coordinates import Coordinates
from ..utils import countrycodes


class Location:
"""
A location in the world affected by the coronavirus.
Expand All @@ -20,7 +21,7 @@ def __init__(self, id, country, province, coordinates, last_updated, confirmed,
self.confirmed = confirmed
self.deaths = deaths
self.recovered = recovered

@property
def country_code(self):
"""
Expand All @@ -37,25 +38,19 @@ def serialize(self):
"""
return {
# General info.
'id' : self.id,
'country' : self.country,
'country_code': self.country_code,
'province' : self.province,

"id": self.id,
"country": self.country,
"country_code": self.country_code,
"province": self.province,
# Coordinates.
'coordinates': self.coordinates.serialize(),

"coordinates": self.coordinates.serialize(),
# Last updated.
'last_updated': self.last_updated,

"last_updated": self.last_updated,
# Latest data (statistics).
'latest': {
'confirmed': self.confirmed,
'deaths' : self.deaths,
'recovered': self.recovered
},
"latest": {"confirmed": self.confirmed, "deaths": self.deaths, "recovered": self.recovered},
}


class TimelinedLocation(Location):
"""
A location with timelines.
Expand All @@ -64,18 +59,21 @@ class TimelinedLocation(Location):
def __init__(self, id, country, province, coordinates, last_updated, timelines):
super().__init__(
# General info.
id, country, province, coordinates, last_updated,

id,
country,
province,
coordinates,
last_updated,
# Statistics (retrieve latest from timelines).
confirmed=timelines.get('confirmed').latest or 0,
deaths=timelines.get('deaths').latest or 0,
recovered=timelines.get('recovered').latest or 0,
confirmed=timelines.get("confirmed").latest or 0,
deaths=timelines.get("deaths").latest or 0,
recovered=timelines.get("recovered").latest or 0,
)

# Set timelines.
self.timelines = timelines

def serialize(self, timelines = False):
def serialize(self, timelines=False):
"""
Serializes the location into a dict.

Expand All @@ -87,10 +85,15 @@ def serialize(self, timelines = False):

# Whether to include the timelines or not.
if timelines:
serialized.update({ 'timelines': {
# Serialize all the timelines.
key: value.serialize() for (key, value) in self.timelines.items()
}})
serialized.update(
{
"timelines": {
# Serialize all the timelines.
key: value.serialize()
for (key, value) in self.timelines.items()
}
}
)

# Return the serialized location.
return serialized
return serialized
Loading