1
0

More than 1 year has passed since last update.

Laravel sailでPythonを使う

Posted at

自作のポートフォリオをLaravelで制作中にPythonのライブラリを使って処理を実行したかったので、挑戦してみました。
いくつかのつまづきポイントがあったのでまとめ

開発環境

PHP(8.0.2)
Laravel(9.19)
Python(3.8.10)

Pythonの実行はexec関数

PythonをLaravel上で使用するのに、いろいろ調べたところ、PHPのexec関数で実行できるということでした。
まずはPythonファイルを作成。
私はappディレクトリ内にpythonディレクトリを作りその中にファイルを作りました。

import sys
import pandas_datareader.data as web

code = sys.argv[1]+'.T'
start_date = sys.argv[2]
start_open_or_close = sys.argv[3]
end_date = sys.argv[4]
end_open_or_close = sys.argv[5]

df = web.DataReader(code, 'yahoo', start_date, end_date)

start_price = df.loc[start_date,start_open_or_close]
end_price = df.loc[end_date,end_open_or_close]
yield_price = end_price - start_price
yield_ratio = round(yield_price/start_price*100,1)
high = df['High'].max()
low = df['Low'].min()
print(start_price)
print(end_price)
print('{:+}'.format(yield_price))
print('{:+}'.format(yield_ratio))
print(high)
print(low)

今回はpandas_datareaderライブラリを使って、コードと日付を受け取り、株価等を返したかったので、
①ライブラリをインポート
②sys関数で引数をとる
③実行メソッドを書く
④print関数で出力
を行いました。

そしてLaravelのControllerでexec関数を使いPythonファイルを実行し、返ってきた値をsessionに入れています。

    public function start(Request $request)
    {
        $request->validate([
            'code' => 'required | numeric',
            'start_date' => 'required | date | before_or_equal:today |  before_or_equal:end_date',
            'end_date' => 'required | date | before_or_equal:today | after_or_equal:start_date',
	    ]);

	    $path = app_path() . "/python/test.py";
        $code = $request->code;
        $star_date = $request->start_date;
        $start_open_or_close = $request->start_open_or_close;
        $end_date = $request->end_date;
        $end_open_or_close = $request->end_open_or_close;
        $command =  "/usr/bin/python3 " . $path . " $code" . " $star_date" . " $start_open_or_close" . " $end_date" . " $end_open_or_close";
	    exec($command, $output);

        if (empty($output)){
            return back()->withInput()->with('no_data', '銘柄コード、日付を正しく入力してください');
        }
        $result = [
            'start_price' => $output[0] ,
            'end_price' => $output[1] ,
            'yield' => $output[2] ,
            'yield_ratio' => $output[3] ,
            'high' => $output[4] ,
            'low' => $output[5] ,
        ];
        $inputs = $request->except('_token');

        $request->session()->put($inputs);
        $request->session()->put($result);

        return view('analyze.result');
    }

これで銘柄コードと日付を渡せば株価や暴落率が返ってくる。
問題はここからです。

pip問題

ローカル環境では動作するのに、コンテナ内では上手く返ってこない。
原因はLaravel sailのdockerコンテナ内にpythonはインストールされているものの、pipがインストールされていなかった。
そこでコンテナ内に入ってpipをインストールしようとしました。

sail shell

そこでaptを実行しようとしても権限エラー

sail root -shell

でルートユーザーでログインできたので、

apt update
apt upgrade
apt install pip

で解決。
そして必要なライブラリをpipインストール

docker fileの編集

コンテナ内で直接pipとライブラリをインストールしてもコンテナを停止して再開したら消えています。

そこでdocker fileを編集しました。

sail artisan sail:publish

でルートディレクトリにdockerファイルの入ったディレクトリが出現。

そこにapt-getのところにpipを追加。

さらに、

RUN pip install ライブラリ名

を追加。

sail build --no-cache

でコンテナを再構築すれば、毎回コンテナに入ってインストールしなくて済みました。

aws内でのエラー

awsにデプロイする際にもつまづきがありました。
デプロイ後値がなにも返ってこない。
ひも解いていくと、PythonファイルでModuleNotFoundErrorとなっていました。
pipインストールしてpip listで確認してもインストールされているのに。

どうやらimportする際の探しにいくpathが問題のようで、
sudoをつけてpipインストールすると解決しました。
これについてももう少し調査の必要があります。

まとめ

言語の組み合わせはなかなか情報が少なくて難しい。
なかなかハードルが高く、無理やりな部分もありますが勉強になりました。

1
0
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
1
0