"""Asynchronous requests in Flask with gevent"""
from time import time
from flask import Flask, Response
from gevent.pywsgi import WSGIServer
from gevent import monkey
import requests
# need to patch sockets to make requests async
monkey.patch_all()
CHUNK_SIZE = 1024*1024 # bytes
app = Flask(__name__) # pylint: disable=invalid-name
app.debug = True
@app.route('/Seattle.jpg')
def seattle(requests_counter=[0]): # pylint: disable=dangerous-default-value
"""Asynchronous non-blocking streaming of relatively large (14.5MB) JPG
of Seattle from wikimedia commons.
"""
requests_counter[0] += 1
request_num = requests_counter[0]
url = 'http://upload.wikimedia.org/wikipedia/commons/3/39/Seattle_3.jpg'
app.logger.debug('started %d', request_num)
rsp = requests.get(url, stream=True)
def generator():
"streaming generator logging the end of request processing"
yield '' # to make greenlet switch
for data in rsp.iter_content(CHUNK_SIZE):
yield data
app.logger.debug('finished %d', request_num)
return Response(generator(), mimetype='image/jpeg')
def main():
"Start gevent WSGI server"
# use gevent WSGI server instead of the Flask
http = WSGIServer(('', 5000), app.wsgi_app)
# TODO gracefully handle shutdown
http.serve_forever()
if __name__ == '__main__':
main()