はじめに
前回と同じく社内のTableauサーバに公開されているグラフの画像データとテキストデータをダウンロードします。
必要なライブラリ
・Pythonの実行環境 (v3.11.4で試しました)
・ライブラリ requests, json
ライブラリがない場合は以下でインストールしてください
(jsonはもとから入っているようです)
pip install requests
必要な情報
・個人用アクセストークン:Tableauサーバの「マイアカウントの設定」画面より設定してください。
詳細は前回の記事に記載しています。
まず、認証してTokenを取得する
以下のsigninのAPIを利用して認証します。JSONのパースはResponse Bodyに書かれてあるタグを参考にしています。
POST /api/api-version/auth/signin
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#sign_in
以下のコードです。TODOに書かれているサーバ情報とトークン情報を実行するサーバのものに修正してください。認証はrequests.postを実行します。このときにPersonal Access TokenをPayloadに設定します。実行した結果のHTTP Responseを分析してこの後の通信で使用するTokenとsite idを取得します。
# -*- coding: utf-8 -*-
import requests, json.
TABLEAU_TOKEN_VALUE = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' #TODO Tableauの情報
TABLEAU_TOKEN_NAME = 'test' #TODO 個人用アクセストークンの「トークン名」
TABLEAU_SERVER = 'tableauserver.tableauserver.jp' #TODO Tableauサーバのアドレス
TABLEAU_VERSION = '3.19' #TODO Tabeleau ServerのAPI version
#Tableauサーバーへサインインする
server_name = TABLEAU_SERVER
version = TABLEAU_VERSION
site_url_id = "" # Site URLのパス、空白の場合はDefaultになる
# Personal Access Token を指定する
personal_access_token_name = TABLEAU_TOKEN_NAME # Personal access tokenの名前
personal_access_token_secret = TABLEAU_TOKEN_VALUE # Personal access token
signin_url = "https://{server}/api/{version}/auth/signin".format(server=server_name, version=version)
payload = { "credentials": { "personalAccessTokenName": personal_access_token_name, "personalAccessTokenSecret": personal_access_token_secret, "site": {"contentUrl": site_url_id }}}
headers = {
'accept': 'application/json',
'content-type': 'application/json'
}
# サーバにRequestを送信する
req = requests.post(signin_url, json=payload, headers=headers, verify=False)
req.raise_for_status()
#HTTP Responseを取得
response = json.loads(req.content)
#credentialsのエレメントからTokenを取得する
token = response["credentials"]["token"]
#Site IDエレメントからSite IDを取得する
site_id = response["credentials"]["site"]["id"]
print('Sign in successful!')
print('Token: {token}'.format(token=token))
print('Site ID: {site_id}'.format(site_id=site_id))
view idを検索する
以下のAPIを使ってview_idを検索します。
GET /api/api-version/sites/site-id/views?filter=viewUrlName:eq:view-name
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#get_view_by_path
検索結果はJSON形式で返るようにして、JSONデータをパースして最初のview idを取得しています。複数のviewを持つ結果が返る場合はプログラムを修正してください。
VIEW_URL_NAME = 'Order_Sales' #TODO viewUrlNameの値(シート名)を入れる
#view idを探す
query_value= "filter=viewUrlName:eq:{viewUrlName}".format(viewUrlName=VIEW_URL_NAME)
headers = {'X-tableau-auth':token,
'accept': 'application/json'}
#GET /api/api-version/sites/site-id/views?filter=viewUrlName:eq:view-name
view_get_url="https://{server}/api/{version}/sites/{siteid}/views?{query}".format(
server=TABLEAU_SERVER, version=TABLEAU_VERSION, siteid=site_id, query= query_value)
outDataOrig = requests.get(view_get_url,headers=headers).content
outDataDecode= outDataOrig.decode()
json_out = json.loads(outDataDecode)
view_id = json_out['views']['view'][0]['id']
print('view id: {view_id}'.format(view_id=view_id))
viewUrlNameからうまく検索できない場合は以下のコードのようにフィルタなしでviewの一覧を出すこともできます。この場合はprintされたXMLから目的のシートのview idを探してview_idセットしてください
headers = {'X-tableau-auth':token}
#GET /api/api-version/sites/site-id/views?filter=viewUrlName:eq:view-name
view_get_url="https://{server}/api/{version}/sites/{siteid}/views".format(
server=TABLEAU_SERVER, version=TABLEAU_VERSION, siteid=site_id)
outDataOrig = requests.get(view_get_url,headers=headers).content
print(outDataOrig.decode())
画像ファイルを取得する
以下のAPIでイメージを取得します。
GET /api/api-version/sites/site-id/views/view-id/image
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_view_image
必要なものはsite-idとview-idなので取得した値をURLに入れます。
requests.getを実行するとファイルをダウンロードできます。認証情報はHTTPヘッダーの中にSignin時に取得したTokenを入れます。
DOWNLOAD_IMAGE_PATH = 'sample.png' #TODO 保存先のファイル名
query_value = "resolution=high"
headers = {'X-tableau-auth':token}
#GET /api/api-version/sites/site-id/views/view-id/image?vf_<fieldname>=filter-value
image_get_url="https://{server}/api/{version}/sites/{siteid}/views/{viewid}/image?{query}".format(
server=TABLEAU_SERVER, version=TABLEAU_VERSION, siteid=site_id, viewid=view_id, query= query_value)
urlData = requests.get(image_get_url,headers=headers).content
with open(DOWNLOAD_IMAGE_PATH, mode='wb') as f:
f.write(urlData)
テキストファイル(CSV)をダウンロードする
テキストファイルの取得は以下になります。
#GET /api/api-version/sites/site-id/views/view-id/data
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_view_data
取得方法はイメージと同じですが、URLDecodeしないと文字化けするケースがありました。
サンプルではそのままCSVファイルに書き出していますが、openpyxlパッケージを使うとExcelファイルに書き出すこともできます。(もちろん、そのままファイル出力するだけでなくExcel表を読み込んである列に合うデータを入れるといったプログラムを書くこともできます。)
DOWNLOAD_TEXT_PATH = 'sample.csv' #TODO 保存先のファイル名
query_value = ""
headers = {'X-tableau-auth':token}
#GET /api/api-version/sites/site-id/views/view-id/data?vf_<fieldname>=filter-value
data_get_url="https://{server}/api/{version}/sites/{siteid}/views/{viewid}/data?{query}".format(
server=TABLEAU_SERVER, version=TABLEAU_VERSION, siteid=site_id, viewid=view_id, query= query_value)
urlData = requests.get(data_get_url,headers=headers).content
outtext = urlData.decode()
#取得したデータを出力してみる
print(outtext)
#ファイルに出力する
with open(DOWNLOAD_TEXT_PATH, mode='w') as f:
f.write(outtext)
サインアウトする
Tokenはタイムアウトまで有効なためデータ取得できたらサインアウトします。
以下のHTTP POSTの通信を行いますが、RequestのBodyは空になります。
POST /api/api-version/auth/signout
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref.htm#sign_out
server_name = TABLEAU_SERVER #Tableau Serverの情報(Name/IPアドレス)
version = TABLEAU_VERSION #Tabeleau ServerのAPI version
headers = {
'accept': 'application/json',
'content-type': 'application/json'
}
#サインイン時に取得した認証のTokenをヘッダにセットする
headers['X-tableau-auth']=token
#サインアウトのクエリをセット
signout_url = "https://{server}/api/{version}/auth/signout".format(server=server_name, version=version)
req = requests.post(signout_url, data=b'', headers=headers, verify=False)
req.raise_for_status()
print('Sign out successful!')
まとめ
ソースコードをまとめておきます
# -*- coding: utf-8 -*-
import requests, json
#環境に応じて変更する箇所#######################
TABLEAU_TOKEN_VALUE = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' #TODO Tableauの情報
TABLEAU_TOKEN_NAME = 'test' #TODO 個人用アクセストークンの「トークン名」
TABLEAU_SERVER = 'tableauserver.tableauserver.jp' #TODO Tableauサーバのアドレス
TABLEAU_VERSION = '3.19' #TODO Tabeleau ServerのAPI version
DOWNLOAD_IMAGE_PATH = 'sample.png' #TODO 保存先のファイル名
DOWNLOAD_TEXT_PATH = 'sample.csv' #TODO 保存先のファイル名
VIEW_URL_NAME = 'Order_Sales' #TODO viewUrlNameの値(シート名)を入れる
##############################################
#Tableauサーバーへサインインする
signin_url = "https://{server}/api/{version}/auth/signin".format(server=TABLEAU_SERVER, version=TABLEAU_VERSION)
payload = { "credentials": { "personalAccessTokenName": TABLEAU_TOKEN_NAME, "personalAccessTokenSecret": TABLEAU_TOKEN_VALUE, "site": {"contentUrl": SITE_URL_ID }}}
headers = {
'accept': 'application/json',
'content-type': 'application/json'
}
# サーバにRequestを送信する
req = requests.post(signin_url, json=payload, headers=headers, verify=False)
req.raise_for_status()
#HTTP Responseを取得
response = json.loads(req.content)
#credentialsのエレメントからTokenを取得する
token = response["credentials"]["token"]
#Site IDエレメントからSite IDを取得する
site_id = response["credentials"]["site"]["id"]
print('Sign in successful!')
print('Token: {token}'.format(token=token))
print('Site ID: {site_id}'.format(site_id=site_id))
###########################################################################################
#view idを探す
query_value= "filter=viewUrlName:eq:{viewUrlName}".format(viewUrlName=VIEW_URL_NAME)
headers = {'X-tableau-auth':token,
'accept': 'application/json'}
#GET /api/api-version/sites/site-id/views?filter=viewUrlName:eq:view-name
view_get_url="https://{server}/api/{version}/sites/{siteid}/views?{query}".format(
server=TABLEAU_SERVER, version=TABLEAU_VERSION, siteid=site_id, query= query_value)
outDataOrig = requests.get(view_get_url,headers=headers).content
outDataDecode= outDataOrig.decode()
json_out = json.loads(outDataDecode)
view_id = json_out['views']['view'][0]['id']
print('view id: {view_id}'.format(view_id=view_id))
###########################################################################################
#Imageファイルのダウンロード
query_value = "resolution=high"
headers = {'X-tableau-auth':token}
#GET /api/api-version/sites/site-id/views/view-id/image?vf_<fieldname>=filter-value
image_get_url="https://{server}/api/{version}/sites/{siteid}/views/{viewid}/image?{query}".format(
server=TABLEAU_SERVER, version=TABLEAU_VERSION, siteid=site_id, viewid=VIEW_ID, query= query_value)
urlData = requests.get(image_get_url,headers=headers).content
with open(DOWNLOAD_IMAGE_PATH ,mode='wb') as f:
f.write(urlData)
###########################################################################################
#テキストファイルのダウンロード
query_value = ""
headers = {'X-tableau-auth':token}
#GET /api/api-version/sites/site-id/views/view-id/data?vf_<fieldname>=filter-value
data_get_url="https://{server}/api/{version}/sites/{siteid}/views/{viewid}/data?{query}".format(
server=TABLEAU_SERVER, version=TABLEAU_VERSION, siteid=site_id, viewid=VIEW_ID, query= query_value)
urlData = requests.get(data_get_url,headers=headers).content
outtext = urlData.decode()
#取得したデータを出力してみる
#print(outtext)
with open(DOWNLOAD_TEXT_PATH ,mode='w') as f:
f.write(outtext)
######################################################################################
#Signout
headers = {
'accept': 'application/json',
'content-type': 'application/json'
}
#サインイン時に取得した認証のTokenをヘッダにセットする
headers['X-tableau-auth']=token
#サインアウトのクエリをセット
signout_url = "https://{server}/api/{version}/auth/signout".format(server=TABLEAU_SERVER, version=TABLEAU_VERSION)
req = requests.post(signout_url, data=b'', headers=headers, verify=False)
req.raise_for_status()
print('Sign out successful!')