Skip to content

Commit d954534

Browse files
authored
Merge pull request #30 from Kilo59/refactor#28
refactor Timeline class to pydantic model
2 parents ba5050e + cf65e6e commit d954534

File tree

11 files changed

+207
-230
lines changed

11 files changed

+207
-230
lines changed

Pipfile.lock

Lines changed: 152 additions & 149 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/models.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""app.models.py"""
22
from typing import Dict, List
33

4-
from pydantic import BaseModel
4+
from pydantic import BaseModel, validator
55

66

77
class Latest(BaseModel):
@@ -27,9 +27,26 @@ class Timeline(BaseModel):
2727
Timeline model.
2828
"""
2929

30-
latest: int
3130
timeline: Dict[str, int] = {}
3231

32+
@validator("timeline")
33+
@classmethod
34+
def sort_timeline(cls, value):
35+
"""Sort the timeline history before inserting into the model"""
36+
return dict(sorted(value.items()))
37+
38+
@property
39+
def latest(self):
40+
"""Get latest available history value."""
41+
return list(self.timeline.values())[-1] if self.timeline else 0
42+
43+
def serialize(self):
44+
"""
45+
Serialize the model into dict
46+
TODO: override dict() instead of using serialize
47+
"""
48+
return {**self.dict(), "latest": self.latest}
49+
3350

