Redash APIを使ってみる
時間がない人へのまとめ
この記事では、Dockerを使いOSS版Redashの環境を整えRedash APIを使用してみます。 APIの紹介では、クエリのキャッシュされた結果を引っ張ってくることや、新たにクエリを実行してその結果を取得する方法などを記載しています。
目次
そもそもRedashってなに?
Redashは、OSSのBIツールの一つです。
どういったことができるか大雑把に言うと、以下のような感じです。
app.redash.ioでホストされているRedashサービスは2021年11月に提供を終了したみたいです。 なので、使用する場合はOSS版を自前のホストに立ててください。
前準備
今回はDockerを使ってOSS版Redashの環境を立ててAPIを試していきたいと思います。
docker環境を立てる
さっそく、OSS版Redashを使えるようにしていきましょう!
適当なディレクトリを作成してその中に以下のようなdocker-compose.yml
を作ります。
(Re:Dashのインストール(Docker)のものを使わせていただきました。)
version: '2'
x-redash-service: &redash-service
image: redash/redash:latest
depends_on:
- postgres
- redis
env_file: redash.env
restart: always
services:
server:
<<: *redash-service
command: server
ports:
- "5000:5000"
environment:
REDASH_WEB_WORKERS: 4
scheduler:
<<: *redash-service
command: scheduler
environment:
QUEUES: "celery"
WORKERS_COUNT: 1
scheduled_worker:
<<: *redash-service
command: worker
environment:
QUEUES: "scheduled_queries,schemas"
WORKERS_COUNT: 1
adhoc_worker:
<<: *redash-service
command: worker
environment:
QUEUES: "queries"
WORKERS_COUNT: 2
redis:
image: redis:latest
restart: always
postgres:
image: postgres:latest
env_file: redash.env
restart: always
ports:
- "5436:5432"
nginx:
image: redash/nginx:latest
ports:
- "80:80"
depends_on:
- server
links:
- server:redash
restart: always
そして同じディレクトリに以下のようなredash.env
を作成しましょう
REDASH_HOST=http://localhost/redash
PYTHONUNBUFFERED=0
REDASH_LOG_LEVEL=INFO
REDASH_REDIS_URL=redis://redis:6379/0
POSTGRES_DB= redash
POSTGRES_USER= redash
POSTGRES_PASSWORD= hogehoge
REDASH_COOKIE_SECRET=redash-selfhosted
REDASH_SECRET_KEY=redash-selfhosted
REDASH_DATABASE_URL=postgresql://redash:hogehoge@postgres/postgres
これで以下のようにコマンドを叩くとredashが使えるようになります。
$ docker-compose run --rm server create_db
$ docker-compose up -d
問題なくコンテナが立ち上がったら、http://localhost/redash/にアクセスしてみましょう。
そうすると、以下のような画面が表示されると思います。
適当に入力してsetupボタンをクリックします。
以下のようなRedashのトップページが表示されればセットアップ完了です!
テストデータをDBに流す
次に、DBにデータを流していこうと思います まず、サンプルDBのデータを以下のページからDLしてきましょう。
DLリンクは下の方にあります。 DLしてきたものを解凍して、でてきたtarファイルを先程のdocker-compose.yml
を置いているディレクトリに配置しましょう。
そして以下のコマンドを打って、DBにデータを流しましょう!
ホスト側にPostgreSQLが入っている前提です。
pg_restore -h localhost -p 5436 -U redash -d redash ./dvdrental.tar
データがDBにリストアされればOKです。
Redashのデータソース設定
続いて、redashのデータソース登録をやっていきます。 先程サンプルデータを流したDBをredashで使えるようにしましょう。 トップページの右上にあるsettingsをクリックします。
クリックすると以下のような管理画面になると思います。 この「New Data Sources」をクリックします。 すると以下のような画面になるので、テキストボックスに`postgresql`と入力するとフィルターされて選択肢が出てくるので`PostgrSQL`をクリックします。 続いて、接続の設定が出てくるので以下のように記入し終了。Host: postgres # docker-compose.ymlで設定しているpostgrsqlコンテナのホスト名
User: redash # redash.envで設定したユーザー名
Password: hogehoge # redash.envで設定したパスワード
Database Name: redash # redash.envで設定したDB
これで、準備したPostgrSQLのDBをRedashで使えるようになりました。
簡単なクエリを実行してみる
それでは、さっそく簡単なクエリを実行してみましょう。 Redashのヘッダーにある「Create」から「Query」を選択しましょう。 すると以下のような画面になるので、クエリを書いて「Execute」してみます。 以下のように、結果が帰ってきましたね。
APIをためす
ようやく本題のRedash APIをためしていきたいとおもいます。
公式のAPIドキュメントの場所です。
クエリの結果を取得する
まず、クエリーページから「Show API key」をクリックします。 そうすると以下のように、API Keyと例としてリクエストURLが書かれています。 さっそく、このリクエストURLを使ってクエリの結果を取ってみます。 今回はCurlでいきましょう。
$ curl get "http://localhost/api/queries/1/results.json?api_key=apikey" |jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: get
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 21924 100 21924 0 0 382k 0 --:--:-- --:--:-- --:--:-- 382k
{
"query_result": {
"retrieved_at": "2021-12-19T04:42:10.577Z",
"query_hash": "db936c708c77683dd372f1ada72b8777",
"query": "select *\nfrom actor;",
"runtime": 0.015136957168579102,
"data": {
"rows": [
{
"first_name": "Penelope",
"last_name": "Guiness",
"actor_id": 1,
"last_update": "2013-05-26T14:47:57.620"
},
{
"first_name": "Nick",
"last_name": "Wahlberg",
"actor_id": 2,
"last_update": "2013-05-26T14:47:57.620"
},
....
しっかりと結果が取れましたね。
パラメーター付SQLの結果を取得する。
続いてパラメーター付きのものを試してみたいと思います。 まず、以下のようにパラメーターを使用するようにRedashのクエリを変更します。 クエリ
select *
from actor
where actor_id = {{ id }};
これで一回Redash上で結果を見てみると、actor_id
が1の結果のみ帰ってきていますね。
それでは、Curlを使って結果を取得してみます。
$ curl -X POST -H "Content-Type: application/json" -d '{"parameters":{"id": 1}}' "http://localhost/api/queries/1/results?api_key=token"|jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 511 100 487 100 24 16233 800 --:--:-- --:--:-- --:--:-- 17033
{
"query_result": {
"retrieved_at": "2021-12-19T04:59:35.423Z",
"data": {
"rows": [
{
"first_name": "Penelope",
"last_name": "Guiness",
"actor_id": 1,
"last_update": "2013-05-26T14:47:57.620"
}
],
"columns": [
{
"friendly_name": "actor_id",
"type": "integer",
"name": "actor_id"
},
{
"friendly_name": "first_name",
"type": null,
"name": "first_name"
},
{
"friendly_name": "last_name",
"type": null,
"name": "last_name"
},
{
"friendly_name": "last_update",
"type": "datetime",
"name": "last_update"
}
]
}
}
}
こちらも無事結果が帰ってきましたね。
もし以下のようにエラーが帰ってくる場合は、redashのパラメーターのテキストボックスの上にある設定⚙を押して見てください。
{
"job": {
"status": 4,
"error": "This query contains potentially unsafe parameters and cannot be executed on a shared dashboard or an embedded visualization."
}
}
そこで表示されるTypeの型にCurlのPOSTするパラメーターを合わせてください。
キャッシュされていないクエリの結果を取得する
先程までのものは、一度Redash上で実行されたものでキャッシュが残っているパターンを取得していました。
それでは、Redash上でキャッシュの残っていないクエリの結果を取得してみたいと思います。
以下のコマンドを叩きます。
$ curl -X POST -H "Content-Type: application/json" -d '{"parameters":{"id": 2}}' "http://localhost/api/queries/1/results?api_key=token"|jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 147 100 123 100 24 3000 585 --:--:-- --:--:-- --:--:-- 3585
{
"job": {
"status": 1,
"error": "",
"id": "92d7f7eb-1491-4cfa-810d-f4fa992a6076",
"query_result_id": null,
"updated_at": 0
}
}
上記のように、クエリの結果ではなくjobの情報が帰ってきたと思います。
jobの状態を取得する
ここから、クエリの結果を取るには帰ってきたジョブが終了している必要があります。 なので、少し経って以下のコマンドを実行してみましょう。
エンドポイント:/api/jobs/<job_id>
このとき、使用するAPI_keyは先程までのものではなく、ユーザーに紐付いたAPI_keyである必要があります。 Redashの画面右上にあるメニューから「Edit Profile」をクリックし、下の方にあるAPI Keyを使用しましょう。
もし、今までのKeyを使用していると以下のようになると思います
hara% curl "http://localhost/api/jobs/92d7f7eb-1491-4cfa-810d-f4fa992a6076?api_key=key" |jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 71 100 71 0 0 5916 0 --:--:-- --:--:-- --:--:-- 5916
{
"message": "Couldn't find resource. Please login and try again."
}
$ curl "http://localhost/api/jobs/先程帰ってきたjobのid?api_key=user-token"|jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 120 100 120 0 0 12000 0 --:--:-- --:--:-- --:--:-- 12000
{
"job": {
"status": 3,
"error": "",
"id": "92d7f7eb-1491-4cfa-810d-f4fa992a6076",
"query_result_id": 7,
"updated_at": 0
}
}
帰ってきたステータスの意味は以下のとおりです。
- 1 == PENDING(実行待ち)
- 2 ==開始(実行中)
- 3 ==成功
- 4 ==失敗
- 5 ==キャンセル
jobからクエリの結果を取得する
上記例だと、成功しているのでクエリの結果を取得してみましょう。
エンドポイント /api/query_results/<query_result_id>
$ curl "http://localhost/api/query_results/7?api_key=key"|jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 651 100 651 0 0 28304 0 --:--:-- --:--:-- --:--:-- 29590
{
"query_result": {
"retrieved_at": "2021-12-19T05:10:38.654Z",
"query_hash": "04bb6c6ca4e4f15ef3941d86296b18a4",
"query": "select *\nfrom actor\nwhere actor_id = 2;",
"runtime": 0.009379863739013672,
"data": {
"rows": [
{
"first_name": "Nick",
"last_name": "Wahlberg",
"actor_id": 2,
"last_update": "2013-05-26T14:47:57.620"
}
],
"columns": [
{
"friendly_name": "actor_id",
"type": "integer",
"name": "actor_id"
},
{
"friendly_name": "first_name",
"type": null,
"name": "first_name"
},
{
"friendly_name": "last_name",
"type": null,
"name": "last_name"
},
{
"friendly_name": "last_update",
"type": "datetime",
"name": "last_update"
}
]
},
"id": 7,
"data_source_id": 1
}
}
しっかり結果が帰ってきましたね。
注意しなければいけないのは、このリクエストに使用するAPI Keyもユーザーに紐づくものではないといけないようです。 queryに対するもの以外はすべてユーザーに紐づくAPI keyの方ってことですね。
キャッシュされたものを使いたくない場合
キャッシュされたデータではなく、新しくじっこうしたクエリの結果を取得したい場合以下のようにmax_age
パラメータで指定してあげるといいみたいです。
curl -X POST -H "Content-Type: application/json" -d '{"parameters":{"id": 1},"max_age":0}' "http://localhost/api/queries/1/results?api_key=key" | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 159 100 123 100 36 3967 1161 --:--:-- --:--:-- --:--:-- 5129
{
"job": {
"status": 1,
"error": "",
"id": "4ad82496-f1b0-4b2d-a72b-347af8c3a0b1",
"query_result_id": null,
"updated_at": 0
}
}
この場合でも、帰ってくるのはjobの情報なので先程のようにjobからクエリの結果を引っ張って来てくださいね。
おわりに
今回Redashの環境構築から、APIを使用してデータを引っ張ってくるところまでをおこないました。 ここからGASをつかって毎日情報をSlackに送ることなどいろいろなことができるとおもいます。 Redashのダッシュボード機能も便利だと思うので使っていきたいですね。