Electron と Python の連携
Electron(画面を作るのが得意) と Python(計算やデータ処理が得意) を組み合わせて、最強のデスクトップアプリを作る方法について解説します。
「言語が違うのにどうやって会話するの?」と不思議に思うかもしれませんが、実は意外とシンプルな方法で連携できるんです。
連携の仕組み:主な2つの方法
Electron(Node.js)とPythonをつなぐ方法は、大きく分けて2つのアプローチがあります。
方法1:標準出力(Stdout)を使う方法
これは、ElectronがPythonファイルを「実行(Spawn)」し、Pythonがprint()した内容をElectronが「読み取る」方法です。
-
流れ:
- Electron「ねえPython、このスクリプト動かして!」
- Python「処理終わったよ!結果を
printするね!」 - Electron「(コンソールに出てきた文字を読んで)なるほど、結果はこれか」
方法2:Web API(HTTP通信)を使う方法
こちらは、Pythonで小さな「Webサーバー(FastAPIなど)」を立ち上げ、ElectronからWebサイトを見るようにアクセスする方法です。
-
流れ:
- Python「ローカルサーバー(localhost:8000)を立ち上げて待ってるよ」
- Electron「このURLにデータを送って、結果をちょうだい(HTTPリクエスト)」
- Python「OK!計算してJSONで返すね」
メリット・デメリット
本格的に開発するならどちらが良いか、表で比較してみましょう。
| 特徴 | 方法1:標準出力 (Print) | 方法2:Web API (FastAPI) |
|---|---|---|
| 手軽さ | ◎ とても簡単。ファイル1つで済む | △ Webサーバーの知識が少し必要 |
| データのやり取り | △ 文字列のみ。複雑なデータは苦手 | ◎ JSON形式で複雑なデータも楽々 |
| 処理の並列性 | △ Pythonが動いている間、止まりがち | ◎ 非同期通信が得意。画面が固まらない |
| 拡張性 | △ 規模が大きくなると管理が大変 | ◎ 機能追加しやすく、構造がきれい |
| 既存資産の活用 | △ スクリプト単位での再利用 | ◎ Python側をそのままWebバックエンドに転用可 |
結論:本格開発なら「方法2(Web API)」がおすすめ
ちょっとしたスクリプトを動かすだけなら「方法1」でも十分ですが、将来的に機能を増やしたり、エラー処理をしっかりやりたい場合は「方法2」が圧倒的に有利
Web開発の標準的な技術(HTTP通信)を使うため、困ったときに情報が見つかりやすいのも大きなメリットであり、生成AIの恩恵も受けられやすい
ハンズオン
それでは、「方法2(FastAPI連携)」 で、最小構成のアプリを作ってみましょう。
ボタンを押すと、Pythonが挨拶を返してくれるシンプルなアプリです。
事前準備
- Node.js がインストールされていること
- Python がインストールされていること
Step 1: プロジェクトのセットアップ
適当なフォルダ(例: electron-python-app)を作り、ターミナルで以下を実行してライブラリを入れましょう。
# フォルダ作成と移動
mkdir electron-python-app
cd electron-python-app
# Pythonのライブラリ(FastAPIとサーバー)をインストール
pip install fastapi uvicorn
# Electronの初期化とインストール
npm init -y
npm install electron --save-dev
Step2: Pythonサーバー作成(api.py)
まずは「裏方」となるPythonファイルを作成します。
# api.py
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello from Python!"}
@app.get("/greet/{name}")
def read_item(name: str):
return {"message": f"こんにちは、{name}さん!Pythonより愛を込めて。"}
if __name__ == "__main__":
# ポート8000でサーバーを起動
uvicorn.run(app, host="127.0.0.1", port=8000)
- 解説: これだけで立派なWebサーバーです。localhost:8000/greet/あなたの名前 にアクセスすると、JSONデータが返ってきます
Step3: Electronの画面を作る (index.html)
次に「見た目」を作ります。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Electron + Python</title>
</head>
<body style="font-family: sans-serif; text-align: center; padding: 50px;">
<h1>Electron 🤝 Python</h1>
<input type="text" id="nameInput" placeholder="名前を入れてね" />
<button id="sendBtn">送信</button>
<h2 id="result" style="color: blue; margin-top: 20px;"></h2>
<script>
const btn = document.getElementById('sendBtn');
const resultArea = document.getElementById('result');
const input = document.getElementById('nameInput');
btn.addEventListener('click', async () => {
const name = input.value;
// Pythonサーバー(FastAPI)にアクセス!
try {
const response = await fetch(`http://127.0.0.1:8000/greet/${name}`);
const data = await response.json();
resultArea.innerText = data.message;
} catch (error) {
resultArea.innerText = "エラー: API取得失敗";
}
});
</script>
</body>
</html>
Step4: Electronのメインプロセス作成(main.js)
最後に、アプリの起動とPythonサーバーの管理をするファイルです。 「アプリ起動時にPythonも一緒に起動し、アプリ終了時にPythonも止める」 という処理を書きます。
const { app, BrowserWindow } = require('electron');
const path = require('path');
const { spawn } = require('child_process');
let mainWindow;
let pythonProcess;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true, // 簡易化のため有効化
},
});
mainWindow.loadFile('index.html');
}
// アプリ起動時の処理
app.whenReady().then(() => {
// 1. Pythonサーバーを裏でこっそり起動
console.log('Start Python server...');
pythonProcess = spawn('python', ['api.py']);
// ※ Mac/Linuxの場合は 'python3' かもしれません
// PythonのログをElectronのコンソールに出す(デバッグ用)
pythonProcess.stdout.on('data', (data) => {
console.log(`Python: ${data}`);
});
// 2. ウィンドウを作る
createWindow();
});
// アプリ終了時の処理
app.on('will-quit', () => {
// Pythonプロセスを確実に殺す
if (pythonProcess) {
pythonProcess.kill();
}
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
Step 5: 動作確認
package.json の scripts 部分を少し書き換えて、実行しやすくします。
{
"name": "electron-python-app",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"start": "electron main.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"electron": "^39.2.6"
}
}
コマンドプロンプトで下記を実行
npm start
補足資料: 配布方法
開発環境では動いても、他の人のPCにはPythonが入っていないかもしれません。 そこで、「Pythonごとアプリに埋め込んで配布する(Embed)」 という方法を使います。
Python Embeddable Package とは?
Python公式が提供している「インストール不要の最小構成zip版Python」です。これをElectronアプリのフォルダの中にコピペして一緒に配ります。
手順の概要
-
ダウンロード: Python公式サイトから Windows embeddable package (64-bit) というzipをダウンロードします。
-
配置: Electronプロジェクトの中に python_env などのフォルダを作り、zipの中身を全て展開します。
-
設定ファイルの変更: 展開した中にある python3xx._pth ファイルをメモ帳で開き、#import site の行の # を消して有効化します(これをしないとpipで入れたライブラリが読み込めません)。
-
ライブラリのインストール: この埋め込みPythonに対して、FastAPIなどをインストールします。 (ターミナルで python_env/python.exe -m pip install fastapi uvicorn のように指定して実行)
-
Electron側の修正: main.js で spawn('python', ...) としていた部分を、埋め込んだPythonのパス spawn('./python_env/python.exe', ...) に変更します。
少し難しく、手順も複雑ですが、これでpython環境ごとアプリを配布できます。
応用
現在、pythonのサーバーは8000番を使用していますが、このポートは使用されている可能性があります。動的に秋ポートを探すという処理を入れておくのが良いでしょう。また、ローカル環境とは言え、トークンによる認証設定も推奨します。少し難しい話になりましたね。
最後に
今回はElectron + Pythonという現代デスクトップアプリの王道について解説しました。
いいね、コメントどんどんよろしくお願いします。