3451
class Timelines(BaseModel):
3552
"""

app/services/location/jhu.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from ...caches import check_cache, load_cache
1212
from ...coordinates import Coordinates
1313
from ...location import TimelinedLocation
14-
from ...timeline import Timeline
14+
from ...models import Timeline
1515
from ...utils import countries
1616
from ...utils import date as date_util
1717
from ...utils import httputils
@@ -178,25 +178,25 @@ async def get_locations():
178178
location["country"],
179179
location["province"],
180180
# Coordinates.
181-
Coordinates(coordinates["lat"], coordinates["long"]),
181+
Coordinates(latitude=coordinates["lat"], longitude=coordinates["long"]),
182182
# Last update.
183183
datetime.utcnow().isoformat() + "Z",
184184
# Timelines (parse dates as ISO).
185185
{
186186
"confirmed": Timeline(
187-
{
187+
timeline={
188188
datetime.strptime(date, "%m/%d/%y").isoformat() + "Z": amount
189189
for date, amount in timelines["confirmed"].items()
190190
}
191191
),
192192
"deaths": Timeline(
193-
{
193+
timeline={
194194
datetime.strptime(date, "%m/%d/%y").isoformat() + "Z": amount
195195
for date, amount in timelines["deaths"].items()
196196
}
197197
),
198198
"recovered": Timeline(
199-
{
199+
timeline={
200200
datetime.strptime(date, "%m/%d/%y").isoformat() + "Z": amount
201201
for date, amount in timelines["recovered"].items()
202202
}

app/services/location/nyt.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from ...caches import check_cache, load_cache
1010
from ...coordinates import Coordinates
1111
from ...location.nyt import NYTLocation
12-
from ...timeline import Timeline
12+
from ...models import Timeline
1313
from ...utils import httputils
1414
from . import LocationService
1515

@@ -119,18 +119,18 @@ async def get_locations():
119119
last_updated=datetime.utcnow().isoformat() + "Z", # since last request
120120
timelines={
121121
"confirmed": Timeline(
122-
{
122+
timeline={
123123
datetime.strptime(date, "%Y-%m-%d").isoformat() + "Z": amount
124124
for date, amount in confirmed_history.items()
125125
}
126126
),
127127
"deaths": Timeline(
128-
{
128+
timeline={
129129
datetime.strptime(date, "%Y-%m-%d").isoformat() + "Z": amount
130130
for date, amount in deaths_history.items()
131131
}
132132
),
133-
"recovered": Timeline({}),
133+
"recovered": Timeline(),
134134
},
135135
)
136136
)

app/timeline.py

Lines changed: 0 additions & 42 deletions
This file was deleted.

requirements-dev.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,44 @@ astroid==2.4.2
44
async-asgi-testclient==1.4.4
55
async-generator==1.10
66
asyncmock==0.4.2
7-
attrs==19.3.0
7+
attrs==20.2.0
88
bandit==1.6.2
99
black==19.10b0
1010
certifi==2020.6.20
1111
chardet==3.0.4
1212
click==7.1.2
13-
coverage==5.2.1
14-
coveralls==2.1.1
13+
coverage==5.3
14+
coveralls==2.1.2
1515
docopt==0.6.2
1616
gitdb==4.0.5
17-
gitpython==3.1.7
17+
gitpython==3.1.8
1818
idna==2.10
1919
importlib-metadata==1.7.0 ; python_version < '3.8'
2020
iniconfig==1.0.1
2121
invoke==1.4.1
22-
isort==4.3.21
22+
isort==5.5.2
2323
lazy-object-proxy==1.4.3
2424
mccabe==0.6.1
2525
mock==4.0.2
26-
more-itertools==8.4.0
26+
more-itertools==8.5.0
2727
multidict==4.7.6
2828
packaging==20.4
2929
pathspec==0.8.0
30-
pbr==5.4.5
30+
pbr==5.5.0
3131
pluggy==0.13.1
3232
py==1.9.0
33-
pylint==2.5.3
33+
pylint==2.6.0
3434
pyparsing==2.4.7
3535
pytest-asyncio==0.14.0
36-
pytest-cov==2.10.0
37-
pytest==6.0.1
36+
pytest-cov==2.10.1
37+
pytest==6.0.2
3838
pyyaml==5.3.1
3939
regex==2020.7.14
4040
requests==2.24.0
41-
responses==0.10.15
41+
responses==0.12.0
4242
six==1.15.0
4343
smmap==3.0.4
44-
stevedore==3.2.0
44+
stevedore==3.2.2
4545
toml==0.10.1
4646
typed-ast==1.4.1
4747
urllib3[secure]==1.25.10 ; python_version >= '3.5'

requirements.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ aioredis==1.3.1
66
asgiref==3.2.10 ; python_version >= '3.5'
77
async-timeout==3.0.1
88
asyncache==0.1.1
9-
attrs==19.3.0
9+
attrs==20.2.0
1010
cachetools==4.1.1
1111
certifi==2020.6.20
12-
cffi==1.14.1
12+
cffi==1.14.2
1313
chardet==3.0.4
1414
click==7.1.2
15-
cryptography==3.0
15+
cryptography==3.1
1616
dataclasses==0.6 ; python_version < '3.7'
17-
fastapi==0.60.1
17+
fastapi==0.61.1
1818
gunicorn==20.0.4
1919
h11==0.9.0
2020
hiredis==1.1.0
@@ -29,8 +29,8 @@ pyopenssl==19.1.0
2929
python-dateutil==2.8.1
3030
python-dotenv==0.14.0
3131
requests==2.24.0
32-
scout-apm==2.15.2
33-
sentry-sdk==0.16.2
32+
scout-apm==2.16.1
33+
sentry-sdk==0.17.4
3434
six==1.15.0
3535
starlette==0.13.6
3636
urllib3[secure]==1.25.10 ; python_version >= '3.5'

tasks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
def sort(ctx, targets="."):
2121
"""Sort module imports."""
2222
print("sorting imports ...")
23-
args = ["isort", "-rc", "--atomic", targets]
23+
args = ["isort", "--atomic", targets]
2424
ctx.run(" ".join(args))
2525

2626

@@ -40,7 +40,7 @@ def check(ctx, fmt=False, sort=False, diff=False): # pylint: disable=redefined-
4040
sort = True
4141

4242
fmt_args = ["black", "--check", "."]
43-
sort_args = ["isort", "-rc", "--check", "."]
43+
sort_args = ["isort", "--check", "."]
4444

4545
if diff:
4646
fmt_args.append("--diff")

tests/test_countries.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from app.utils import countries
44

5-
65
"""
76
Todo:
87
* Test cases for capturing of stdout/stderr

tests/test_location.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import pytest
55

6-
from app import coordinates, location, timeline
6+
from app import coordinates, location, models
77

88

99
def mocked_timeline(*args, **kwargs):
@@ -22,7 +22,7 @@ def __init__(self, latest):
2222
(2, "Cruise Ship", "XX", "", 15, 100, 1000, 1111, 22222),
2323
],
2424
)
25-
@mock.patch("app.timeline.Timeline", side_effect=mocked_timeline)
25+
@mock.patch("app.models.Timeline", side_effect=mocked_timeline)
2626
def test_location_class(
2727
mocked_timeline,
2828
test_id,
@@ -39,9 +39,9 @@ def test_location_class(
3939
coords = coordinates.Coordinates(latitude=latitude, longitude=longitude)
4040

4141
# Timelines
42-
confirmed = timeline.Timeline(confirmed_latest)
43-
deaths = timeline.Timeline(deaths_latest)
44-
recovered = timeline.Timeline(recovered_latest)
42+
confirmed = models.Timeline(confirmed_latest)
43+
deaths = models.Timeline(deaths_latest)
44+
recovered = models.Timeline(recovered_latest)
4545

4646
# Date now.
4747
now = datetime.utcnow().isoformat() + "Z"

0 commit comments

Comments
 (0)