How to set maximum number of pending connections in Flask - python

How can I set a maximum number of pending connections in a Flask application?
E.g.
After I run this code, I can send it two requests at the same time. While the first request is being processed, the other one will wait. When the first one is done, the second one will be processed.
from flask import Flask
application = Flask(__name__)
#application.route("/")
def hello():
for x in range(10000000):
x += 1
return "Hello World!"
if __name__ == '__main__':
application.run()
How can I make it so that when I send two requests at the same time, the first one will be processed and the second one, instead of waiting, will not be able to connected (maybe it will get a some kind of error instead).

You can use Flask with some sort of web server, such as Gunicorn, Nginx or Apache, to accept HTTP requests which it will then operate on. The reason why people run Nginx and Gunicorn together is that in addition to being a web server, Nginx can also proxy connections to Gunicorn which brings certain performance benefits.
Gunicorn is pre-forking software. For low latency communications, such as load balancer to app server or communications between services, pre-fork systems can be very successful. A gunicorn server can;
Runs any WSGI Python web application (and framework)
Can be used as a drop-in replacement for Paster (Pyramid), Django's Development Server, web2py etc.
Comes with various worker types and configurations
Manages worker processes automatically
HTTP/1.0 and HTTP/1.1 (Keep-Alive) support through synchronous and asynchronous workers
You can take help from this blogpost, for setting up a flask application with gunicorn.

Related

Celery - Reuse a broker connection with apply_async()

We have a Django app that uses Celery's apply_async() call to send tasks to our RabbitMQ server. The problem is that when there are thousands of requests coming into the Django app, each apply_async() call will cause it to open thousands of new connections to the RabbitMQ server.
In the Celery documentation for apply_async, there is a connection parameter:
connection – Re-use existing broker connection instead of establishing a new one.
My question is, how can I use it in a Django app? I cannot find any examples of how to use this. We are running Django using Gunicorn, ideally we would like to have each worker create one connection to the broker and re-use it between requests. In this way, the number of connections opened on the broker is limited by the amount of workers running.

Bottle server not responding while calculating

I have a bottle server running on port 8080, using the "gevent" server. I use this server to support some simple "server sent events".
My question is probably related to not knowing exactly how my set up is working. I hope someone can take the time to elaborate on this.
All routes and serving of files from the server is working great, but I have an issue when accessing a specific route "/get_data". This gathers data from the web as well as from some internal data sources. The gathering takes about 30 minutes. While this process is running, I am not able to access any routes on the server, i.e. "/" or "/login". Once the process is finished, everything works again and the database is updated with the gathered information.
I tried replacing the gathering algorithms by a simple time.sleep(60), and while the timer was active, I was still able to access other routes just fine.
This leads to my two questions:
Why am I not able to access the server while this process is running. Is it the port that is blocked (from reading web-information), or maybe it has something to do with threading?
What would be the best way to run a demanding / long process on my server? Preferably I would like to access this from my web app, but I have thought about just putting this in a seperate python file and run this localy on the server, in a seperate instance of python. This process is run at most once per day, maybe as seldom as once per week.
This happen because WSGI handle request/response synchronously.
You can use gunicorn to run your application, it will handle multi requests and response, or you can use other methods described in bottle website:
Primer to Asynchronous Applications

HTTP Streaming with Apache mod_wsgi

I've got an ubuntu-server where I am running multiple web-apps.
All of them are hosted by Apache using named VirtualHosts.
One of them is a Flask app, which is running via mod_wsgi.
This app is serving continuous, unlimited HTTP streams.
Does this eventually block my app/server/apache worker, if enough clients are connecting to the streaming endpoint?
And if yes, are there alternatives?
Other non-blocking wsgi-servers that play nicely with VirtualHosts, a different http-streaming paradigm, or some magic apache mod_wsgi settings?
The core of it looks like:
#app.route('/stream')
def get_stream():
def endless():
while True:
yield get_stuff_from_redis()
time.sleep(1)
return Response(endless(), mimetype='application/json')
If the clients never disconnect, yes, you will eventually run out of processes/threads to handle more requests.
You are more than likely better off using a async framework such as Tornado or Twisted for this specific type of application. Doing async programming can be tricky if you aren't used to that concept.
Some people use coroutine system such as gevent/eventlet, but they also have their own problems you have to watch out for.

