Docker、Python、IoT による世界のワクチン接種率の追跡

世界のワクチン接種率 Docker

私は、低電力、低コストのWi-Fi対応マイクロコントローラーのESP32-S2プラットフォームの大ファンです。 Adafruitは、 MagTagと呼ばれる2.9フィートのEインクディスプレイとPythonサポートを備えたバリアントを具体的に販売しています。 私は自分のアパート全体に散らばっているこれらのものがあまりにも多くあることを認めることを恥じていません。

私のお気に入りの組織の1つは、 データの世界(OWID)です。 彼らは何千人もの研究者と協力して、研究とデータを一般に公開しています。 特に、私はCOVIDワクチン接種率を追跡する 彼らのレポ を注意深く見守っています。 世界中の多くの機関がワクチン接種率の指標を更新すると、OWID はそのデータを 1 つの JSON ファイルに統合します。

MagTagとOWIDのデータセットの組み合わせは、DockerのDevRelチームの最新メンバーとしての最初のプロジェクトに影響を与えました。 私はMagTagを私がフォローしている特定のOWIDのディスプレイに変えることにしました。 しかし、私は始めている間にいくつかの問題に遭遇しました。

OWID は、JSON データ コレクションを API エンドポイント経由で提供するのではなく、生の JSON (または CSV) ファイルとして GitHub にアップロードします。 合計ペイロードも34MBです。 それは巨大ではないようですが、MagTag自体には4MBのフラッシュストレージと2MBのPSRamしかありません。 これは、そのすべてのデータを解析するのに十分なメモリにはほど遠いです。 幸いなことに、私はデータ処理レイヤーを作成するためにいくつかの予備のRaspberryPiを指揮しました。 Python を使用すると、イメージを処理するための迅速な Flask サーバーを起動することができ、Docker のおかげで、コンテナー化されたサービスをわずか数秒で Raspberry Pi にデプロイできます。

私のPiは、Docker HubからArmv7用に構築されたイメージをプルします。 そのコンテナーは、ローカル ネットワーク上でアクセス可能な API エンドポイントを作成します。 そこから、MagTagはPiに国のデータを要求できます。 Pi は OWID から最新の JSON ファイルを取得し、MagTag が探している情報だけを取り出し、それを渡します。 この方法により、データペイロードが34MBからKB範囲に削減され、IoTデバイスにとってはるかに管理しやすくなります。

そうは言っても、コードに飛び込みましょう。

ソリューションのコーディング

コードを読むだけの場合は、 GitHub または Docker Hub にアクセスしてデプロイ手順を確認してください。

データ処理

Raspberry Pi のデータ処理関数がかなり軽量であることを知っていたので、jsonify で JSON を処理する Flask の組み込み機能を利用して、Flask サーバーを立ち上げることにしました。 OWIDからデータを取得するためのリクエストライブラリも非常に便利でした。

1
2
3
from flask import Flask, jsonify
import requests
app = Flask(__name__)

このプロジェクトでは、2つのルートのみが必要です。 API がオンラインであることを確認するためのヘルスチェックとして機能するもの。

1
2
3
4
5
6
7
# Setup a health route to check if the service is up
@app.route("/")
@app.route("/health")
def hello():
response = jsonify({"status": "api online"})
response.status_code = 200
return response

次に、さらに重要なのは、OWID データセットに到達するためのルートです。 このルートは、要求された ISO コードの 34MB の JSON ファイルを解析し、最新のデータを取得して、ラズベリーパイ用にフォーマットします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Setup a GET route for requesting the data of the requested ISO Code.
@app.route("/iso_data/<iso>", methods=["GET"])
def iso_data(iso):
# Get the OWID Data from GitHub
try:
vaccinations = requests.get(vaccination_url)
except:
return "False"
vaccinations_dict = {}
# Using lambda and filter to find our requested ISO Code
item = list(filter(lambda x: x["iso_code"] == iso, vaccinations.json()))
if item:
item = item[0]
# If data is found format it for our response.
vaccinations_dict = {
"data": item["data"][-1],
"iso_code": item["iso_code"].replace("OWID_", " "),
"country": item["country"],
}
response = jsonify(vaccinations_dict)
# Returning a 203 since it's a mirror of the OWID data.
response.status_code = 203
else:
# If no data is found return a 404.
response = jsonify(
{"status": 404, "error": "not found", "message": "invalid iso code"}
)
response.status_code = 404
return response

最後に、依存関係をインストールし、要件ファイルを生成するコードを取得する必要があります。 私はPython仮想環境を管理するために pyenv を使用していますが、あなたはそれをあなたの好みの方法に置き換えます。

1
2
3
4
5
pyenv virtualenv 3.10.1 flask-owid-server
pyenv activate flask-owid-server
pip install flask requests
pip freeze > requirements.txt
flask run
世界のワクチン接種率Dockerスクリーンショット

次に、新しいシェルプロンプトを開き、Flaskサーバーにcurlリクエストを送信して、すべてが期待どおりに実行されていることを確認します。

1
2
curl localhost:5000
curl localhost:5000/iso_data/USA
世界のワクチン接種率Dockerスクリーンショット

Flask サーバーのドッキングとデプロイ

