🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

3回答

3578閲覧

Rails5からPythonスクリプトを実行したい

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2019/10/28 07:15

編集2019/10/30 02:15

##実現したいこと
Railsアプリケーションのユーザ側から、3つのファイル提供を受け、inputとして受け取る。(ファイルはDBに保存せずに、使い捨て?のような形をとりたい。)
そして、link_toメソッドで「実行」をクリックすると、Pythonスクリプトが実行され、outputがViewに出力されるようにしたい。
※link_toメソッドでなくても、ページ遷移に伴ってpythonスクリプトを実行したい。

イメージ画像
イメージ説明

####しかし
・アプリケーション内のどのディレクトリにPythonスクリプトファイルを置くべきかわからない。
・どこからPythonスクリプトを呼び出せば良いか確信が持てない。link_toメソッドで飛ばしたコントローラのアクション内か?
・受け取るファイルを、Pythonスクリプト内に反映させるにはどうしたら良いのか?

###参考にした情報と学んだ内容(1時間程度調べてみました。番号は学習した段階を表しています。)
1,teratailから得られた情報
→そもそも、RailsからPythonスクリプトを実行できるかどうかすらわからなかったが、この記事を閲覧することで、呼び出し自体は難なく行うことができることを確認。
2,Rubyで外部コマンドを実行して結果を受け取る方法あれこれ
→Qiitaの記事。どんぴしゃりの内容だと感じ、閲覧したものの、情報の価値がわからないという体たらく。しかし、ここから得られることは多そうだと感じた。
3,railsのwebシステム内にpythonのスクリプトを共存させることは可能でしょうか?
→これまたどんぴしゃりの内容だ!!と感じて閲覧したものの、読んでも書いてあることがわからないので、それぞれの言葉を確認しながら調べている最中。
とりあえず、この回答を信頼して、外部スクリプトの実行を体験したことがない自分は、IO.popenを使用するのが現段階では難易度的にベストと感じ、調べている最中です。

###質問内容
IO.popen公式ドキュメント?
→何が書いてあるのか全くわからん。という状態です。外部スクリプトの実行に関する内容があると想定していたのですが・・・
このサイトを理解するために何をするべきでしょうか?というのが今回の質問です。お答えいただけると幸いです。

###ベストアンサーの選択について
ご回答いただいた3人の識者の方のおかげで、自分が実現したいことに対して、大まかな方針を立てることが可能になりました。
まず、3人の識者の方にお礼申し上げます。ありがとうございました。
さて、本題についてですが、「質問内容」に対してもっとも的確にお答えいただいた方を選択することにしました。
今後ともよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

前提:Pythonをインストールしてパスを通しておくこと。

  1. ファイルを任意の場所に配置する。
  2. 配置した場所を "sample.py" のところに記述する。
  3. 標準出力は stdout, 標準エラー出力は stderr に格納されるのでそれを View に表示する。

Ruby

1require 'open3' 2 3stdin, stdout, stderr, wait_thr = *Open3.popen3("python sample.py") 4 5puts stdout.read # => 標準出力 6puts stderr.read # => 標準エラー出力 7

参考:
パス (path)とは
「PATH を通す」の意味をできるだけわかりやすく説明する試み
Rubyから外部プログラムを起動する方法まとめ
Open3.#popen3

投稿2019/10/28 12:12

編集2019/10/28 12:13
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/10/28 14:25

簡潔なご回答ありがとうございます! 1,Pythonプログラムにユーザーからファイルの提出を求めているのですが、その場合の処理についてはどのようにするべきでしょうか? 2,ページの遷移に従ってプログラムを実行したいので、コントローラで実行することを念頭においているのですが、そうなると、 >stdin, stdout, stderr, wait_thr = *Open3.popen3("python sample.py") この部分で代入している部分をインスタンス変数として扱わないとViewに渡せないと思います。これは以下のようにすれば良いのでしょうか? コントローラ @stdin, stdout, stderr, wait_thr = *Open3.popen3("python sample.py") View @stdout.read => 標準出力 @stderr.read => 標準エラー出力
退会済みユーザー

退会済みユーザー

2019/10/29 12:01

私はRailsを使ったことがありません。 1.既存のコードを参考にします。 以下の記事の「CSVのアップロード機能の実装」までを参考とします。 CSVの読み込みは行わずにfile.pathをpythonに渡せば動くのではと思います。 RailsでCSV/Excel/OpenOfficeのアップロード機能の実装方法 https://ruby-rails.hatenadiary.com/entry/20141120/1416483136 2.既存のコードを参考にします。 インスタンス変数にして動くならたぶんそれでよいと思います。 ビューの作成とデータの受け渡し https://www.javadrive.jp/rails/ini/index5.html
退会済みユーザー

退会済みユーザー

2019/10/30 02:08

ご回答ありがとうございます。 参考にして学習いたします。
guest

0

ベストアンサー

Pythonプログラムの出力をプログラムで扱わないのであれば、systemでもいいのですが、標準出力を変数に取得したいということであれば、バッククォートによる実行が必要です。

Ruby

