同梱した Python スクリプトを実行する

Recipe ID: shell-010

Tauri アプリに同梱した外部バイナリ(Python スクリプトを exe 化したものなど)を実行する方法、いわゆる「Sidecar」パターンの実装手順を解説します。

前提条件

プラグインのインストールが必要です。

npm run tauri add shell

Permissions (権限) の設定

src-tauri/capabilities/default.json に以下の権限を追加します。

{
    "permissions": [
        ...,
        "shell:allow-execute",
        "shell:allow-open",
        {
            "identifier": "shell:allow-execute",
            "allow": [
                {
                    "name": "binaries/backend",
                    "sidecar": true,
                    "args": true
                }
            ]
        }
    ]
}

手順

Sidecar は通常のコマンド実行とは異なり、アプリのバンドルにバイナリを含めるための特別な設定が必要です。

1. Python スクリプトのバイナリ化 (PyInstaller)

Python スクリプトをそのまま配布すると、ユーザー環境に Python ランタイムが必要になります。その依存関係を解消するために、PyInstaller などを使って単一の実行ファイル(バイナリ)化してから Sidecar として登録します。

まず、簡単な Python スクリプト backend.py を用意します。

import sys

# 標準出力に出力すると、Tauri 側で受け取れます
print("Hello from Python Sidecar!")
sys.stdout.flush()

次に、PyInstaller をインストールしてビルドします。

pip install pyinstaller
pyinstaller --clean --onefile backend.py

成功すると dist フォルダに実行ファイル(Windowsなら backend.exe、macOS/Linuxなら backend)が生成されます。

2. バイナリの配置とリネーム

Tauri の Sidecar として認識させるためには、バイナリファイル名を <command>-<target-triple><extension> の形式にする必要があります。

ターゲットトリプル(Target Triple)は rustc -Vv コマンドなどで確認できます(例: host: x86_64-pc-windows-msvc)。

例: Windows (x64) で backend というコマンド名にする場合
1. 生成された dist/backend.exe をコピーします。
2. プロジェクトの src-tauri/binaries/ フォルダ(なければ作成)に配置します。
3. ファイル名を backend-x86_64-pc-windows-msvc.exe にリネームします。

この命名規則に従うことで、Tauri は実行環境に応じた適切なバイナリを自動的に選択します。

3. tauri.conf.json の設定

bundle 設定でバイナリの場所(相対パス)を指定し、externalBin に登録します。

{
  "bundle": {
    "externalBin": [
      "binaries/backend"
    ]
  }
}

※ 設定には 拡張子やターゲットトリプルは含めず、コマンド名のみを記述します(binaries/backend)。Tauri がビルド時に、手順2で命名したファイルの中から、現在のプラットフォームに合ったものを自動的に探してバンドルします。

1. フロントエンドから作成する (TypeScript)

Command.sidecar メソッドを使用します。

import { Command } from '@tauri-apps/plugin-shell';

async function runSidecar() {
  // externalBin に登録したパスの「ファイル名部分(コマンド名)」を指定します
  const cmd = Command.sidecar('backend');
  
  const output = await cmd.execute();
  console.log(output.stdout);
}

2. バックエンドから作成する (Rust)

tauri_plugin_shell::ShellExt トレイトを使用することで、Sidecar として登録されたコマンドを簡単に呼び出せます。
この方法を使うと、Tauri がファイル名の解決(アーキテクチャや拡張子の付与)を自動で行ってくれます。

前提: Cargo.toml

tauri-plugin-shell クレートを依存関係に追加している必要があります。

実装例

use tauri_plugin_shell::ShellExt;
use tauri::AppHandle;

#[tauri::command]
async fn run_sidecar(app: AppHandle) -> Result<String, String> {
    // externalBin に "binaries/backend" と登録してあっても、
    // sidecar() に渡すのは "backend" (コマンド名) のみです。
    
    let output = app.shell()
        .sidecar("backend")
        .map_err(|e| e.to_string())?
        .output()
        .await
        .map_err(|e| e.to_string())?;

    if output.status.success() {
        let stdout = String::from_utf8_lossy(&output.stdout);
        Ok(stdout.to_string())
    } else {
        let stderr = String::from_utf8_lossy(&output.stderr);
        Err(stderr.to_string())
    }
}

※ Python スクリプト (.py) を直接同梱して実行するのではなく、PyInstaller などで実行可能バイナリ (.exe / ELF / Mach-O) に変換してから Sidecar として扱うのが一般的で確実な方法です。