redis-pyを使って、PythonからRedisにアクセスする

# TL;DR

* PythonからRedisにアクセスするためのライブラリを知りたい
* `redis-py`というものを使うらしいので、ちょっと試してみた

[redis-py](https://pypi.org/project/redis/)

[redis-py（GitHub）](https://github.com/andymccurdy/redis-py)


# Redis

Key Value Storeの有名どころですね。

[Redis](https://redis.io/)

値として取れるものも、単純なものだけではなくList、Set、Sorted set、Hash、HyperLogLogs、Streamなどを扱うことができます。

[An introduction to Redis data types and abstractions](https://redis.io/topics/data-types-intro)

今回は、Redisの`5.0.5`を使用します。Dockerイメージで。

```shell
$ docker container run -it --rm --name redis redis:5.0.5

$ docker inspect redis | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.2",
                    "IPAddress": "172.17.0.2",
```

PythonからRedisへアクセスするためには、`redis-py`というものがメジャーなようなので、こちらを使用して試してみることにします。

[Clients / Python](https://redis.io/clients#python)


# 環境および`redis-py`のインストール

利用するPythonのバージョン。

```shell
$ python3 -V
Python 3.6.7
```

`redis-py`のインストールとバージョン。

```shell
$ pip3 install redis

$ pip3 freeze
...
redis==3.2.1
```


# `redis-py`を使って、PythonからRedisにアクセスする

とりあえず、Getting Startedを見ながら書いてみましょう。

[Getting Started](https://github.com/andymccurdy/redis-py#getting-started)

あんまり使い方が書かれていないのですが、コードを見つつ、なんとなく書いてみます…。

https://github.com/andymccurdy/redis-py/blob/3.2.1/redis/client.py

hello-redis.py

```python
import redis

redis_client = redis.Redis(host = '172.17.0.2', port = 6379)


## Simple
redis_client.set('key1', 'value1')

assert redis_client.get('key1') == b'value1'
assert redis_client.get('key1').decode('utf-8') == 'value1'


## Hash
redis_client.hmset('hash_key1', { 'member1': 'hash_value1', 'member2': 'hash_value2' })

assert redis_client.hget('hash_key1', 'member1') == b'hash_value1'
assert redis_client.hgetall('hash_key1') == { b'member1': b'hash_value1', b'member2': b'hash_value2' }
```

実行。

```shell
$ python3 hello-redis.py
```

動きました。

ところで、レスポンスが`byte`で返ってきているので、ひたすら`decode`することになります。

ここで、ドキュメントをちゃんと見ると、`decode_responses`を`True`にすればよいとあるのでこちらを使ってみましょう。

[Getting Started](https://github.com/andymccurdy/redis-py#getting-started)

> If all string responses from a client should be decoded, the user can specify decode_responses=True to Redis.__init__. In this case, any Redis command that returns a string type will be decoded with the encoding specified.

hello-redis-decoded.py

```
import redis

redis_client = redis.Redis(host = '172.17.0.2', port = 6379, decode_responses = True)


## Simple
redis_client.set('key1', 'value1')

assert redis_client.get('key1') == 'value1'


## Hash
redis_client.hmset('hash_key1', { 'member1': 'hash_value1', 'member2': 'hash_value2' })

assert redis_client.hget('hash_key1', 'member1') == 'hash_value1'
assert redis_client.hgetall('hash_key1') == { 'member1': 'hash_value1', 'member2': 'hash_value2' }
```

スッキリしましたね。

とりあえず、基本的な使い方はこんな感じでしょうか。

接続時のオプションなどは、ちゃんと見た方が良さそうです。

https://github.com/andymccurdy/redis-py/blob/3.2.1/redis/client.py#L605-L615


# その他の機能

ドキュメントを見ると、コネクションプールなどの機能もあるようです。

[More Detail](https://github.com/andymccurdy/redis-py#more-detail)

Hiredisとか、面白いですね

[Parsers](https://github.com/andymccurdy/redis-py#parsers)

RedisチームがCで実装したパーサーで、Hiredisをインストールすると`redis-py`のパース処理が早くなるようです。

[Hiredis](https://github.com/redis/hiredis)

```shell
$ pip3 install hiredis
```

`redis-py`自身が、Hiredisを意識したソースコードになっています。

https://github.com/andymccurdy/redis-py/blob/3.2.1/redis/connection.py#L434-L437

あと、ドキュメントには記載がなさそうですが、Redis Clusterも使えそうなので、そのうち試してみたいところ。

https://github.com/andymccurdy/redis-py/blob/3.2.1/redis/client.py#L492-L514

Redis Sentinelのサポートは書かれているんですけどね。

[Redis Sentinel](https://github.com/andymccurdy/redis-py#sentinel-support)

今回はこれくらいで。