💻

Streamlit と Mimesis で八百屋さん EC サイトを作ってみた

2022/04/28に公開

こんにちわ alivelimb です。
Pythonista の皆さん、こんな風に思ったことはないでしょうか?

  1. Flask や FastAPI を書いてるけど、HTML/JS/CSS を書くのが面倒
  2. データ分析や機械学習をやってるけど、デモをするのは jupyter では限界
  3. デモやテスト用にテストデータを毎回作るのが大変
  4. 人名や地名をそれっぽい値で自動生成したい

1,2 に当てはまる方はStreamlitが、3,4 に当てはまる方はMimesisをおすすめします。どちらも Python パッケージなのでpip installするだけで試すことが出来ます。今回はこれらのパッケージを使って、八百屋さん EC サイトを作ってみたので紹介したいと思います。

はじめに

本記事で紹介するソースコードはgithubで公開しています。

Streamlit, Mimesis の紹介記事は多くあるため、詳細はそちらに譲りますが概要だけ紹介です。

Streamlit とは?

Streamlit turns data scripts into shareable web apps in minutes. All in pure Python. No front‑end experience required.

公式の謳い文句をざっくり訳すと

  • データスクリプトを数分で共有可能な Web アプリにできる
  • 全て Python で書けてフロントエンドの知識は必要ない

データスクリプトというのはおそらくstrpandas.DataFrameなどでしょうか。データ分析ではお馴染みのDataFrameを雑に渡すだけでテーブル表示をしてくれます。flask や Django のように HTML を書く必要はなく、printを同じような書き方で Web 画面が出来るので、アプリエンジニアだけでなくデータサイエンティストなども簡単にデモアプリを作成できます。公式のGalleryを見るだけでも、Streamlit の魅力が実感できるでしょう。

私は React(Next.js)も多少書きますが、正直 Python ほど得意ではありません(コンポーネント設計が苦手)。当然 React を書く場合よりも小回りが効かないケースはあるため、本番運用レベルのアプリには向かないと思いますが、デモや検証用には十分です。Streamlit で試してユーザの反応が良ければ、本格的に開発する PoC にはもってこいだと思います。

Mimesis とは?

Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes in a variety of languages.

こちらも公式の謳い文句をざっくり訳すと

  • ハイパフォーマンスでダミーデータ生成ができる
  • 様々な言語に対応している

今回のようなデモアプリだけでなく、単体テストなどでもダミーデータが必要になる時があると思います。Mimesis は様々なケースのデータに対応しており、公式ドキュメントからいくつかピックアップすると、人名、会社名、文章、パスワードなどがあります。

なお、公式で言及されている通り、Mimesis は Object Factory ではありません。これはsqlalchemyのような ORM(Object Relational Mapper)と連携したオブジェクト生成ツールではないということです。Object Factory としてはfactory-boyが有名ですが、Mimesis と factory-boy を統合したmimesis-factoryもあるようです(こちらは試していません)。

なんで八百屋さん?

白状するとこの記事は「Mimesis ってのがあるんや」という発見が始まりで、ドキュメントを眺めていると「野菜名」を自動生成できることに気づきました。これに加えて、私が社会人 4 年目に突入したということもあり、後輩に「Python だけでも簡単な Web アプリデモなら作れるんやで」というのを教えたい一心で実装&執筆しました。本記事では Streamlit と Mimesis がメインですが、API, DB, 単体テスト, AWS などについても言及できるようにしたいと思っています。

画面一覧

現段階で作成した画面は以下の 4 つです

  • ログイン画面
  • 商品一覧画面
  • カート画面
  • 注文一覧画面

Streamlit のおかげで、それっぽいアプリ画面に仕上げっていることが分かると思います。ソースコードは github を参照して頂ければと思いますが、HTML/JS/CSS は一切書いていません。

ログイン画面

ログイン画面gif

  • 現段階では認証は実装していません
  • ユーザを選択するだけでログインできます

ユーザ種別(role)毎のアクセス権限は以下の通りです。

ユーザ種別 ログイン 商品一覧 カート 注文一覧
管理者(admin) O O O O
オーナー(owner) O X X O
会員(member) O O O X
ゲスト(guest) O X X X

商品一覧画面

商品一覧画面gif

  • 現段階では商品詳細画面は実装していません
  • 数量を指定し、カートへ追加できます

カート画面

カート画面gif

  • 現段階ではカード情報など、購入に必要な情報は入力不要です
  • カート内の商品の注文を確定できます

数量指定のボタンがイケてないですが、小回りが効かないのはまさにこういった部分です。

注文一覧画面

注文一覧画面gif

ダミーデータ作成

いよいよ mimesis でのユーザと商品のダミーデータを作成します

ユーザ

ユーザの生成項目は以下の通りです

  • user_id: アルファベット 5 文字 ~ 10 文字
  • name: 日本人らしい名前
    • reverse=Trueにすることで「太郎 山田」ではなく「山田 太郎」表記になる
  • birthday: 1950 年 ~ 2010 年
  • email: ドメインがsample.comのメールアドレス

一応説明を入れてみたものの、説明不要なくらい直感的にかけます。full_nameなどの文字列は公式ドキュメントにあるものを指定すれば OK です。

_ = Field(locale=Locale.JA)
schema = Schema(
    schema=lambda: {
        "user_id": _("random.generate_string", str_seq=string.ascii_lowercase, length=randint(5, 10)),
        "name": _("full_name", reverse=True),
        "birthday": _("date", start=1950, end=2010),
        "email": _("email", domains=["sample.com"]),
    }
)

公式ドキュメントに従い_ = Field()と書いていますが、何故_にするのかは謎です

商品

商品についても同様ですが、nameitem_typeには"vegetable""fruit"が入るようになっています。(八百屋さんなので野菜と果物が商品になっているという訳です)

_ = Field(locale=Locale.JA)
schema = Schema(
    schema=lambda: {
        "item_id": _("uuid"),
        "name": _(item_type),
        "price": randint(1, 5) * 100 - 2,
        "producing_area": _("prefecture"),
    }
)

まとめ

Streamlit と Mimesis を活用することで、Python のみで EC サイトのデモアプリが簡単に実装できました。面白そうだなと思った方は是非触ってみてください。本記事では紹介できていない機能がたくさんあるので、是非公式ドキュメントもご参照ください。

今後試したいこと

現段階の実装ではやや物足りない部分があるため機能追加・改修したいと思っています。
機能としては

  • 認証付きログイン
  • カート内商品の削除
  • 在庫管理
  • 管理者による商品追加
  • クレジットカード番号追加
  • 決済

などが挙げられます

非機能+α は

  • データをメモリではなく DB に保存
  • localhost ではなくサーバにデプロイ
  • 単体テストの追加

などを考えています。
上記の内容を追加次第、また記事にしようと思います。

Discussion