2012-05-18 20 views
6

मैं एफसीजीआई के साथ पायथन फ्लास्क + nginx का उपयोग कर रहा हूँ।पायथन फ्लास्क + 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

responseflask.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 में यह समस्या नहीं है।

संबंधित मुद्दे