2012-05-18 7 views
6

私はFCGIでPython Flask + nginxを使用しています。Python Flask + nginx fcgi - 大きなレスポンスを出力しますか?

リクエストによっては、大きな回答を出力する必要があります。通常、これらの応答はソケットから取得されます。現在、私は次のような応答をしています。

response = [] 
while True: 
    recv = s.recv(1024) 
    if not recv: break 
    response.append(recv) 
s.close() 
response = ''.join(response) 

return flask.make_response(response, 200, { 
              'Content-type': 'binary/octet-stream', 
              'Content-length': len(response), 
              'Content-transfer-encoding': 'binary', 
              }) 

問題は実際には必要ありません。また、ソケットからフェッチする正確なレスポンス長を決定する方法もあります。だから私は、HTTPヘッダーを送信し、メモリから収集してnginxに(おそらく何らかの種類のストリームによって)供給するのではなく、ソケットから直接出力を開始する良い方法が必要です。

このような一般的な問題は解決できませんでした。どのように達成されるでしょうか?

ありがとうございました!

答えて

10

responseの場合flask.make_responseは反復可能ですが、応答を生成するために反復され、各ストリングはそれ自身の出力ストリームに書き込まれます。

これは、繰り返し処理されたときに出力を生成するジェネレータを返すことができることを意味します。コンテンツの長さを知っていれば、それをヘッダーとして渡すことができます。

簡単な例:

from flask import Flask 
app = Flask(__name__) 
import sys 
import time 
import flask 

@app.route('/') 
def generated_response_example(): 
    n = 20 
    def response_generator(): 
     for i in range(n): 
      print >>sys.stderr, i 
      yield "%03d\n" % i 
      time.sleep(.2) 

    print >>sys.stderr, "returning generator..." 
    gen = response_generator() 

    # the call to flask.make_response is not really needed as it happens imlicitly 
    # if you return a tuple. 
    return flask.make_response(gen ,"200 OK", {'Content-length': 4*n}) 

if __name__ == '__main__': 
    app.run() 

あなたがこれを実行すると、ブラウザでそれをしようとした場合、あなたはそれがそうなので素敵incemental数...

は(コンテンツタイプが設定されていない表示されるはずですもし私がそうするなら、私のブラウザはページをレンダリングする前にコンテンツ全体がストリーミングされるまで待つでしょう。wget -qO - localhost:5000にはこの問題はありません

関連する問題