1system("python -V") # バージョン文字列を標準出力に出す 2 3python_version = `python -V` # バージョン文字列を変数に取得

また、Pythonプログラムの標準入力になにかを渡したいとか、標準出力を順次読み取りたいとかであれば、参考にされたページにある、IO.popenとかopen3モジュールとかを使う必要があります。

→何が書いてあるのか全くわからん。という状態です。外部スクリプトの実行に関する内容があると想定していたのですが・・・

外部スクリプトというか、外部コマンドの実行ですね。サンプルとして、標準入力を標準出力に出すコマンドcatコマンドの実行例と、ファイル一覧を出すlsコマンドの実行例が載っていますが、これをpythonに変えるだけです。

このサイトを理解するために何をするべきでしょうか?というのが今回の質問です。お答えいただけると幸いです。

少なくとも、popenを理解するには、ファイルディスクリプタ(標準入力、標準出力、標準エラー出力、その他一般のファイルディスクリプタ)、(ファイルディスクリプタの)リダイレクト、パイプ、プロセスなどについての知識がある程度ないと難しいと思います。
Linux入門のやや難しめの物を読むと良いのではないでしょうか。適度な本があるかどうか知りませんが。

「Unixプログラミング」「Linuxプログラミング」と言ったシステムコールを使うプログラミングの本を読めば十分ではあるのですが、「RubyからPythonを起動したい」レベルの話にはそこまで必要ではないと思うので、この手の本を読むのは手間をかけすぎという気がします。

投稿2019/10/28 08:47

otn

総合スコア85882

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/10/28 14:18

Pythonプログラムには、ユーザ側から3つのファイルの入力を求める予定です。それをPythonプログラムに渡しプログラムを実行させます。 出力は単にViewで表示できれば良いという状況です。(現状では、ですが・・) つまり、systemでも大丈夫という認識で大丈夫でしょうか? >Pythonプログラムの標準入力になにかを渡したい あ、ダメそうですね。調べた内容通り、popenを理解しないといけない流れになる気がします。 >少なくとも、popenを理解するには、ファイルディスクリプタ(標準入力、標準出力、標準エラー出力、その他一般のファイルディスクリプタ)、(ファイルディスクリプタの)リダイレクト、パイプ、プロセスなどについての知識がある程度ないと難しいと思います。 「ファイルディスクリプタ」という言葉そのものを聞いたことなかったです。勉強しないといかんということですね。 >「Unixプログラミング」「Linuxプログラミング」と言ったシステムコールを使うプログラミングの本を読めば十分ではあるのですが、「RubyからPythonを起動したい」レベルの話にはそこまで必要ではないと思うので、この手の本を読むのは手間をかけすぎという気がします。 少し、これらの本について調べてみたいと思います。
otn

2019/10/28 14:41

「cat というプログラムに、その標準入力からデータを与え、その標準出力からデータを得る」 という短いサンプルが公式リファレンスのIO.popenに載っているので参考になるかと思います。 > 「ファイルディスクリプタ」という言葉そのものを聞いたことなかったです。勉強しないといかんということですね。 サンプルをもとにpopenを使うだけであれば、「標準入力、標準出力、標準エラー出力」が理解できていれば十分かと思います。あと、リダイレクトの概念と。 systemは実行だけするもの。IO.popenやopen3ライブラリは実行と入出力のリダイレクトを行います。 > 少し、これらの本について調べてみたいと思います。 いや、回答に書いた通り、「手間かけすぎ」だと思いますよ。 とにかく、「単純なPythonプログラム」を利用するコードをIO.popenで書いてみましょう。
退会済みユーザー

退会済みユーザー

2019/10/30 02:09

ご回答ありがとうございます。 返信が遅れまして、申し訳ないです。 >とにかく、「単純なPythonプログラム」を利用するコードをIO.popenで書いてみましょう これをまずやってみて、できたら先に進もうと思います。ありがとうございました。
guest

0

RailsからPythonを実行しようと思ったことがないのですが、パッと思いつくのは
Kernel.#systemでシェル経由でPythonスクリプトを実行することですかね。

IOクラスはファイルを読み込んだり書き込んだりしたりするときに使うものなので

RailsからPythonスクリプトを実行

には適していないかなと思います。

さて、質問への回答ですが

このサイトを理解するために何をするべきでしょうか?

Rubyをある程度理解している前提であれば、実際にサンプルコードを書いて色々試してみるのが一番だと思います。

投稿2019/10/28 07:23

Mugheart

総合スコア2349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/10/28 07:32 編集

ご回答ありがとうございます。 IOクラスはそのような扱いなのですね。勉強になります。 ご回答についてはそうですね。実際にサンプルコード書くのがもっとも勉強になります。 少し自分に勉強不足の節があるので、「Rubyをある程度理解している」、この基準に明確なものがあれば教えていただけると嬉しいです。 いただいたご回答では、system(~.py)といった形で実行するのがベストとのことですね。 実際に、コードを書いて検証してみます。 質問の主旨と少し外れますが、 ユーザから受け取ったinputファイルをPythonスクリプト内に反映させるのは、どうしたら良いでしょう? ここも少し想像がつかなくて困っています。別質問として立てた方がよければ、別質問として立てようと思います。
Mugheart

