Pythonだけでwebアプリを開発（Streamlit, FastAPI）

# はじめに
web開発の学習のアウトプットとしてwebアプリを作成しました。
開発の詳細について記していこうと思います！

### 目次
[1. アプリの概要](#1アプリの概要)
[2. アプリを作ったきっかけ](#2アプリを作ったきっかけ)
[3. 課題点](#3課題点)
[4. アプリの機能](#4アプリの機能)
[5. 使用技術](#5使用技術)
[6. こだわったところ](#6こだわったところ)
[7. 大変だったところ・詰まったところ](#7大変だったところ・詰まったところ)
[8. アプリ開発による効果](#8アプリ開発による効果)
[9. 追加したい機能・改善点](#8追加したい機能・改善点)
[10. 最後に](#9最後に)


# 1.アプリの概要
従業員の出退勤を管理する勤怠管理アプリです。 

 **タイムカード+エクセルにデータを手入力** で勤怠管理を行なっている場合、このアプリを導入することで
- 各従業員の出勤・退勤時刻の記録
- 各従業員の勤務時間、給与管理  

をアプリ内で一元管理することができます。  

それにより、**今までの煩雑な作業を全て自動化**させて勤怠管理にかかっていた**時間・コスト削減を実現**することができます。

想定ユーザーは店長と従業員です。

### GitHubレポジトリ

https://github.com/kizataka/attendance-management/tree/main

開発期間は2週間程度でした。

### サイトイメージ
| 勤怠入力画面 |　勤怠管理画面（検索フォーム） |
| ---- | ---- |
| ![input_screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741553/a4e62140-e7f4-befd-03ca-7c5c98f8dd2e.png) | ![management_screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741553/73a0de49-e10b-5ee7-ad4a-cb8379ecd965.png) |
| 各従業員の出退勤時刻を記録する打刻機能を実装しました | 各従業員の勤務データを日付で絞り込み検索できる機能を実装しました |

| 勤怠管理画面（検索結果表示） |　従業員登録画面 |
| ---- | ---- |
| ![management_screen_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741553/1a68b5b9-4722-0497-5166-310c57af5b7e.png) | ![registration_screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741553/09e1ffcb-1dfe-f2ee-875d-6dd178fc2761.png) |
| 各従業員の勤務データを表形式で表示する機能を実装しました | 勤怠管理に用いる各従業員のデータを登録する機能を実装しました |

# 2.アプリを作ったきっかけ
自分が働いているバイト先では出勤時間の打刻などの勤怠管理をタイムカードとエクセルで管理していました。店長が勤怠管理の作業にかなり時間を費やしていて大変そうだったので解決できないかと思い、このアプリを作ることにしました。

# 3.課題点
アプリを作成するにあたってまずは勤怠管理作業の現状を把握し、何が課題なのかを特定してからどのような機能を実装するかを考えました。

課題についてはGitHubのREADMEに詳細に書いているのでそちらを見ていただけると助かります。

一言で言うと、タイムカードに記録されたデータを再度エクセルに入力する作業が時間を要している原因で、最大の課題でした。

従業員がアプリ上で出退勤時に打刻し、それをデータベースで保存すれば勤怠データが記録されて手入力の手間が省けると考えました。

例えば、従業員一人の1日の出退勤時刻をエクセルに入力する時間を仮に**5秒**だとすると、
1ヶ月30日と仮定した際に、1ヶ月分のデータを入力するのに**150秒**、つまり**2.5分**かかります。
従業員が10名いるとすると、データ入力だけで**25分**かかる計算になります。この時間を短くするのが目的でした。

# 4.アプリの機能
◆ ユーザー登録機能
- 各従業員データの登録、削除

◆ 打刻機能
- 出勤時刻、退勤時刻の記録

◆ 勤務データの検索・取得機能
- 各従業員の勤務実績(勤務日数、給与)の表示
- 指定された日時の勤務データを表形式で表示

◆ 勤務データのエクセルファイル化機能
- 表形式で表示した勤務データをエクセルファイルとしてダウンロード

# 5.使用技術
### フレームワークについて
今回のアプリではバックエンドにpythonの**FastAPI**、フロントエンドにpythonの**Streamlit**を使用しています。
#### FastAPIを選択した理由について
- Pythonでコードを書きたい
- 型定義ができる
- APIドキュメントが自動生成される

正直なところ、自分はプログラミング経験が浅くPythonしか勉強したことがなかったため、まずはアプリを動かすことが最優先だったこともあり慣れているPythonのフレームワークを使用することにしました。

また、型定義ができることやドキュメントの自動生成はPythonの他のフレームワークであるDjangoやFlaskなどにはない機能で、開発経験が少ない自分にとって効率的にAPI開発ができるところが魅力だと感じました。

#### Streamlitを選択した理由について
- 直感的かつ容易にフロントエンド開発ができる

デザインにこだわりはなく、シンプルなUIができれば十分だと考えていました。Pythonを数行書くだけで簡単に整ったフロントエンドを実装でき、素晴らしい技術だなと実感しました。

ただ良くも悪くもレイアウトが定まっておりデザインの拡張性がないため、UIに力を入れるのであればJavaScriptを用いたほうがいいなと思いました。

また、Streamlitの特性上、ユーザーが操作するたびに処理全体が最初から再実行されてしまうため処理に時間がかかってしまうので、大規模サービスにはReactなど他の技術で作成すべきだと感じました。

バイト先の従業員数は数十名程度なので問題ないですが、今後従業員数や勤務データが増えた場合には対策を考える必要があります。

### DBについて
データベースは**SQLite**を使用しています。

#### SQLiteを選択した理由について
- 今回のwebアプリのユーザー数が限られている
- 他のDBに比べて設定が簡単

サーバーを用いないのでサクッと利用できるところが魅力に感じました。また、バイト先のみで利用するため、大量のユーザー数は考えにくいので小規模アプリケーションに向いているSQLiteを選択しました。

### 開発環境について
Pythonのパッケージ管理ツールである**Poetry**を使用しました。

フロントエンドもバックエンドも全てPythonで実装しているため、Poetryを用いてパッケージの管理と仮想環境の構築を行いました。

# 6.こだわったところ
- **タイムカードで打刻していた時と同じような操作になるようにユーザー（従業員）の操作を設計したこと**

今まで従業員は

**自分のタイムカードを取る → タイムカードをタイムレコーダーに通して打刻**

という二段階の操作で出退勤時刻を打刻していました。
よって、今回のアプリ上でも

**ユーザー選択 → 出勤・退勤ボタンを押す**

のように今までの操作と同じような設計にして使いやすいようにしました。

こだわった理由としては、従業員にはパソコン操作に慣れていない方も多く、そのような方でも簡単に使えるものにしたいと思ったからです。なるべくやり方を大きく変えず、かつシンプルに使えるように意識しました。


# 7.大変だったところ・詰まったところ
出勤・退勤ボタンの実装に苦労しました。

要因としてはCRUD処理についての理解が乏しかったことです。

勤務時間の計算を簡単にするためにも、DBの同じ日付の行に出勤時刻と退勤時刻を記録したいと考えていました。

当初は出勤・退勤ボタンを押すたびにデータをCreateしてしまっており、同じ日付のデータが二つ並ぶ状態になっていました。

もう一度CRUD処理について調べ、Updateの機能について学習することでうまく実装できました。

基本的なところで詰まってしまいましたが、CRUD処理の理解が深まりました。

# 8.アプリ開発による効果
完全に運用するにはまだまだ不完全ですが、従業員登録機能をつけて従業員ごとにデータを保存するようにしたことで今までの管理者の作業を全て自動化することができました。

つまり、アプリ導入により勤怠管理作業に要していた時間を**25分 → 0分**にする効果が見込めそうです。

運用実績はまだないですが、アプリ開発による時間短縮の効果は十分に見込めることがわかりました。


# 9.追加したい機能・改善点
- **認証機能**

バイト先の従業員の個人情報が含まれているのでログイン機能を設けてセキュリティを強化する必要があります。
FastAPIのOAuth2による認証機能、またはFirebase Authenticationを用いて実装できればいいなと考えています。  


- **出退勤時刻の編集機能**

現状、誤って出退勤ボタンを押してしまうとその誤った時刻のまま勤務データに保存されてしまいます。
CRUD処理の更新機能で時刻の編集ができるようにしていきたいです。

# 10.最後に
今回のアプリ開発を通して、見やすくて使いやすいUIにするにはどうすればいいか、DBの操作はどう工夫すればいいか、デプロイ後の動作の確認の必要性などたくさんのことを学ぶことができました。

学習する上で実際に何か作ってみることの重要性を再度実感しました。

難しいことだらけでしたが実装する中で自分が思った通りに動いた時は純粋に嬉しかったし、この機能をつけるにはあの技術が必要になってくるんだなという好奇心や学びも深まってとても楽しかったです。

何かしら参考になれば幸いです！