2012-05-18 6 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

flask.make_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에는이 문제가 없습니다.