💭

[2023年5月版]Redis 再入門 その②: Redis Stackお試し

2023/05/25に公開

前回はRedisの基本機能と"Redis Stack"についての紹介でした。

今回は Python でのクライアント実装のサンプルを…と思いまして。クライアントのリストページを参照してみました。

で、今回は Python OMに挑戦したいと思います。

Python OM

Python OM のリポジトリは以下です。

https://github.com/redis/redis-om-python

また、これのサンプルは以下です。

https://github.com/redis-developer/redis-om-python-flask-skeleton-app

Redis OM Python をFlaskでREST API化したものです。

今回はいろいろイジりたいのでForkを作成いたしました。
mainブランチはupstreamにお任せするので、stack-exampleブランチを作成いたしまして、こちらにいろいろ突っ込んでいきたいと思います。

https://github.com/asopitech/redis-om-pyflask/tree/stack-example

セットアップ

まずは REAMDME.md に従ってPythonプロジェクトの準備です。
とはいえ、先にやるのはDocker 立ち上げる前に時間のかかるPythonのセットアップです。

$ python3 -m venv venv
$ . ./venv/bin/activate
$ pip install -r requirements.txt
...

セットアップ完了後、dockerでRedis stackを立ち上げます。

$ sudo docker compose up -d

ここで以外だった?のは、redis-stack-serverイメージではなく、redis-stackイメージであったこと。
RedisInsightが使えるじゃない!!後ほど、こちらも見てみたいと思います。

Flaskサーバーの起動

とりあえず flaskを起動。

$ export FLASK_ENV=development
$ flask run
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
...

で、以下のようにFlaskが立ち上がります。

Flask Start

サンプルデータ投入

flaskがローカルに立ち上がったところでデータ投入スクリプトを叩きます。
'dataloader.py' によって 'data/people.json' のデータを投入いたします。

$ python dataloader.py
Created person Robert McDonald with ID xxxxxxxxxxxxxxxxxxxxx
Created person Kareem Khan with ID xxxxxxxxxxxxxxxxxxxxx
Created person Fernando Ortega with ID xxxxxxxxxxxxxxxxxxxxx
Created person Noor Vasan with ID xxxxxxxxxxxxxxxxxxxxx
Created person Dan Harris with ID xxxxxxxxxxxxxxxxxxxxx

IDはデータ投入時点のもので毎度、変わります。

処理コードの確認

まず dataloader.py の処理は以下です。
メインの処理はシンプルにこれだけです。

with open('data/people.json', encoding='utf-8') as f:
    people = json.loads(f.read())

for person in people:
    r = requests.post('http://127.0.0.1:5000/person/new', json = person)
    print(f"Created person {person['first_name']} {person['last_name']} with ID {r.text}")

json ファイルを読み取り、1オブジェクトごとに'Flask'に'POST'しています。

つづいて Flask サーバーでの /person/new のパス側での処理を抜き出してみます。

from flask import Flask, request
...
from person import Person
...

# Create a new person.
@app.route("/person/new", methods=["POST"])
def create_person():
    try:
        print(request.json)
        new_person = Person(**request.json)
        new_person.save()
        return new_person.pk

    except ValidationError as e:
        print(e)
        return "Bad request.", 400

request.jsonは上のrequests.post('http://127.0.0.1:5000/person/new', json = person)で渡したJSONですね。
注目は次の new_person = Person(**request.json)です。このPersonコンストラクタでは何が生成されているのでしょうか?
それが次に定義されたモデルクラスです。

from redis_om import (EmbeddedJsonModel, Field, JsonModel)
...
class Person(JsonModel):
    # Indexed for exact text matching
    first_name: str = Field(index=True)
    last_name: str = Field(index=True)

    # Indexed for numeric matching
    age: PositiveInt = Field(index=True)

    # Use an embedded sub-model
    address: Address

    skills: List[str] = Field(index=True)

    # Indexed for full text search
    personal_statement: str = Field(index=True, full_text_search=True)

ファイルは person.py です。
JsonModelクラスを継承したPersonクラスがFlaskサーバーでの処理でインスタンス化されてます。
このように JsonModel を継承したモデルクラスを定義することで、Redisに保存するJSONをPtyhohのクラスや属性のにマッピングすることができ、ActiveRecordのように save() メソッドで保存が可能となります。

RedisInsight で確認

さて、実際にデータが保存されているのか RedisInsight で見てみましょう。

http://localhost:8001/ にアクセスしてみます。
まず使用許諾やプライバシーポリシーなどの確認画面です。

Insight Start

ダイアログ下のI have read and understood the Terms にチェック入れてSubmitすると次の画面に遷移します。
このようにオブジェクトブラウザで登録済みデータが見れます。

Insight Browser

無事にPerson型で定義したとおりのJSON文字列が保存されているようですね。

Workbenchにチュートリアル?!

で、次のWorkbenchタブが気になったのですが…

Insight Workbrench 1

TUTORIALSとかRedis StackとかVector Similarity Searchなどの不穏な(?)単語が並んでいますね…w
恐る恐る、ちょっと触ってみますと…

Insight Workbrench 2

あら~、Insight のWorkbrenchでチュートリアルが動かして試せるようです!!

んで…このチュートリアルの実際の定義を以下の Github にて発見いたしました。

https://github.com/RedisInsight/Tutorials/blob/main/src/redis_stack/vector_similarity_search.md

ここにあるとおりに叩くとデータ入れてクエリ叩いて機能の確認ができるようです。
自前でいろいろ実装してみようかと思いましたが…ちょっと方向性が…w

さらに README.md にあるとおり、自前のチュートリアルも実装可能なようです。
https://github.com/RedisInsight/Tutorials/blob/main/README.md

次回はここら辺を参考に、クライアントのサンプル実装をしてみようかなと思います。
ありがとうございました!

Discussion