機能的なFlaskサーバーを使用すると、それをドッキングし、RaspberryPiのアプリ展開プロセスを簡素化できます。 私はドッカーファイルを作成することから始めました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#Use the python 3 base image.
FROM python:3-slim
#Expose ports
EXPOSE 5000
# Setup work directory.
WORKDIR /app
# Copy the requirements file to the container and the install dependencies.
COPY requirements.txt /app
RUN pip3 install -r requirements.txt --no-cache-dir
# Copy all the code into the container/
COPY . /app
# Spin up our flask server.
ENTRYPOINT ["python3"]
CMD ["app.py"]

この Dockerfile を配置したら、Docker ビルド コマンドを実行してイメージを作成できます。

1
docker build --tag {yourdockerusernamehere}/flask-owid-parser:latest .
世界のワクチン接種率Dockerスクリーンショット

新しく作成したイメージを Docker Desktop から実行しながら、コンテナーに名前を付け、ローカル ポートを 5000 に設定することができます。

世界のワクチン接種率Dockerスクリーンショット
世界のワクチン接種率Dockerスクリーンショット
世界のワクチン接種率Dockerスクリーンショット

コマンドラインを使用したい場合は、Docker CLIのようなもので同じ効果が得られます。

1
docker container run --publish 5000:5000 --detach --name flask-owid-parser {yourdockerusernamehere}/flask-owid-parser
世界のワクチン接種率Dockerスクリーンショット

もう一度、localhost:5000 に curl 要求を行い、すべてが正しく実行されていることを確認します。

マシンですべてが検証されたら、RaspberryPiで実行するアプリケーションを構築できます。 この例の Raspberry Pi 3 モデル B は armv7 プラットフォームを使用しているため、armv7 をターゲットにしたビルドを作成できます。 このビルドを私のMacBookで実行することで、ビルド時間は私のラズベリーパイよりも大幅に速くなります。

1
docker build --platform linux/arm/v7 -t {yourdockerusernamehere}/flask-owid-parser:armv7 .
世界のワクチン接種率Dockerスクリーンショット

Docker デスクトップに戻ると、armv7 ビルドを Docker Hub にプッシュできます。

世界のワクチン接種率Dockerスクリーンショット

Docker Hubにアクセスして、armv7ビルドが正しく表示されることを確認します。

世界のワクチン接種率Dockerスクリーンショット

ラズベリーパイにSSHで接続して、このコードのデプロイを開始します。 Docker をまだインストールしていない場合は、Pi で Docker の使用を開始する手順については、 ドキュメントを参照してください 。

次に、Docker Hub から armv7 イメージをプルし、Raspberry Pi で実行します。

1
2
docker pull {yourdockerusernamehere}/flask-owid-parser:armv7
docker run -d -p 5000:5000 --name flask-owid-parser shyruparel/flask-owid-parser:armv7
世界のワクチン接種率Dockerスクリーンショット

オリジナルのMacBookに戻ると、最後の1つのcurlリクエストを介して、サーバーが実行中であることと、ローカルネットワークからアクセス可能であることの両方を確認できます。 Raspberry Pi OS の新規インストール時のデフォルトのホスト名は raspberrypiであるため、Pi OS を実行しているすべての Raspberry Pi は自動的に に応答します raspberrypi.local。 それでも問題が解決しない場合は、ラズベリーパイのIPアドレスと交換 raspberrypi.local してください。

1
2
3
ping -c 3 raspberrypi.local
curl raspberrypi.local:5000
curl raspberrypi.local:5000/iso_data/USA
世界のワクチン接種率Dockerスクリーンショット

マグタグの設定

私のお気に入りのMagTag機能の1つは、サーキットPythonのサポートです。 依存関係のインストールに使用するのを忘れてください pip 。 代わりに、単にコピー .mpy してください あなたのコードと一緒にUSB経由でマグタグに。 初めてMagTagをセットアップするために、私はAdafruitの人々によってまとめられた 優れたチュートリアル に任せます。

このプロジェクトを MagTag にインストールするには、このプロジェクトのコードを含む GitHub リポジトリ にアクセスします。 すべてのコードを MagTag ディレクトリから USB 経由で MagTag にドラッグします。

世界のワクチン接種率Dockerスクリーンショット

code.py を調べると ファイルを作成すると、MagTagがラズベリーパイに接続するように構成されていることがわかります。

1
2
3
4
# Build our endpoint
endpoint_iso_first = "http://raspberrypi.local:5000/iso_data/{}".format(
secrets["iso_first"]
)

secrets.py を更新する ファイルを使用して、独自のWifiネットワークの情報を含めます。 MagTagとRaspberry Piが同じネットワークを共有していることを確認してください。

MagTagを再起動して、Our World in Dataの人々が投稿した最新情報を確認します。

世界のワクチン接種率Dockerスクリーンショット

GitHub にアクセスして、依存関係を含むこのプロジェクトの完全なソース コードと、Docker Hub 上のイメージへのリンクを見つけてください。初めての Python および Docker ユーザーは、Python 開発者向けの クイック スタート チュートリアル を参照する必要があります。

略歴:シャイ・ルパレルは、Dockerのシニア開発者アドボケイトです。 彼はほぼ10年間、開発者コミュニティのエンパワーメントに取り組んできました。 彼は愚かなIoTプロジェクト、良いジョーク、そして毎日Twitterであなたに素晴らしい一日を願う持続力に情熱を持っています。

投稿カテゴリ