flask application timeout with amazon load balancer

I'm trying to use a Flask application behind an Amazon Load Balancer and the Flask threads keep timing out. It appears that the load balancer is sending a Connection: keep-alive header and this is causing the Flask process to never return (or takes a long time). With gunicorn in front the processes are killed and new ones started. We also tried using uWSGI and simply exposign the Flask app directly (no wrapper). All result in the Flask process just not responding.
I see nothing in the Flask docs which would make it ignore this header. I'm at a loss as to what else I can do with Flask to fix the problem.
Curl and direct connections to the machine work fine, only those via the load balancer are causing the problem. The load balancer itself doesn't appear to be doing anything wrong and we use it successfully with several other stacks.
The solution I have now is using gunicorn as a wrapper around the flask application. For the worker_class I am using eventlet with several workers. This combination seems stable and responsive. Gunicorn is also configured for HTTPS.
I assume it is a defect in Flask that causes the problem and this is an effective workaround.
Did you remember to set session.permanent = True and app.permanent_session_lifetime?
The easiest way is to force all connections is to make sure you are using HTTP/1.0 and not adding the header Connection: Keep-Alive to the response.
Please checkout werkzeug.http.remove_hop_by_hop_headers().
Do you need an HTTP load balancer? Using a layer 4 balancer might just as well solve your problem, because it does not interfere with higher protocol levels.

python webtest port configuration?

I am attempting to write some tests using webtest to test out my python GAE application. The problem I am running into is that the application is listening on port 8080 but I cannot configure webtest to hit that port.
For example, I want to use app.get('/getreport') to hit http://localhost:8080/getreport. Obviously, it hits just thits http:// localhost/getreport.
Is there a way to set up webtest to hit a particular port?
With paste.proxy.TransparentProxy you can test anything that responds to an http request...
from webtest import TestApp
from paste.proxy import TransparentProxy
testapp = TestApp(TransparentProxy())
res = testapp.get("http://google.com")
assert res.status=="200 OK","failure....."
In config, and I quote,
port
Required? No, defaults is "80"
Defines the port number to use for
executing requests, e.g. "8080".
Edit: the user clarified that they mean this webtest (pythonpaste's), not the widely used Canoo application. I wouldn't have guessed, because pythonpaste's webtest is a very different kettle of fish, and I quote...:
With this you can test your web
applications without starting an HTTP
server, and without poking into the
web framework shortcutting pieces of
your application that need to be
tested. The tests WebTest runs are
entirely equivalent to how a WSGI HTTP
server would call an application
No HTTP server being started, there is no concept of "port" -- things run in-process, at WSGI level, without actual TCP/IP and HTTP in play. So, the "application" is not listening on port 8080 (or any other port), but rather its WSGI entry points are called directly, "just as if" an HTTP server was calling them.
If you want to test an actual running HTTP server, then you need Canoo's webtest (or other equivalent frameworks), not pythonpaste's -- the latter will make for faster testing by avoiding any socket-layer and HTTP-layer overhead, but you can't test a separate, existing, running server (such as GAE's SDK's) in this way.
I think you're misunderstanding what WebTest does. Something like app.get('/getreport') shouldn't make any kind of request to localhost on any port. The beauty of WebTest is that it doesn't require your app to actually be running on any server.
Here's a quote from the "What This Does" section of the WebTest docs:
With this you can test your web applications without starting an HTTP server, and without poking into the web framework shortcutting pieces of your application that need to be tested. The tests WebTest runs are entirely equivalent to how a WSGI HTTP server would call an application.

Categories

Resources