オフラインPCにTabpyをインストールしてみた

# 概要
オフライン環境のPCにTabpyをインストールする手順です。
オンライン接続可能なPCで必要なファイルを`pip download`でダウンロードし、インストールしたいPCにそれをコピーしてインストールしました。

:::note info
つまづいたポイントをインフォメーションとして注記しています。
:::



# 環境
インストールするPC
| ソフトウェア | バージョン |
|:-|:-|
|Windows 10 Enterprise|20H2|
|Tableau Desktop|2021.4.9|
|Tableau Prep|2021.4.4|
|anaconda|4.12.0|
|python|3.9.12|

ファイルをダウンロードするPC
| ソフトウェア | バージョン |
|:-|:-|
|Windows 10 Pro|20H2|
|anaconda|4.8.3|
|python|3.8.3|

# 作業内容 
- オンライン接続可能なPCで必要なファイルを一括ダウンロード
- ダウンロードしたファイルをtabpyをインストールしたいPCにコピーしてインストール
:::note info
小さなパッケージであれば、ファイルを１つずつ[pypi](https://pypi.org/project/coverage/#files)からダウンロードすることも可能ですが、tabpyの場合は必要なパッケージも多いので、`pip download`で一括ダウンロードします。
:::

### 必要なファイルのダウンロード
オンライン接続可能なPC（anacondaインストール済み）のanaconda promptで以下のコマンドを実行します。
カレントディレクトリにダウンロードファイルを保存するためのフォルダ（ここでは「tp」としていますが、任意の名称でOK）を作成しています。
```:anaconda prompt
pip download -d ./tp tabpy
```

このtpフォルダに保存されたファイルをすべて、インストールしたいPCに持っていきます。

:::note info
pipのアップデート
pipが最新でないと、以降のステップで失敗することがあるので、以下のコマンドでアップデートします。
```:anaconda prompt
pip install -U pip
```
:::

### tabpyのインストール
先ほど保存したファイルを入れたフォルダをカレントディレクトリに置き、以下のコマンドを実行します。
```:anaconda prompt
pip install --no-index --find-links=./tp tabpy
```

:::note info
エラーが出る場合
私の環境では、作業中に以下のようなエラーが出ました。
メッセージを読むと、「coverage」のパッケージが要求を満たしてませんよ、ということなので、[pypi](https://pypi.org/project/coverage/#files)からソースファイル(.tar.gz)をダウンロードして、tpフォルダに入れました。他のパッケージでエラーが出るようなら、該当するものを検索してダウンロードするとうまくいくかもしれません。
```:anaconda prompt
ERROR: Could not find a version that satisfies the requirement coverage (from tabpy) (from versions: none)
ERROR: No matching distribution found for coverage
```
:::

### tabpyの起動
anaconda promptで`tabpy`コマンドを実行するだけです。

```:anaconda prompt
(base) C:\Users\208078\Documents>tabpy
2022-09-13,10:59:16 [INFO] (app.py:app:244): Parsing config file D:\Anaconda3\lib\site-packages\tabpy\tabpy_server\app\..\common\default.conf
2022-09-13,10:59:16 [INFO] (app.py:app:436): Loading state from state file D:\Anaconda3\Lib\site-packages\tabpy\tabpy_server\state.ini
2022-09-13,10:59:16 [INFO] (app.py:app:332): Password file is not specified: Authentication is not enabled
2022-09-13,10:59:16 [INFO] (app.py:app:347): Call context logging is disabled
2022-09-13,10:59:16 [INFO] (app.py:app:125): Initializing TabPy...
2022-09-13,10:59:16 [INFO] (callbacks.py:callbacks:43): Initializing TabPy Server...
2022-09-13,10:59:16 [INFO] (app.py:app:129): Done initializing TabPy.
2022-09-13,10:59:16 [INFO] (app.py:app:83): Setting max request size to 104857600 bytes
2022-09-13,10:59:16 [INFO] (callbacks.py:callbacks:64): Initializing models...
2022-09-13,10:59:16 [INFO] (app.py:app:106): Web service listening on port 9004
```

### Tableau側の設定
ヘルプ⇒設定とパフォーマンス⇒分析の拡張機能接続の管理
![tabpy接続1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114658/e5936743-9254-71d3-cf02-5f06c2e3c937.png)
tabpyを選択し、ホスト名：localhost、ポート：9004として保存をクリックします。
念のため、テスト接続もクリックして接続確認もしておきましょう。
![tabpy接続2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114658/121b258d-ee64-64cd-af5a-007af4b50282.png)


### 動作確認
サンプルスーパーストアのデータを使って、売上の合計を返す計算式を作成しました。
第一引数がPythonのコード、第二引数にPythonに渡すフィールドを指定します。
第二引数に指定するフィールドは集計関数か属性である必要があります。
なお、`_arg1`は第二引数の`sum([売上])`に対応します。第二引数が複数ある場合は、
`_arg1`、`_arg2`、`_arg3`、・・・、`_argn`　が対応することになります。
```:売上（合計）
SCRIPT_INT(
    'return _arg1' ,
    SUM([売上])
)
```
一応、普通に合計した場合と変わらないか確認
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114658/97cc27ac-2dbd-4147-8461-226e14110475.png" width="70%">


以上で、Tabpyのインストールが完了しました。
次回から活用について書いていきます（予定）。

# 参考にしたサイト

https://densan-hoshigumi.com/develop/python-pip-offline-install
https://newssdx.kcme.jp/tableau-prep_python-script-2/
https://help.tableau.com/current/pro/desktop/ja-jp/functions_functions_tablecalculation.htm#SCRIPTfunc