Tableau Serverにアクセスして画像、データを取得するプログラムを作ってみる。その２フィルタ（Python）

## はじめに
前回の記事ではREST APIを使用してTableauのシートの画像、データを取得するプログラムを作ってみたのですが、今回はフィルタ条件など条件を入れた取得を行います。

## 準備
基本的には[前回](https://qiita.com/kktzn0920/items/b42c92c0ca9b72678809)の流れと同じです。画像を取得する部分にフィルタが追加されます。(データについては今回は割愛しますが同じようにできます)

## 今回のグラフ
以下のグラフの画像を取得します。基本的には前回と同じですが、Categoryでフィルタがかけられるようになっているシートです。
![Tableau_profit_filter_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3837083/997c61d0-4855-15ab-9e65-680effc9056c.png)

## フィルタするコード
フィルタについては以下に説明があります。
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_concepts_filtering_and_sorting.htm
具体的にはvf_<fieldname>=filter-valueという形でフィルタの条件を入れるだけです。

画像を取得する場合は以下のAPIを使用します。
GET /api/api-version/sites/site-id/views/view-id/image?vf_<fieldname>=filter-value
https://help.tableau.com/current/api/rest_api/en-us/REST/rest_api_ref_workbooks_and_views.htm#query_view_image

```sample_filter01.py
FILTER_TEXT = 'Category'  #TODO フィルタのメジャーまたはディメンジョン名
FILTER_VAL = "Office Supplies"  #TODO フィルタしたいワード

#Imageファイルのダウンロード
query_value = "resolution=high&vf_{t_filter}={filter_val}".format(
        t_filter=FILTER_TEXT, filter_val=FILTER_VAL) 
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)
```

## フィルタ出来ないケース
フィルタのクエリーができるのはメジャーまたはディメンジョン名です。以下のようにメジャーネームを切り替えるケースはフィルタ出来ないです。
この例ではフィルタはメジャーネームのDiscount、Orderのカウント、Profit、Quantity、Salesを切り替えるようになっていますが、これは特定のメジャー、ディメンジョンの要素ではないのでREST APIのFilterクエリでは実行できないです。
![スクリーンショット 2024-07-14 195801.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3837083/1ccdc168-60b5-b4fb-26da-9339510ef345.png)

## コードのまとめ
前回の投稿の内容も入れて実行できるコードにまとめます。
```sample_filter_all.py
# -*- 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 保存先のファイル名
VIEW_URL_NAME = 'Profit_Category'  #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',
           'content-type': '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))

###########################################################################################
FILTER_TEXT = 'Category'  #TODO フィルタのメジャーまたはディメンジョン名
FILTER_VAL = "Office Supplies"  #TODO フィルタしたいワード
#FILTER_VAL = "Furniture"

#Imageファイルのダウンロード
query_value = "resolution=high&vf_{t_filter}={filter_val}".format(
        t_filter=FILTER_TEXT, filter_val=FILTER_VAL) 
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)

######################################################################################
#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!')
```