🤖

Flaskで個人開発したツール系Webサービスの技術スタック

2021/02/05に公開

はじめに

個人開発で日記のWebサービスをリリースしました。ツール系のサービスとしてOAuth認証からStripe課金までひととおり実装したので、個人的には多くの技術的知見を得られました。ここでは一つの技術を深追いせず、利用したライブラリ等についてざっと紹介したいと思います。PythonでWeb開発を行う方やこれからの方も含めて、他の開発者がどのようなライブラリ等を選定してるのか参考になれば幸いです。

サービスの概要

日記をカテゴリごとに登録し、グラフで可視化することで振り返りを促すサービスとなります。
image_calendar
image_plot
https://dekigoto.herokuapp.com/
サービスに含まれる機能とその目的を大まかにリストアップします。

  • OAuthでSNS認証することでユーザーに煩わしいパスワードの管理をさせないこと
  • PC・スマホを問わずどの端末からでも参照・登録できるよう、ブラウザのサイズを問わないレスポンシブ対応とすること
  • 日記をグラフで可視化することで、ユーザーに日記を継続するモチベーションとしてもらうこと
  • 多言語対応で様々なユーザーにアプローチすること
  • 課金機能でマネタイズできる仕組みを作り、自分自身に対してもモチベーションとすること

使ったライブラリ等

以下に説明します。具体的な実装についてはGitHubレポジトリを参考ください。
https://github.com/ShinyaMoriyama/dekigotodiary

Flask

PythonでWeb開発を行う場合、大規模な場合の多くはDjangoが選ばれますが、今回は個人開発で行うこともあり、軽量なフレームワークとしてメジャーなFlaskを選びました。Flaskであれば追加で欲しくなった機能をライブラリ等で拡張できるので、「好きな技術を自分自身で選べる」という個人開発の趣向とも一致していると思います。

Flask-Dance

https://flask-dance.readthedocs.io/en/latest/
OAuth認証のライブラリです。SNSごとの実装例が紹介されており「これなら出来そう」と思ったので選びました。Flask-Danceでサポートする実装の流れは次のとおりです。

  1. 利用するSNSをFlaskに登録しておく
  2. ユーザーがリクエストする際に認証済か否かをチェックする
  3. 認証が済んでいなければ上記で登録済のSNSごとのURLへ遷移する
  4. ユーザーはSNSで認証を行い成功すればサービスのURLに遷移する

ちなみにユーザーはどのURLからサービスにアクセスするかは分からないので、ほぼすべてのURL共通の前処理としてユーザーの認証チェックを行うことにしました。

@main.before_app_request # Flaskが提供する共通の前処理
def before_request():
    '''
    triggered before executing all view functions
    '''
    if current_user.is_authenticated:
        return # 認証済であれば前処理を抜けてそれぞれのリクエストへ
    return redirect(url_for('main.login')) # 認証なしの場合ログイン画面へ

Flask-Bootstrap

ブラウザをレスポンシブ対応するためBootstrapを選びました。
https://getbootstrap.com/
FlaskからBootstrapを利用する場合、BootstrapをincludeしHTMLを作りやすくしてくれるライブラリがFlask-Bootstrapです。
https://pythonhosted.org/Flask-Bootstrap/
少し残念なのはFlask-BootstrapがBootstrap V3.3.7のサポートで止まっていることです。Bootstrapは執筆時点(2021年2月)でV5がリリースされています。この差を埋めるためにはFlask-Bootstrapを使わずにBootstrapのTutorialを参照して独自に実装するか、必要な部分だけ最新のCSS等のコンポーネントをダウンロードする方法です。ちなみにSNSのアイコンはV3.3.7では存在しなかったため、自分はFont Awesomeから利用することとしました。Bootstrap V5には最低限ですがSNSのアイコンはあります。

以下のアイコンがFont Awesomeから利用しているものです。

Font Awesomeについては以下の記事で触れました。
https://zenn.dev/morisin/articles/8a77f1c9c4d37343b749

FullCalendar

