10月にNHKハッカソン 防災編に参加しました。
ハッカソン自体への参加がはじめてでした(多分)。イベント自体は、いろいろな方が参加されており、アイデアを聞いているだけでも楽しめました。
一応手も動かしたいということで、チームで作った「災害の学習に役立つNHKコンテンツのCSVファイル」を使って、それをランダムに返すアプリを作成しました。
イベントは様々な方と作業ができて、凄い楽しかったです。この記事は、参加記録兼作ったもののメモです(遅いけどw。
概観
--- 開発環境 ---
WSL2
python 3.8.10
dash 2.6.2
flask 2.2.2
--------
アプリの構造的にはFlaskでランダムにニュースのURLを返すAPIを作って、それをDashで描画します。
DashはPythonのReactラッパーみたいな存在で、お手軽に使えるので、使いました。
アプリはヘロクの無料枠で動いており、11月28日に動かなくなる見込みです。
https://nhk-hackathon-front.herokuapp.com/
API
APIはFlaskを使って作りました。普段はデータ分析ばかりしているので、あまりAPIとか作りませんが、Flaskはちょっと触ったことがあったので、簡単に作成できました。
コードとデータはリンク先のリポジトリに置いてあります。今見たらvenvディレクトリが入りっぱなし。修正しておきます。
https://github.com/mazarimono/nhk-hackathon
ここでは、dataディレクトリにnhk-news.csvを置いています。
そのファイルをpandasを使って読み込み、データフレームの列数を数えたあと、ランダムな数値を生成し、ニュースのタイトルとURLを返します。
from flask import Flask
import pandas as pd
import random
@app.route('/api/v0/news/random_news')
def return_randomnews():
df = pd.read_csv('data/nhk-news.csv')
random_int = random.randrange(0, len(df))
rand_df = df.iloc[random_int, :]
news_title = rand_df.loc['タイトル']
news_url = rand_df.loc['URL']
return {
'news_title': news_title,
'news_url': news_url
}
フロント
フロントでは、Dashのコールバックで先ほど作成したAPIを叩いてニュースのリンクを呼び出して描画しています。
工夫した点はボタンのn_clicks属性の初期値を1にしたうえで、コールバックがn_clicks>0で動作するようにした点です。これによりアプリの立ち上がりでもAPIを叩いて、ニュースのリンクが表示されます。
コールバックでは、ボタンが押されるとAPIを叩き、記事のリンクとURLを返します。
再度ボタンが押されると、次のニュースが呼び出されます。
https://github.com/mazarimono/nhk-randomnews
from dash import Dash, html, Input, Output
import dash_bootstrap_components as dbc
import requests
app = Dash(
"__name__",
external_stylesheets=[dbc.themes.BOOTSTRAP],
meta_tags=[
{"name": "viewport", "content": "width=device-width, initial-scale=1"},
],
)
server = app.server
app.layout = html.Div(
[
html.Div(
[
html.H1("おススメNHK防災コンテンツ", style={"padding": 10}),
html.H3(id="selected_title"),
html.A(id="selected_link"),
]
),
html.Div(
[dbc.Button(id="update_button", children="ニュース更新ボタン", n_clicks=1)],
style={"padding": 30},
),
html.Div(
[
dbc.Accordion(
[
dbc.AccordionItem(
[html.P("このサイトは防災について学べるおススメ記事のリンクを、ランダムにおススメします")],
title="サイトの説明",
)
],
start_collapsed=True,
style={"width": "80%", "margin": "auto"},
),
]
),
],
style={"textAlign": "center", "padding": 10},
)
@app.callback(
Output("selected_title", "children"),
Output("selected_link", "href"),
Output("selected_link", "children"),
Input("update_button", "n_clicks"),
)
def update_news(n_clicks):
if n_clicks > 0:
r = requests.get("https://nhk-hackathon.herokuapp.com/api/v0/news/random_news")
news_title = r.json()["news_title"]
news_url = r.json()["news_url"]
return news_title, news_url, news_url
else:
pass
if __name__ == "__main__":
app.run_server(debug=True)
まとめ
以上のようなアプリを作って、NHKさんの防災に役立つ記事が読めるアプリを作成してみました。NHKさんにはたくさんのアセットがあるそうなので、APIとか作られると色々楽しそうですね!
私はこのアプリを使って、CSVファイルにある記事をたまに読んで、防災学習をしています。
最後に、ハッカソンの開催ありがとうございました!
csvをランダムに吐き出すのはDashのみでもできるのですが、チームのアプリでこのような機能を使いたかったのでAPIを作成しました。このアプリでもそのAPIを使ったらええやんと思い、こんかいのようなかたちとなっております。