2024年現在のWebアプリ作成方法の一つとして、「PythonだけでWebアプリを完結する」作り方があります。
その一つとしてReflexというのがあります。
Reflexとは
PythonのWebアプリケーションフレームワークです。
ただし、Djangoのような、いわゆるHTMLを中心としたWebアプリケーションとかなり違います。
どちらかというとStreamlitの系統と似ています。
本記事では、ReflexをSQLiteを用いてloginするようなサンプルを作成してみたいと思います。
特徴
特徴として、以下だそうです。
- Pure Python
すべてPythonで書けます - 簡単で、柔軟性がある
- 全部入り
Reflexだけで一通りの機能が備わってる
やはり一番の特徴は、作り方がReact.jsっぼい
というところでしょう。
作り方がPython+Reactのような、独特の作り方をします。慣れるまである程度の時間がかかるでしょう。
でも、Reactと違い、立ち上げるまでの時間はかかりません。その意味では動かしながら学ぶこと可能なので分かりやすいです。
注意点としては、まだ0.6.1というバージョンでしょう。まだstableとは言えません。その点は注意する必要があります。
環境
使ってみた環境は以下です。
- WSL2
- ubuntu 24.04 LTS
- Python3.12.5
- reflex 0.6.1
dashboardにlogin_formを設定してみる
プロジェクトの最初にdashboardを指定し、dashboardにlogin_formを設置してみます。
準備
実装したソースはここにあります。
$ cd reflex_exmaple $ pip install reflex $ reflex init $ pip install reflex-local-auth $ reflex db init $ reflex db makemigrations $ reflex db migrate
SQLite
まずsqliteを指定します。
import reflex as rx config = rx.Config( app_name="reflex_example", db_url="sqlite:///reflex.db", )
reflex-local-authを使用する
自前ですべて実装してもいいですが、まずは(reflex-local-auth)[https://github.com/masenf/reflex-local-auth]を使用してみました。
reflex-local-authの使用法
実際には、README.mdに書いてあることだけでは出来ませんでした。
私がやった方法は以下です。
- (1) まずはREADME.mdに書いてあった方法を行う
- (2) stateに認証用classを別途実装する
- (3) on_loadで認証用classのログイン処理を呼び出すよう追加する
自分で、on_load時にログイン処理をする必要があるのでは、あまりライブラリを使う必要を感じませんが、、まぁゼロからつくりよりはましというところです。
修正箇所
それぞれの修正箇所は以下です。
state/auth.py
import reflex as rx import reflex_local_auth class ProtectedState(reflex_local_auth.LocalAuthState): username: str def on_load(self): if not self.is_authenticated: rx.window_alert(f"Invalid username or password.") return rx.redirect("/login") self.username = f"{self.authenticated_user.username}" print(f"valid username {self.username}") def do_logout(self): self.username = "" return reflex_local_auth.LocalAuthState.do_logout
relrex_example.py
import reflex_local_auth app.add_page( reflex_local_auth.pages.login_page, route=reflex_local_auth.routes.LOGIN_ROUTE, title="Login", ) app.add_page( reflex_local_auth.pages.register_page, route=reflex_local_auth.routes.REGISTER_ROUTE, title="Register", )
pages/index.py
def index_onload(): result = ProtectedState.on_load() if result: return result return StatsState.randomize_data() @reflex_local_auth.require_login @template(route="/", title="Overview", on_load=index_onload())
pages/index.pyはもともとon_loadが呼ばれてたので、それはそのまま生かしてログインすることにしました。
ログアウトは以下のように記述できます。
components/navbar.py
rx.button("Sign out", on_click=ProtectedState.do_logout, size="3"),
起動方法
$ reflex run
おわりに
いまいち納得いかない部分がありますが、ログイン機能を追加すること自体は簡単でした。
参考
- https://github.com/reflex-dev/reflex-examples/blob/main/twitter/twitter/state/auth.py