2019/10/28 07:34

> Rubyをある程度理解している 明確な基準と言われると困ってしまいますが、初心者マークがついていなかったのである程度理解している自負のある方かと思ったまでです。 そうですね、マニュアルに出てくるオプションや固有のメソッド以外のコード(Rubyを書いていて幅広く使われるようなメソッド)の意味はわかるといったところでしょうか...。 標準入力からファイルパスを渡してやればいけるかと思います。
退会済みユーザー

退会済みユーザー

2019/10/28 07:41

無理な質問をしてしまったようで、申し訳ないです。 ご自身の基準で結構です、ありがとうございました。 >マニュアルに出てくるオプションや固有のメソッド以外のコード(Rubyを書いていて幅広く使われるようなメソッド)の意味はわかるといったところでしょうか...。 「たのしいRuby」のような参考書に書いてあるメソッド等々がわかれば、という理解で良いでしょうか? パスについて、ちょっと勉強してきます。
Mugheart

2019/10/28 07:45

たのしいRubyを読んだことがないのですが、概ねその理解で良いと思います。 パスというのはファイルのある位置です。 dir/dir/file みたいなやつのことです。よく見るはずですよ。
退会済みユーザー

退会済みユーザー

2019/10/28 07:56 編集

ありがとうございます。実はかしこまって言語を勉強したことがない(その都度ググって解決すればいいと思っていた)ので、この機会を生かして勉強してみようと思います。 パスそのものについては知っているのですが、inputから通す方法がちょっとイメージつかなくて、わからないという感じです。直感的な悩みとしては、 言語違うな。inputで受け取ったファイルをPython側に送るときに、Python側を書き換える必要あるけど、どう書き換えるべきかな。というところでイメージつきにくいです。 相対パス、絶対パスについては理解しています。
Mugheart

2019/10/28 07:59

ファイルをフォームで送信すると、それを受け取ったparamsの中に送信したファイルのTempfileオブジェクトがあると思います。 そのTempfileオブジェクトは一時ファイルみたいなものなんですが、それに対してpathメソッドを実行するとその一時ファイルの置いてあるパスが取得できます。
退会済みユーザー

退会済みユーザー

2019/10/28 08:17 編集

なるほどです。イメージが掴めてきました。 コピペの要領と似てる感じですね。ファイルがクリップボードにあるようなイメージでいいでしょうか? ちなみに、pathメソッドというのは何を意味しているのでしょうか? 「"Rails5" and "pathメソッド"」で検索をかけると、主に以下のようなサイトが出てきました。 https://marketing-web.hatenablog.com/entry/rail4_get_url https://qiita.com/YosukeItabashi/items/7ea8d51d41dab2eb0e9d 2つ目のサイトは、redirect toメソッドの引数として、「rails routes」から確認できたpathの引数に、インスタンス変数を指定して、詳細ページに飛ばそうとしているだけのようです。これだけですと、よくイメージがつきません・・・。
Mugheart

2019/10/28 08:17 編集

> ファイルがクリップボードにあるようなイメージでいいでしょうか? そういうイメージをしたことがないのでなんとも言えません、すみません。 おそらく間違ってはいないとは思いますが、試して違和感があればイメージし直してください。 > 「"Rails5" and "pathメソッド"」で検索をかけると Tempfileで調べた方がいいかもしれないですね。 https://docs.ruby-lang.org/ja/latest/class/Tempfile.html#I_PATH (pathの説明はページの一番下の部分にあたります)
退会済みユーザー

退会済みユーザー

2019/10/28 08:29 編集

イメージ違いでしたか、お恥ずかしいです。おそらく修正するべきですね。 丁寧にリンクまでいただいて、ありがとうございます。確認いたしました。 ファイルのpathをrequestで探すのですね。 https://keruuweb.com/ruby-tempfile%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/ 綺麗に描かれているサイトでも確認してみました。 疑問が湧いてきたのですが、この処理(一番下のpathの説明)は、アプリケーションのどこで行うのでしょうか?画面遷移に伴わせてPythonスクリプトを動かしたい場合は、コントローラでこの処理を書けば良いでしょうか?
Mugheart

2019/10/28 08:36

> アプリケーションのどこで行うのでしょうか? フォームの値を受け取って画面をレンダリングするまでの間で行います。 コントローラで行うのが一番手っ取り早いですが、 場合によってはモデルに書いたりモジュールに切り出したりもします。 どこに書こうがそのコードが実行されれば動きます。 好みというかアプリケーション次第というかこの辺りはFatControllerとかで調べればいいです。 コントローラに処理を書きすぎてしまう問題です。特に問題なければコントローラでもいいと思います。
退会済みユーザー

退会済みユーザー

2019/10/28 13:55

返信が遅くなりすみません。少し体調悪いので、実際に検証するのは明日になりそうです。 内容についてなるほどです。 今回はそこまでコード量が多くないので、コントローラーに記載しようと思います。 あとは、実際に作業します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問