0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【環境構築】Laravel から Python を呼ぶ構築3パターン

0
Last updated at Posted at 2026-08-05

8f0620bc-8d89-4f67-84cc-216597987f73.png

PHPで表を作りつつ、重い処理だけPythonに投げたいときのメモ。

前提の流れ

Blade のフォームでファイルアップロード → Python に投げる → 結果を Blade で表示。

3パターン

1. プロセス直呼び(同期)

Symfony Process で python3 script.py を叩いて stdout を JSON で受ける。一番シンプル。数秒で終わる処理ならこれで十分。
弱点は PHP-FPM のワーカーが Python の終了まで塞がること。長い処理でタイムアウトする。

$result = Process::run([$pythonBin, $script, $path]);
$data = json_decode($result->output(), true);

2. キュー + ジョブ(非同期)

呼び方は1と同じだが Laravel Queue に投げて非同期化。ブラウザには受付IDを即返し、ポーリングで結果を取りに行かせる。
数十秒〜数分の処理ならこれ一択。Redis + worker の運用コストがかかる。

非同期 = 「裏で処理して終わったら取りに行く」。リアルタイム垂れ流しではない。途中経過を流したいなら SSE / WebSocket は別の話。

3. FastAPI で常駐(HTTP)

Python 側を常駐サービスにして HTTP で叩く。フロントは PHP のままで、FastAPI は HTML を吐かない。JSON を返すだけの裏方。127.0.0.1 にバインドして外部から叩けないようにする。

$data = Http::post('http://127.0.0.1:8001/analyze', ['path' => $path])->json();

比較

毎回起動 常駐(FastAPI)
同期 1番。最小構成 軽い処理を高速に返す
非同期 2番。重い処理向け 重い処理 + モデル常駐

判断は「準備 : 処理」の比率で決まる。

準備 処理 選択
軽い 短い 1番
軽い 長い 2番
重い 短い 3番
重い 長い 3番 + 非同期

3番が要るのはどんなときか

常駐が効くのは「準備は重いのに処理は一瞬」のやつ。

モデル読み込み 20秒 + 判定 0.1秒   ← 常駐が刺さる
起動 0.5秒     + 分析 300秒        ← 常駐しても無意味

処理が長いやつほど常駐は意味がない。起動3秒なんて誤差だから。それは非同期の出番。

具体的に3番が要るのは、AIモデル(数百MB〜GB、ロード10〜30秒)、デカい辞書やベクトルインデックス、あとは高頻度リクエスト。
逆に、ファイル読んで集計、正規表現でパース、グラフ画像生成、外部API叩いて加工 — この辺は全部1番で足りる。

セッションなしで同時アクセスされたら混ざる?

混ざらない。受付IDが引換券になる。ジョブは DB に「ID / 状態 / 結果」で独立して1行ずつ保存されるので、自分の ID でしか結果を取れない。ログインもセッションも不要。

ID は URL に埋めておけばブラウザを閉じても後から見に来れる。ただし2点注意。

  • 連番は絶対にやるな。 /result/1 は他人の結果が見える。UUID v4 を使う
  • 掃除処理を最初から入れる。 会員制じゃないと誰も消しに来ないので溜まり続ける。24時間で結果とアップロードファイルを自動削除

worker が1つだと直列処理になる点も注意。並列にするなら queue:work を複数立てるが、CPU コア数が上限の目安。Python がメモリ食うなら無闇に増やすとサーバが死ぬ。

ハマりどころ

  • venv のパス — web サーバから実行されると PATH が違う。python3 ではなく /path/to/venv/bin/python をフルパスで config に持つ
  • ファイルの受け渡し — storage に保存してパスだけ渡す。標準入力に流し込むと大きいファイルで詰まる
  • stdout と stderr を分ける — stdout は結果 JSON 専用。ログやエラーは stderr へ。混ぜると死ぬ
  • 文字コード — Python 側で encoding='utf-8' を明示。日本語ファイルで確実に事故る
  • コマンドインジェクション — ユーザー入力を引数に直接渡さない。Process の配列形式なら安全

結論

まず1番で作る。遅いと感じたら2番に移す。3番は Python 側が育ってから。

最初から3番をやると構成が重すぎる。ただし Python 側は def analyze(入力) -> 出力 の関数1本にまとめておくこと。これさえ守れば FastAPI で包むのは後から1時間で済む。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?