JavaScriptのカレンダーライブラリです。このライブラリの制約は表示機能のサポートが中心となるので、登録は別途実装する必要があります。ただ無料枠でも月間スケジュールやリスト表示をはじめ様々な表示形態に対応しているので、用途を限定すれば非常に便利なライブラリと言えます。
https://fullcalendar.io/
こちらに別途まとめたのでよかったら参考にしてください。
https://zenn.dev/morisin/articles/70763c73ab2b162aecbd

Plotly

https://plotly.com/python/
グラフの実装は機械学習の分野でメジャーなPlotlyを使いました。PlotlyはPython版だけでなくJavaScript版も提供されているため、バックエンドの言語を問わずWebサービスにおいて幅広く使えると思います。Plotlyの特徴としてはインタラクティブな表示で、プロット領域の拡大やマウスホバーでの値の表示、画像の保存等の機能があらかじめ提供されていることです。

Flask-Babel

多言語対応はFlask-Babelを利用しています。ここでは分かりやすく利用方法をまとめてくれているMiguelのBlogを紹介します。
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xiii-i18n-and-l10n
基本的な利用方法は、事前準備を除くと次のとおりです。

  1. 翻訳したい文字列を指定されたFunction_()または_l()でラッピングする
  2. 言語ごとのコマンド実行flask translate init ja(日本語の場合)で辞書定義ファイル(messages.mo)を作成する
  3. 辞書定義ファイル(messages.mo)を編集する
  4. flask translate compileで実行時の参照バイナリファイル(messages.po)を作る

2回め以降の翻訳、つまり辞書定義ファイル(messages.mo)を更新する場合はコマンドflask translate initの代わりにflask translate update(言語の種類不問)で辞書定義ファイル(messages.mo)を更新します。

Stripe

決済手数料は執筆時点(2021年2月)で3.6%と、スマホアプリの手数料と比べると非常に安価です。この手数料の差が、個人開発でWebサービスを開発しようとするモチベーションの一つになっています。実装のためのTutorialは非常に充実していますが、それがゆえに迷うこともあるかと思います。自分はサブスクリプションモデルを実装したのでこれについて簡単に学習フローを説明します。
まずは下記Documentを読み大まかな流れを掴みます。ところがStripe専門や決済関連の用語が多数あり、自分を含め決済サービス実装が初めての方は具体的なイメージが掴みづらいかもしれません。
https://stripe.com/docs/billing/subscriptions/checkout
そこで上記からもリンクされているのですが、GitHubのリポジトリからCloneを作りLocal環境から動作確認することをおすすめします。
https://github.com/stripe-samples/checkout-single-subscription
ここで紹介されているPythonモジュールはFlask製であることもあり、自分の場合はこれでようやく理解することできました。基本的にはこのリポジトリの内容をカスタマイズして自分のサービスに取り込んでいくと比較的スムーズに実装できるのかなと思います。

Heroku

リリース環境はHerokuとしました。Herokuではサブドメイン割当とデータベース10,000件までが無料で利用できるため、低コストでランニングしたい個人開発の用途としては理にかなっています。Herokuの無料枠の欠点は30分ごとにサービスが非活性となることですが、運用監視ツール等で外から定期的にアクセスすることで問題なくサービス継続できるようになります。自分が利用しているのはUptimeRobotで、最短5分間隔のアクセスまでは無料です。スマホアプリも用意されておりUIがシンプルで使いやすいです。
https://uptimerobot.com/

favicon.io & Adobe Stock

最後に無料素材として利用しておすすめできるものを紹介します。
favicon.io: 無料のFavicon作成サービスでユーザー登録も不要
https://favicon.io
Adobe Stock: 無料で多くの画像が利用でき、デザイン向上には必須
https://stock.adobe.com/jp/

まとめ

以上、ざっくりと利用したライブラリ等について紹介しました。Flaskで実装することのメリットは、自分自身でライブラリを選定できること、そして必要なもののみ追加していけるというシンプルな進め方が出来ることです。ライブラリ等を自由に選定できるのは個人開発の醍醐味であり、Flaskは目的に沿った最適な選択と考えられます。またWebサービスとして運用できることは手数料などサービス提供者としてのメリットもありますので、個人開発としてこの選択肢を考えてもらえると面白いはずです。最後に、あらためて日記サービスのリンクです。興味のある方はぜひ試してください。
https://dekigoto.herokuapp.com/

Discussion