本日、v0.1.4をリリースし、それなりに動作するようになったので、私が開発中のWebアプリケーションフレームワーク「Pykour」についてご紹介します。
Pykourとは
REST APIを作成することに特化したPython向けWebアプリケーションフレームワークです。FlaskやFastAPIを参考に作成しているので、現時点ではREST APIしか作れないFastAPIのようなフレームワークになっています。
v0.1.xでは機能追加や機能変更を行うベータ版とし、v0.2.0から正式版としてリリースする計画としています。
Pykourの使い方
まずは基本的な使い方について説明します。
インストール
Pykourのインストールは他のフレームワークと同様にpip
コマンドでインストールできます。
$ pip install pykour
pykour
パッケージをインストールすると、pykour
コマンドが使用可能になります。
$ pykour -v
Pykour v0.1.4
main.py
という名前で以下のプログラムを作成します。
from pykour import Pykour
app = Pykour()
@app.get("/")
def home():
return {"message": "Hello, World!"}
最も簡単なプログラムは、FastAPIとほとんど変わらない書き方になります。このプログラムを実行するには、pykour dev
コマンドを使います。
$ pykour dev main:app
pykour dev
コマンドではuvicorn
を使用し、pykour run
コマンドではgunicorn+uvicorn-worker
を使用して、ASGIサーバーを起動しています。
デフォルトではhttp://127.0.0.1:8000でサーバーが起動しますので、
$ curl http://127.0.0.1:8000/
{"message": "Hello, World!"}%
のように応答が返ってきます。
v0.1.4ではどこまでできるのか
v0.1.4では、以下のようなことができるようになっています。
ルーティングの設定
ルーティングの設定は、前述のようにPykourインスタンスに直接設定する方法と、
from pykour import Pykour
app = Pykour()
@app.get("/")
def home():
return {"message": "Hello, World!"}
Routerインスタンスを作成して、それをPykourインスタンスに設定する方法もあります。
from pykour import Router
router = Router(prefix="/users")
@router.get("/")
def get_users():
return {"message": "get users"}
from pykour import Pykour
from .routes import router
app = Pykour()
app.add_router(router)
スキーマの使用
リクエストボディはデフォルトでは辞書型にマッピングされますが、スキーマを作成して対応させることもできます。
from pykour.schema import BaseSchema
class UserSchema(BaseSchema):
name: str
age: int
from pykour import Pykour
from .schemas import UserSchema
app = Pykour()
@app.post("/")
def post_user(user: UserSchema):
return {"name": user.name}
設定ファイルの使用
YAML限定ですが、設定ファイルを使用することもできます。
例えば、
foo:
bar: bas
という設定ファイルをconfig.yamlというファイル名で作成した場合、Pykourインスタンス作成時に設定ファイルを指定することができます。
from pykour import Pykour
app = Pykour("config.yaml")
@app.get("/")
def home(config: Config):
return {"message": config.get("foo.bar")}
設定ファイルはConfig
クラスで扱うことができ、ルート関数の引数に指定しておくと、自動的に設定して呼び出してくれます。
データベースアクセス
まだ、sqlite3しか対応していませんが、データベースアクセスも可能です。
設定ファイルでデータベースの設定を行います。
pykour:
database:
type: sqlite
url: pykour.db
設定ファイルを指定することでデータベースにアクセスできるようになります。
from pykour import Pykour
from pykour.db import Connection
app = Pykour("config.yaml")
@app.get("/")
def home(conn: Connection):
return {"users": conn.select("SELECT * FROM users")}
今後の計画
まだまだ足りない機能や作りたい機能は結構ありますが、どう実装するべきかを考え中です。
- ORMの実装
- 複数のデータベースへの対応(まずはMySQLやPostgreSQL)
- キャッシュ機能(処理を行わずにキャッシュしてあるレスポンスを返す)の実装
最近のFastAPIでは、スキーマとモデルを一体化していますが、リクエストのデータ構造とテーブルのデータ構造の違いを考えると分けた方がよいのではないかと思っています。ORMは確かによいのですが、JOINやカラムの編集などが出てくると途端に難易度が上がったりするので、どういったインターフェースにするか悩んでいます。
また、コード自体の改善やテストケースの改善など安定性の向上についても継続的に進めていきたいと思います。一応、機能を制限することで高いパフォーマンスを発揮することを目標としているので、ベンチマークをとる環境も構築していきたいです。
v0.1.5では複数のデータベースをサポートしつつ、コードの改善を進めていく予定です。