質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1211閲覧

自動起動された対話型PythonスクリプトとのWebブラウザ経由での対話方法

dysk

総合スコア1

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

3クリップ

投稿2021/06/14 02:18

編集2021/06/14 05:16

質問概要

対話を含むあるPythonスクリプトをサーバで実行し、
別端末から、Webブラウザ経由で対話を行いたいです。
どうすれば実装できるのか、検索キーワードすらわからずにいます。
「これを使えば実装できるのでは?」「代替としてこんな実装ならできる」
といった内容をご教授頂きたいです。
欲を言えば、フィージビリティが見えるようなサンプルコードにたどり着けると嬉しいです。

質問者の技術・経験

Webアプリケーションの開発経験なし。
バック系の開発経験はありますが、
技術全般について知識は浅いです。
Python学習期間は3か月程度。

現在できていること

  • 対話部分をinput()で実装したPythonスクリプトが書けている。
  • Teratermを使い、上記スクリプトの実行・対話ができている。

実現したいこと

上記でできている対話部分を、Webブラウザ経由で行うことです。

前提として、スクリプト実行(起動)は、対話部分と異なり、自動実行とする想定です。
スクリプト実行中、対話が必要となったら処理を一時停止し、入力待ち状態を維持。
Webブラウザ経由でその入力待ちに対して入力を返してあげると、スクリプトが再開する、
というイメージです。

難しく思っていること

「現在できていること」2点目では、
スクリプトを起動したSSH接続(Teraterm)があり、
そのままそのウィンドウに入力を返してあげれば対話ができます。

しかしながら、実現したい内容としては、
起動時には対話者とスクリプトとをつなぐウィンドウはないため、
スクリプト実行中(入力待ち)に対して入力を返してあげる方法がイメージできません。

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

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

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

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

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

udon-ken

2021/06/14 03:42

何をしたいのか?あなたの技術・知識レベルがどの程度なのか?がよく分からないので回答のしようがない気がします。 何をしたいのか沢山書かれてはいますが、かなり分かりづらいです。 おそらくですが、分割して階段を登るように一つ一つ解決していく方がいいと思います。
dysk

2021/06/14 05:22

投稿ありがとうございます。 再度整理して書き直してみました。
udon-ken

2021/06/14 09:11

うーん・・・ まず、現在できている事については、Teraterm云々は関係なくて(おそらくプログラムをサーバーに置いて実行できているというだけの意味でローカルマシンでも同じなので特に意味は無い?)、単純に「プログラムが質問した事に対して返答を入力できるプログラムができている」というだけの意味ですかね?多分。 で、、例えば何からのバッチ処理をするプログラムがあって、そいつが実行中にユーザーに対して何らかの問い合わせ(例えば「あと○分程かかりそうですが続行しますか?)をしたいというような事ですか?? それをブラウザに「いきなり」出すとかそういう事でしょうか? おそらくですね…「既存の○○に「かなり」似た仕組み」というのが言えるかどうかがポイントになると思います。 今まで見た事ないようなものが作れる、または自分が思いついたものが独創的で今まで誰もトライしていないものである可能性はかなり低いです(たいていの仕組みはどこかで既に使われていて、そうでないものは技術的に不可能、または実用上不可能・無意味な事がほとんど)。 上記の、「ブラウザにいきなり出したいのかな?」という私の推測が正しいのなら、「今までに閉じてたブラウザがいきなり開いて入力を求められた事あるかな?」とか、「そんな事があったらまずくない??」とか、思考をめぐらせていくと、「そういえば、あの仕組みはわりと遠くないからそれを応用できないかな?」とか繋げていって考えていくとなんとかなる場合があるかなあ。
dysk

2021/06/14 09:41

丁寧なご回答ありがとうございます。 現在できていることについて、ご認識の通りです。 >例えば何からのバッチ処理をするプログラムがあって、そいつが実行中にユーザーに対して何らかの問い合わせ(例えば「あと○分程かかりそうですが続行しますか?)をしたいというような事ですか?? こちらについても、私のしたいことと合っています。 >それをブラウザに「いきなり」出すとかそういう事でしょうか? こちらは、いきなりブラウザが開かれることは考えていませんでした。 例えば、 バッチ処理のプログラムの実行状況をブラウザで参照できる画面を用意し、 「ユーザーに対して何らかの問い合わせをしている」ステータスが表示されるようにする。 このステータスの場合のみ、「対話画面を開く」ボタンが表示され、これを押すと対話画面が開く。 といった具合を一例として想像していました。 一般的なサービスで似た仕組みが浮かばず、Teraterm云々によってそこを表現したかった次第です。 上記「『対話画面を開く』ボタンが表示され、これを押すと対話画面が開く。」とした例で、 ここで表示されてほしい対話画面は、  バッチプログラムが input() 行に到達して入力待ち状態になっているTeraterm画面 と同じものです。 (input()ではそれはできないかもしれませんが、イメージです。)
otn

