LoginSignup
0
0

More than 1 year has passed since last update.

RedashのPythonで自作ロジックを動作させる方法

Posted at

1.はじめに

・複数のDataSourceからexecute_queryを利用してデータを取得してDataFrameに加工。
・add_result_rowとadd_result_columnを利用してRedash用のテーブル化。
上記2点を行うのが面倒だった為、ラッパークラスの作成する事にした。

2.環境把握

Redashは、docker上で動かしているので、
スクリプトはdocker内部に設置する必要がある。

3.ディレクトリ構成を決める

Redash側にスクリプトのパスを設定するので、予め決めておく必要があります。
今回は以下のディレクトリ構成で設定します。

home
  └ redash
      └ scripts

※scriptsディレクトリの中にスプリプトを配置します。

4.ロジックの作成

ラッパークラスを作成します。
最初は簡単なクラスで大丈夫ですが、Redash側に設定するのでファイル名だけは確定させておいてください。

wrapper.py
class Test():
    def __init__(self):
        pass
    ...

5.Redashの設定

ここからRedash側の設定を変更していきます。

5-1.AdditionalModulesPathsの設定

ModulesPaths.PNG
スクリプトを配置しているパスを設定します。
[/home/redash/scripts]を記入します。

5-2.Modules to import prior to running the scriptの設定

ImportScript.PNG
インポートするファイル名を設定します。
wrapperを入力します。
※複数ある場合はカンマ区切りで入力。(カンマの後はスペースを空けない事)

5-3.設定を保存

Saveを押して保存します。
設定は保存されていますが、まだ動作しないので注意してください。

6.Dockerを再起動する。

コンテナ自体を一旦破棄して、再度作り直します。

docker-compose down
docker-compose up -d

※コンテナ自体を作る直す必要はないかもしれないですが、一応作り直しています。

6-1 Redash側の動作

ここは飛ばしてもらっても設定に影響はないです。

https://github.com/getredash/redash/blob/master/redash/query_runner/python.py#L103-L105

        if self.configuration.get("allowedImportModules", None):
            for item in self.configuration["allowedImportModules"].split(","):
                self._allowed_modules[item] = None

Redashの起動時に _allowed_modules配列にwrapperキーの値がNoneとして追加されます。

https://github.com/getredash/redash/blob/master/redash/query_runner/python.py#L107-L110

        if self.configuration.get("additionalModulesPaths", None):
            for p in self.configuration["additionalModulesPaths"].split(","):
                if p not in sys.path:
                    sys.path.append(p)

Redashの起動時に 環境変数にスクリプトのパス「/home/redash/scripts」が登録されます。

7.スクリプトファイルをDocker内に転送する。

まだ実体がDocker内には存在していないので、今の状態でスクリプトを実行するとファイルがないエラーが発生します。
なので、実体をDocker内へ転送します。

docker cp ./scripts/. `docker-compose ps -q server`:/home/redash/scripts/
docker cp ./scripts/. `docker-compose ps -q worker`:/home/redash/scripts/

スクリプトファイルのオーナーがrootであっても
スクリプトは実行できるのを確認しているので、この手順では権限変更を行いません。

8.実際にRedash内で実行する。

from wrapper import test

hoge = test()
hoge.fuga()

8-1.Redash側の動作

https://github.com/getredash/redash/blob/master/redash/query_runner/python.py#L248-L251

    def run_query(self, query, user):
        self._current_user = user

        try:
        ....

実行した際に、run_query関数が走ります。
RestrictedPythonで設定して動かしますが、この記事では触れませんのでご了承ください。

https://github.com/getredash/redash/blob/master/redash/query_runner/python.py#L117-L126

    def custom_import(self, name, globals=None, locals=None, fromlist=(), level=0):
        if name in self._allowed_modules:
            m = None
            if self._allowed_modules[name] is None:
                m = importlib.import_module(name)
                self._allowed_modules[name] = m
            else:
                m = self._allowed_modules[name]

            return m

Redashのロジック内でimportしたモジュールは、custom_import関数内で、importlibを使用してインポートされます。

10.参考サイト

https://qiita.com/tsuboyataiki/items/90dbe94553d3dea39b19
https://qiita.com/reflet/items/ad734edc87c73cbaa459
https://docs.docker.jp/engine/reference/commandline/cp.html

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0