From 917567c5df1437da7d94dc0325e9c54731ce5d9d Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Wed, 12 Oct 2022 16:49:23 +0200 Subject: [PATCH 1/5] added server side API for global incident rates --- caimira/apps/calculator/__init__.py | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/caimira/apps/calculator/__init__.py b/caimira/apps/calculator/__init__.py index 91f2c5d1..67357d11 100644 --- a/caimira/apps/calculator/__init__.py +++ b/caimira/apps/calculator/__init__.py @@ -8,6 +8,8 @@ import base64 import functools import html import json +import pandas as pd +from io import StringIO import os from pathlib import Path import traceback @@ -298,6 +300,38 @@ class ArveData(BaseRequestHandler): self.set_header("Content-Type", 'application/json') return self.finish(response.body) + +class CasesData(BaseRequestHandler): + async def get(self, country): + http_client = AsyncHTTPClient() + # First we need the country to fetch the data + URL = f'https://restcountries.com/v3.1/alpha/{country}?fields=name' + try: + response = await http_client.fetch(HTTPRequest( + url=URL, + method='GET', + ), + raise_error=True) + except Exception as e: + print("Something went wrong: %s" % e) + + country_name = json.loads(response.body)['name']['common'] + + # Get global incident rates + URL = 'https://covid19.who.int/WHO-COVID-19-global-table-data.csv' + try: + response = await http_client.fetch(HTTPRequest( + url=URL, + method='GET', + ), + raise_error=True) + except Exception as e: + print("Something went wrong: %s" % e) + + df = pd.read_csv(StringIO(response.body.decode('utf-8')), index_col=False) + cases_past_7_days = df.loc[df['Name'] == country_name]['Cases - newly reported in last 7 days'] + return self.finish(str(cases_past_7_days.values[0])) + def make_app( debug: bool = False, @@ -317,6 +351,7 @@ def make_app( (calculator_prefix + r'/baseline-model/result', StaticModel), (calculator_prefix + r'/user-guide', ReadmeHandler), (calculator_prefix + r'/api/arve/v1/(.*)/(.*)', ArveData), + (calculator_prefix + r'/cases/(.*)', CasesData), (calculator_prefix + r'/static/(.*)', StaticFileHandler, {'path': calculator_static_dir}), ] From 1a9343998462dea4ab63d86732a0c7cd79197945 Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Wed, 12 Oct 2022 16:49:42 +0200 Subject: [PATCH 2/5] added incidence rate from API to UI --- caimira/apps/calculator/static/js/form.js | 19 +++++++++++++++++++ .../templates/base/calculator.form.html.j2 | 9 +++++++-- setup.py | 1 + 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/caimira/apps/calculator/static/js/form.js b/caimira/apps/calculator/static/js/form.js index 86c23880..300f54ce 100644 --- a/caimira/apps/calculator/static/js/form.js +++ b/caimira/apps/calculator/static/js/form.js @@ -418,6 +418,19 @@ function show_sensors_data(url) { } }; +function geographic_cases(location_country_name) { + $.ajax({ + url: `${$('#url_prefix').data().calculator_prefix}/cases/${location_country_name}`, + type: 'GET', + success: function (result) { + $('#geographic_cases').val(result); + }, + error: function(_, _, errorThrown) { + console.log(errorThrown); + } + }); +} + $("#sensors").change(function (el) { sensor_id = DATA_FROM_SENSORS.findIndex(function(sensor) { return sensor.RoomId == el.target.value @@ -930,6 +943,9 @@ $(document).ready(function () { } } + // Update geographic_cases + geographic_cases('CHE'); + // When the document is ready, deal with the fact that we may be here // as a result of a forward/back browser action. If that is the case, update // the visibility of some of our inputs. @@ -1120,9 +1136,12 @@ $(document).ready(function () { success: function (locations) { // If there isn't precisely one result something is very wrong. geocoded_loc = locations.candidates[0]; + $('input[name="location_name"]').val(selectedSuggestion.text); $('input[name="location_latitude"]').val(geocoded_loc.location.y.toPrecision(7)); $('input[name="location_longitude"]').val(geocoded_loc.location.x.toPrecision(7)); + // Update geographic_cases + geographic_cases(geocoded_loc.attributes['country']); } }); diff --git a/caimira/apps/templates/base/calculator.form.html.j2 b/caimira/apps/templates/base/calculator.form.html.j2 index 5959d555..711736bd 100644 --- a/caimira/apps/templates/base/calculator.form.html.j2 +++ b/caimira/apps/templates/base/calculator.form.html.j2 @@ -386,8 +386,13 @@
-
-
+
+
+ + + Source: World Health Organization. + +
diff --git a/setup.py b/setup.py index c0f292d6..242d662d 100644 --- a/setup.py +++ b/setup.py @@ -28,6 +28,7 @@ REQUIREMENTS: dict = { 'memoization', 'mistune', 'numpy', + 'pandas', 'psutil', 'python-dateutil', 'retry', From 5915a0d5201032cc337ea0ce4b9a0613220374a1 Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Thu, 13 Oct 2022 10:35:35 +0200 Subject: [PATCH 3/5] used 7-day rolling average --- caimira/apps/calculator/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/caimira/apps/calculator/__init__.py b/caimira/apps/calculator/__init__.py index 67357d11..f5ae5b91 100644 --- a/caimira/apps/calculator/__init__.py +++ b/caimira/apps/calculator/__init__.py @@ -318,7 +318,7 @@ class CasesData(BaseRequestHandler): country_name = json.loads(response.body)['name']['common'] # Get global incident rates - URL = 'https://covid19.who.int/WHO-COVID-19-global-table-data.csv' + URL = 'https://covid19.who.int/WHO-COVID-19-global-data.csv' try: response = await http_client.fetch(HTTPRequest( url=URL, @@ -329,8 +329,12 @@ class CasesData(BaseRequestHandler): print("Something went wrong: %s" % e) df = pd.read_csv(StringIO(response.body.decode('utf-8')), index_col=False) - cases_past_7_days = df.loc[df['Name'] == country_name]['Cases - newly reported in last 7 days'] - return self.finish(str(cases_past_7_days.values[0])) + cases = df.loc[df['Country'] == country_name] + # 7-day rolling average + current_date = str(datetime.datetime.now()).split(' ')[0] + eight_days_ago = str(datetime.datetime.now() - datetime.timedelta(days=7)).split(' ')[0] + cases = cases.set_index(['Date_reported']) + return self.finish(str(round(cases.loc[eight_days_ago:current_date]['New_cases'].mean()))) def make_app( From 2d909bc9051f433627a9149ccfa189c39a733ec2 Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Fri, 18 Nov 2022 11:39:20 +0100 Subject: [PATCH 4/5] Added a 0-value verification for geographical cases --- caimira/apps/calculator/__init__.py | 2 ++ caimira/apps/calculator/static/js/form.js | 1 + caimira/apps/templates/base/calculator.form.html.j2 | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/caimira/apps/calculator/__init__.py b/caimira/apps/calculator/__init__.py index f5ae5b91..3a61cd79 100644 --- a/caimira/apps/calculator/__init__.py +++ b/caimira/apps/calculator/__init__.py @@ -334,6 +334,8 @@ class CasesData(BaseRequestHandler): current_date = str(datetime.datetime.now()).split(' ')[0] eight_days_ago = str(datetime.datetime.now() - datetime.timedelta(days=7)).split(' ')[0] cases = cases.set_index(['Date_reported']) + # If any of the 'New_cases' is 0, it means the data is not updated. + if (cases.loc[eight_days_ago:current_date]['New_cases'] == 0).any(): return self.finish('') return self.finish(str(round(cases.loc[eight_days_ago:current_date]['New_cases'].mean()))) diff --git a/caimira/apps/calculator/static/js/form.js b/caimira/apps/calculator/static/js/form.js index 300f54ce..48bca724 100644 --- a/caimira/apps/calculator/static/js/form.js +++ b/caimira/apps/calculator/static/js/form.js @@ -424,6 +424,7 @@ function geographic_cases(location_country_name) { type: 'GET', success: function (result) { $('#geographic_cases').val(result); + result != '' ? $('#source_geographic_cases').show() : $('#source_geographic_cases').hide(); }, error: function(_, _, errorThrown) { console.log(errorThrown); diff --git a/caimira/apps/templates/base/calculator.form.html.j2 b/caimira/apps/templates/base/calculator.form.html.j2 index 711736bd..de520fa2 100644 --- a/caimira/apps/templates/base/calculator.form.html.j2 +++ b/caimira/apps/templates/base/calculator.form.html.j2 @@ -387,9 +387,9 @@
-
+
- +
From 1cbc1d111364d76bb13b03eb56652f2deafb1476 Mon Sep 17 00:00:00 2001 From: Luis Aleixo Date: Tue, 29 Nov 2022 16:50:54 +0100 Subject: [PATCH 5/5] handle WHO message when input changes by user --- caimira/apps/calculator/static/js/form.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/caimira/apps/calculator/static/js/form.js b/caimira/apps/calculator/static/js/form.js index 48bca724..a88c5ccc 100644 --- a/caimira/apps/calculator/static/js/form.js +++ b/caimira/apps/calculator/static/js/form.js @@ -946,6 +946,9 @@ $(document).ready(function () { // Update geographic_cases geographic_cases('CHE'); + + // Handle WHO source message if geographic_cases pre-defined value is modified by user + $('#geographic_cases').change(() => $('#source_geographic_cases').hide()); // When the document is ready, deal with the fact that we may be here // as a result of a forward/back browser action. If that is the case, update