2021/06/14 10:12

たとえば5人がウェブでアクセスした場合、 1.5人それぞれ独立して操作したい。つまり対話プログラムが5多重で起動された状態にしたい 2.対話プログラムは1つだけ動いて、5人の入力が混ざって入力される のどちらかも不明ですね。 いずれにせよ、結構面倒くさい処理になりそうです。
dysk

2021/06/14 12:32 編集

ご回答ありがとうございます。 考慮不足で申し訳ありません。 小規模なチーム内での利用を考えていたため、 複数人からの同時アクセスについて考えられていませんでした。 今回は多重で受け付けたいわけではないため、 直球で回答するならば、同時に1人しか対話できないよう排他処理する、となります。 しかしながら、おっしゃるように面倒なことになりそうな感じがあり、 そもそも質問のようなやり方でなければダメなのか、再考の余地がありそうです。。 実現したいことをさらに手前のところをご説明すると 基本的にはバッチ処理としてプログラムを自動実行、自動完了させたいのですが、 処理対象データによっては途中で異常値を出してしまう場合があります。 このとき、処理内容上、単純な中止や再実行といった対応が好ましくなく、 かといって異常のパターンとそれらに対する分岐処理を網羅的にコード化することもできず、 したがって、人との対話式へ移行する方式をとりたい状況です。 対話内容についても、選択肢で網羅できるものではなく、自由入力が必要です。 やはり、上記内容に直接フィットするような技術というものはなく、 いろいろな工夫と組合せによる実現が必要なのでしょうか?
guest

回答2

0

ベストアンサー

何か入力して、結果を受け取り、ということの繰り返しであれば、中継プロセスを置けば十分可能だと思いますが、一回ごとの結果の終わりを知ることが出来るかどうかがキーだと思います。

人間同士の対話を考えてみると分かりますが、質問して、何か文章が返ってきたとして、その文で終わりなのか、まだ後に文が続くのかの判断ができるか?というようなことです。

中継プロセスとしては、対象プログラムをpopenで起動しておいて、外部からの入力をソケットで受け付けて、popenに書き込み、結果を「終わりまで」受け取ったら、入力元に返す。

別解としては、ApacheやNginxのような汎用のHTTPサーバーを使うんじゃなくて、対象プログラムをpopenで制御するPythonプログラムの中に、HTTPサーバーを組み込んでしまう。その場合は多分コルーチン機能を使うとわかりやすくなる気がします。

投稿2021/06/14 13:35

otn

総合スコア85901

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

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

teamikl

2021/06/15 12:53

コルーチン機能を使うは(必須ではありませんが)良案だと思います。 理由: - 「標準入力からの待ち受け」の部分を抽象化出来るので、  プログラム内で入出力を自由に組み合わせることができる。(プロセス・パイプより自由度高) - 処理の中断・再開を表現できる。 Python では、「コルーチン」は非同期I/Oライブラリの用語として定着してるので、 用語で検索するなら「ジェネレーター」もしくは、 用途から察すると「双方向ジェネレーター」が該当します。 懸念は、実践的なサンプルコードが少ない点。 自分にとっては、難易度的に、Pythonを学習していて割と中盤~後半にでてきそうな印象です。
dysk

2021/06/16 00:25

>otn様 ご回答ありがとうございます。 popen、その他登場するキーワードについても知識がなく、調べてはいるものの、 頂いた解決方法の理解が浅い状態でのコメントとなる点、ご容赦ください。 「対象プログラムをpopenで起動しておく」ことで、 popenで対象プログラムを起動するプログラム(以下、起動プログラム)では、 対象プログラムが入力待ちで止まっているのか、終わっているのかの判定ができ、 また、対象プログラムの標準入力にデータを送信することができる。 ---ここまで合っていますでしょうか?① 次の段階として、2案挙げて頂いている。 1.ソケットで、Webブラウザからの入力を起動プログラムへ通す 2.起動プログラムにHTTPサーバを組み込むことで、Webブラウザの入力をそのまま起動プログラム内で扱える (ソケットを利用したこともないため、こちらも調べながらでイメージがぼんやりです。。) ---ここまで合っていますでしょうか?② ①②が合っている前提ではありますが、 2案のいずれかを選択する場合、考慮すべき違いはありますでしょうか?
dysk

