web-dev-qa-db-ja.com

非メッセージキュー/単純なロングポーリングPython(およびFlask)

計算を実行してグラフを生成する小さなWebインターフェイスのロングポーリングを実行する簡単な(つまり、メッセージングキューを処理するために別のサーバーをセットアップする必要がない)方法を探しています。これは私のWebインターフェイスが行う必要があることです:

  1. ユーザーがWebインターフェイスでグラフ/データを要求する
  2. サーバーはいくつかの計算を実行します。
  3. サーバーが計算を実行している間、小さなコンテナーが計算の進行状況で更新されます(AJAX/jQueryを介して)(printを使用してコンソルで行うのと同様です(つまり、print '密度関数の計算...'))
  4. 計算が終了し、グラフがユーザーに表示されます。

計算はすべてサーバー側で行われるため、これを簡単に設定する方法がよくわかりません。明らかに、ポーリングを処理するためにREST APIをセットアップする必要があります。これは、Flaskでは簡単です。ただし、実際の更新を取得する方法がわかりません。複雑ではありますが、明らかです。この目的のための解決策は、メッセージングキューを設定し、長いポーリングを実行することです。ただし、これがこれほど単純なものに適切なアプローチであるかどうかはわかりません。

これが私の質問です:

  1. ファイルシステムを使用してこれを行う方法はありますか?パフォーマンスは大きな問題ではありません。 AJAX/jQueryはファイルからメッセージを見つけることができますか?進行状況を.jsonファイルに保存しますか?
  2. 酸洗いはどうですか? (私はpickle化についてあまりよく知りませんが、メッセージdictをpickle化して、ポーリングを処理しているAPIによって読み取ることができるかもしれません)。
  3. ポーリングは正しいアプローチでもありますか?これを処理するためのより良いまたはより一般的なパターンはありますか?

この種のことはウェブ上で一般的であることを知っているので、私は物事を複雑にしすぎているような気がします。計算が行われている間(たとえば、Google Analyticsで)、何かが起こっていて、小さな「loading.gif」画像が実行されているのをよく目にします。

ご協力いただきありがとうございます!

25
aaronlevin

FlaskとjQueryだけを使用して、このようなアプリをいくつか作成しました。その経験に基づいて、あなたの計画は良いと思います。

  1. ファイルシステムを使用しないでください。JavaScriptのセキュリティ問題/保護に遭遇します。万が一、合理的な回避策が見つかった場合でも、ポータブルまたはスケーラブルなものはありません。代わりに、Flaskなどの小さなローカルWebサービスフレームワークを使用してください。

  2. 酸洗いしないでください。JSONを使用してください。これはウェブアプリの言語であり、RESTインターフェースです。jQueryとチャートやグラフなどを描画するためのこれらの素晴らしいjQueryベースのプラグインはJSONを期待します。使いやすく、人間が読みやすく、小さい場合-スケールアプリ、他の場所に行く理由はありません。

  3. 達成したいことにはロングポーリングで問題ありません。純粋なHTTPベースのアプリにはいくつかの制限があります。そして、WebSocketやSocket.IOのような同様のソケットっぽいレイヤーは「未来」です。しかし、私の経験では、サーバー側の実装の優れた単純な例を見つけることは困難でした。私は一生懸命に見えました。 Node.js、REDIS、およびその他のミドルウェアをセットアップする必要のある例はたくさんあります。しかし、なぜ2つまたは3つの別個のミドルウェアサーバーをセットアップする必要があるのでしょうか。それはばかげています。 Flaskのようなシンプルで純粋なPythonWebフレームワークでのロングポーリングはIMOへの道です。

コードはスニペットより少し多いので、ここに含めるのではなく、簡単な例を bitbucketのMercurialリポジトリ に入れました。これは、自由に確認、コピー、または複製できます。 3つの部分があります:

  • serve.py Python/Flaskベースのサーバー
  • templates/index.html 98%HTML、2%テンプレートファイルFlaskベースのサーバーはHTMLとしてレンダリングします
  • static/lpoll.jsjQueryベースのクライアント
43
Jonathan Eunice

ロングポーリングは、Web Socketsのシンプルで自然なサポートがほとんどのブラウザーに導入される前、およびFlaskアプリと簡単に統合される前に、合理的な回避策でした。しかし、2013年半ばにWebSocketが登場しました。サポートは長い道のりを歩んできました。

ここに例があります 、上記と同様ですが、FlaskとWebSocketsを統合しています。 gevent および-のサーバーコンポーネント上で実行されます。 gevent-websocket

この例は、WebSocketの傑作を意図したものではないことに注意してください。 lpoll構造を多く保持しているため、比較しやすくなっています。ただし、Webアプリの応答性、サーバーオーバーヘッド、および対話性はすぐに向上します。

Python 3.7 +の更新

最初の回答から5年で、WebSocketの実装が容易になりました。 Python 3.7の時点で、非同期操作は主流の有用性に成熟しています。Python Webアプリは完璧なユースケースです。JavaScriptやノードと同じように非同期を使用できるようになりました。 .jsには、「側の並行性」の癖や複雑さのいくつかが残っています。特に、 Quart をチェックしてください。FlaskのAPIと、いくつかのFlask拡張機能ですが、非同期が有効です。主な副作用は、WebSocket接続をHTTP接続と並行して適切に処理できることです。例:

from quart import Quart, websocket

app = Quart(__name__)

@app.route('/')
async def hello():
    return 'hello'

@app.websocket('/ws')
async def ws():
    while True:
        await websocket.send('hello')

app.run()

クォートは、Python 3.7にアップグレードする多くの大きな理由の1つにすぎません。

10
Jonathan Eunice