Making Of: Eine kostenlose API für COVID-19-Daten


Kürzlich nahmen einige Kollegen und ich am zweitägigen COVID-19-Hackathon #wirvsvirus, organisiert von der deutschen Bundesregierung, teil. Dabei haben wir eine großartige Anwendung zur Simulation von COVID-19-Kurven entwickelt – basierend auf Schätzungen zur Wirksamkeit staatlicher Maßnahmen – FlatCurver.
Da es bereits viele Dashboards und Visualisierungen rund um COVID-19 gibt, dachte ich zunächst, dass es ein Leichtes sei, die zugrunde liegenden Daten aus einer „Single Source of Truth“ zu beziehen. Doch schon bald stellte ich fest, dass es unzählige verschiedene Datenquellen gibt, die meist auf den COVID-19-Falldaten der Johns Hopkins University basieren.
Zuerst dachte ich: super! Doch bei genauerem Hinsehen musste ich meine anfängliche Begeisterung revidieren. Die JHU-Datensätze haben einige Eigenheiten, die ihre Aufbereitung und Analyse etwas mühsam machen:
- merkwürdige Spaltennamen, inklusive Sonderzeichen
- Länder und Bundesstaaten „wild gemischt“
- weites Format, recht unpraktisch für die Datenanalyse
- Importprobleme aufgrund von Zeilenumbrüchen
- usw.
Für alle, die bereits mit COVID-19-Zeitreihendaten arbeiten oder ihre Datenpipeline verbessern möchten, sei gesagt: Wir haben jetzt eine API dafür! Die API nutzt offizielle Daten vom European Centre for Disease Prevention and Control (ECDC) und liefert eine klare und gut strukturierte Datenbasis zur weiteren Verarbeitung und Analyse.
Überblick über unsere COVID-19 API
Unsere brandneue COVID-19-API bringt dir die aktuellen Fallzahlen-Zeitreihen direkt in deine Anwendung oder Analyse – unabhängig von deiner Entwicklungsumgebung. Zum Beispiel kannst du die Daten ganz einfach in Python importieren, etwa mit dem requests
-Paket:
import requests
import json
import pandas as pd
# POST to API
payload = {'country': 'Germany'} # or {'code': 'DE'}
URL = 'https://api.statworx.com/covid'
response = requests.post(url=URL, data=json.dumps(payload))
# Convert to data frame
df = pd.DataFrame.from_dict(json.loads(response.text))
Or if you’re an R aficionado, use httr
and jsonlite
to grab the lastest data and turn it into a cool plot.
library(httr)
library(dplyr)
library(jsonlite)
library(ggplot2)
# Post to API
payload <- list(code = "ALL")
response <- httr::POST(url = "https://api.statworx.com/covid",
body = toJSON(payload, auto_unbox = TRUE), encode = "json")
# Convert to data frame
content <- rawToChar(response$content)
df <- data.frame(fromJSON(content))
# Make a cool plot
df %>%
mutate(date = as.Date(date)) %>%
filter(cases_cum > 100) %>%
filter(code %in% c("US", "DE", "IT", "FR", "ES")) %>%
group_by(code) %>%
mutate(time = 1:n()) %>%
ggplot(., aes(x = time, y = cases_cum, color = code)) +
xlab("Days since 100 cases") + ylab("Cumulative cases") +
geom_line() + theme_minimal()

Die API mit Flask entwickeln
Die Entwicklung einer einfachen Webanwendung mit Python ist mithilfe von Flask unkompliziert. Flask ist ein Webframework für Python. Es ermöglicht dir, Webseiten, Webanwendungen usw. direkt in Python zu erstellen. Flask wird häufig zur Entwicklung von Webservices und APIs eingesetzt.
Eine einfache Flask-App sieht ungefähr so aus:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def handle_request():
""" This code gets executed """
return 'Your first Flask app!'
Im obigen Beispiel legt der app.route
-Decorator fest, bei welcher URL unsere Funktion ausgelöst werden soll. Du kannst mehrere Decorators angeben, um unterschiedliche Funktionen für verschiedene URLs auszulösen. Schau dir gerne unseren Code im GitHub-Repository an, um zu sehen, wie wir die API mit Flask aufgebaut haben.
Deployment mit Google Cloud Run
Die Entwicklung der API mit Flask ist unkompliziert. Der Aufbau der Infrastruktur und ergänzender Dienste rundherum kann jedoch – je nach spezifischen Anforderungen – herausfordernd sein. Einige Punkte, die du beim Deployment einer API berücksichtigen musst:
- Authentifizierung
- Sicherheit
- Skalierbarkeit
- Latenz
- Logging
- Konnektivität
Wir haben uns entschieden, Google Cloud Run zu verwenden – ein containerbasiertes serverloses Computing-Framework auf Google Cloud. Im Grunde ist GCR ein vollständig verwalteter Kubernetes-Dienst, der es dir ermöglicht, skalierbare Webservices oder andere serverlose Funktionen auf Basis deines Containers bereitzustellen.
So sieht unsere Dockerfile
aus:
# Use the official image as a parent image
FROM python:3.7
# Copy the file from your host to your current location
COPY ./main.py /app/main.py
COPY ./requirements.txt /app/requirements.txt
# Set the working directory
WORKDIR /app
# Run the command inside your image filesystem
RUN pip install -r requirements.txt
# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 80
# Run the specified command within the container.
CMD ["python", "main.py"]
Du kannst deinen Container lokal entwickeln und anschließend in die Container Registry deines GCP-Projekts hochladen. Dafür musst du dein lokales Image mit docker tag
nach folgendem Schema taggen: [HOSTNAME]/[PROJECT-ID]/[IMAGE]
. Der Hostname ist einer der folgenden: gcr.io
, us.gcr.io
, eu.gcr.io
, asia.gcr.io
.
Anschließend kannst du das Image mit gcloud push
, gefolgt von deinem Image-Tag, hochladen. Von dort aus lässt sich der Container ganz einfach mit dem Google Cloud Run-Dienst verbinden:

Beim Deployment des Dienstes kannst du Parameter für Skalierung usw. definieren. Dies fällt jedoch nicht in den Rahmen dieses Beitrags. Außerdem erlaubt GCR die Zuordnung benutzerdefinierter Domains zu Funktionen. Deshalb haben wir den praktischen API-Endpunkt https://api.statworx.com/covid.
Fazit
Das Erstellen und Bereitstellen eines Webservices ist heute einfacher denn je. Wir hoffen, dass unsere neue API für deine Projekte und Analysen rund um COVID-19 nützlich ist. Wenn du Fragen oder Anmerkungen hast, kontaktiere uns gerne oder eröffne ein Issue auf GitHub.
Abschließend: Wenn du unsere kostenlose API nutzt, füge bitte einen Link zu unserer Website https://statworx-1727.demosrv.dev in dein Projekt ein. Vielen Dank im Voraus – und bleib gesund!