2021/06/16 02:16 編集

>teamikl様 補足ありがとうございます。検索ワードのご提示助かります。 otn様の「対象プログラムをpopenで制御するPythonプログラムの中に、HTTPサーバーを組み込んでしまう。その場合は多分コルーチン機能を使う」という案を推して頂いていると理解しました。 ご提示頂いた「双方向ジェネレーター」で検索したところ、 yieldを右辺に持つ式を含むジェネレータと、そのジェネレータの呼び出し元でsend()を使用しているサンプルコード を見つけることができましたが、言わんとしているものはこれで合っていますでしょうか? (用途にマッチするような気はしています。頭の中で具体的にすべてがつながったわけではありませんが。。)
otn

2021/06/16 02:52

> popenで対象プログラムを起動するプログラム(以下、起動プログラム)では、 対象プログラムが入力待ちで止まっているのか、終わっているのかの判定ができ、 プログラムが終了してしまえばわかりますが、プログラムが実行中の場合は、処理中か、結果出力途中か、出力完了して次の入力待ちかなどは不明です。 なので、 > 一回ごとの結果の終わりを知ることが出来るかどうかがキーだと思います。 > 人間同士の対話を考えてみると分かりますが、質問して、何か文章が返ってきたとして、その文で終わりなのか、まだ後に文が続くのかの判断ができるか?というようなことです。 と書いてます。「応答出力は常に1行」とかでないのであれば、応答内容の文字列を見て、終わっているのかどうか判断が必要です。時間で判断(2秒待ったけど続きが来ないので終わりと判断)も出来るかも知れませんが、うまく行かないかも知れません。 > また、対象プログラムの標準入力にデータを送信することができる。 これは出来ます。 > 次の段階として、2案挙げて頂いている。 > 1.ソケットで、Webブラウザからの入力を起動プログラムへ通す > 2.起動プログラムにHTTPサーバを組み込むことで、Webブラウザの入力をそのまま起動プログラム内で扱える これは書かれている範囲では合ってます。2はジャストアイデアなので、中身はあまり考えてません。 また、Pythonでのコルーチン機能について調べたことはないので、私の書いた「コルーチン」は一般IT用語でのコルーチンです。
guest

0

「ブラウザ経由で対話」のみに反応すると、

  • jupyter notebook (ブラウザでの対話実行環境)や
  • xtermjs (ブラウザで動く端末) cloud IDE 環境によく組み込まれてる端末のfront-end
  • click_web (ブラウザから実行) 起動時パラメータのみ。実行後の対話は×

といった枠組みはあります。
バッチ処理ということなので、jupyter + papermill が代替候補。
ですが、詳細は把握してないので細かい部分で、適してるかどうかは解りません。
「実行後の対話」辺りが課題になりそう。

何らかの手段でバッチ処理のスクリプトと通信することになりますが、

  • プロセス間通信、パイプで行う、
  • 仮想端末(pty)経由で標準入力に送る (既存の実行済みプロセスに対して、外部から入力)

 バッチ処理を実行してるホスト側がwindowsだと少し面倒です。クロスプラットフォーム用途では△

  • バッチ処理のスクリプトに手を加えられるなら、他の選択肢も取れます。

投稿2021/06/15 12:46

teamikl

総合スコア8760

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

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

dysk

2021/06/16 02:15 編集

>teamikl様 ご回答ありがとうございます。 バッチ処理のスクリプトとの通信についてですが、 >バッチ処理を実行してるホスト側がwindowsだと少し面倒です。 →ホスト側はLinux想定です。 >バッチ処理のスクリプトに手を加えられるなら、他の選択肢も取れます。 「バッチ処理のスクリプト」とは、私が「現在できていること」に記載しました 「対話部分をinput()で実装したPythonスクリプト」を指していると理解しました。 上記のバッチスクリプトに手を加えることは可能です。 バッチスクリプト視点での命題として、 バッチ実行中にWebブラウザからの入力を受け取る、というものがあり、 それを実現するためにスクリプト内外をどのようにしていけばよいか、 の解決策を模索している状況です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問