Python bottle process reach timeout connection - python

I have a problem that after certain amount of time my bottle server is not reachable and you get connection reset- timeout connection error.
When checking if the process is running, I found it running, but after killing the process and running it again the server return to serve requests.
Any idea what it could be?
I wrapped most of my functions with exception catching , but didn't helped me to understand the problem.
I wonder if anybody has used bottle and had encountered such problem

My guess is because bottle is single threaded, and it's hanging on a request. I would suggest trying a multi-threaded server, such as cherrypy, to see if that resolves the issue. Then go back and see where the hangup was at.
Install cherrypy
pip install cherrypy
Update your python file
bottle.run(myapp, server='cherrypy')
Would need to see more code to identify any specific issue.

Related

How to setup WSGI server to run similarly to Apache?

I'm coming from PHP/Apache world where running an application is super easy. Whenever PHP application crashes Apache process running that request will stop but server will be still ruining happily and respond to other clients. Is there a way to have Python application work in a smilar way. How would I setup wsgi server like Tornado or CherryPy so it will work similarly? also, how would I run several applications from one server with different domains?
What you are after would possibly happen anyway for WSGI severs. This is because any Python exception only affects the current request and the framework or WSGI server would catch the exception, log it and translate it to a HTTP 500 status page. The application would still be in memory and would continue to handle future requests.
What we get down to is what exactly you mean by 'crashes Apache process'.
It would be rare for your code to crash, as in cause the process to completely exit due to a core dump, the whole process. So are you being confused in your terminology in equating an application language level error to a full process crash.
Even if you did find a way to crash a process, Apache/mod_wsgi handles that okay and the process will be replaced. The Gunicorn WSGI server will also do that. CherryPy will not unless you have a process manager running which monitors it and the process monitor restarts it. Tornado in its single process mode will have the same problem. Using Tornado as the worker in Gunicorn is one way around that plus I believe Tornado itself may have some process manager in it now for running multiple process which allow it to restart processes if they die.
Do note that if your application bug which caused the Python exception is bad enough and it corrupts state within the process, subsequent requests may possibly have issues. This is the one difference with PHP. With PHP, after any request, whether successful or not, the application is effectively thrown away and doesn't persist. So buggy code cannot affect subsequent requests. In Python, because the process with loaded code and retained state is kept between requests, then technically you could get things in a state where you would have to restart the process to fix it. I don't know of any WSGI server though that has a mechanism to automatically restart a process if one request returned an error response.
If you're in an UNIX-like environment, you can run mod_wsgi under Apache in Daemon Mode. This means there will be a separate process for the Python code, and even if it crashes the server will continue running normally (and hopefully the WSGI process will restart itself). A WSGI application can run under multiple processes and multiple threads per process.
As for running multiple domains in the same server, check Name-Based Virtual Hosts.

Slow Requests on Local Flask Server

Just starting to play around with Flask on a local server and I'm noticing the request/response times are way slower than I feel they should be.
Just a simple server like the following takes close to 5 seconds to respond.
from flask import Flask
app = Flask(__name__)
#app.route("/")
def index():
return "index"
if __name__ == "__main__":
app.run()
Any ideas? Or is this just how the local server is?
Ok I figured it out. It appears to be an issue with Werkzeug and os's that support ipv6.
From the Werkzeug site http://werkzeug.pocoo.org/docs/serving/:
On operating systems that support ipv6 and have it configured such as modern Linux systems, OS X 10.4 or higher as well as Windows Vista some browsers can be painfully slow if accessing your local server. The reason for this is that sometimes “localhost” is configured to be available on both ipv4 and ipv6 socktes and some browsers will try to access ipv6 first and then ivp4.
So the fix is to disable ipv6 from the localhost by commenting out the following line from my hosts file:
::1 localhost
Once I do this the latency problems go away.
I'm really digging Flask and I'm glad that it's not a problem with the framework. I knew it couldn't be.
Add "threaded=True" as an argument to app.run(), as suggested here:
http://arusahni.net/blog/2013/10/flask-multithreading.html
For example: app.run(host="0.0.0.0", port=8080, threaded=True)
The ipv6-disabling solution did not work for me, but this did.
Instead of calling http://localhost:port/endpoint call http://127.0.0.1:port/endpoint.
This removed the initial 500ms delay for me.
The solution from #sajid-siddiqi is technically correct, but keep in mind that the built-in WSGI server in Werkzeug (which is packaged into Flask and what it uses for app.run()) is only single-threaded.
Install a WSGI server to be able to handle multi-threaded behavior. I did a bunch of research on various WSGI server performances. Your needs may vary, but if all you're using is Flask, then I would recommend one of the following webservers.
Update (2020-07-25): It looks like gevent started supporting python3 5 years ago, shortly after I commented that it didn't, so you can use gevent now.
gevent
You can install gevent through pip with the command pip install gevent or pip3 with the command pip3 install gevent. Instructions on how to modify your code accordingly are here: https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/#gevent
meinheld
gevent is better, but from all the benchmarks I've looked at that involve real-world testing, meinheld seems to be the most straightforward, simplistic WSGI server. (You could also take a look at uWSGI if you don't mind some more configuration.)
You can also install meinheld through pip3 with the command pip3 install meinheld. From there, look at the sample provided in the meinheld source to integrate Flask: https://github.com/mopemope/meinheld/blob/master/example/flask_sample.py
*NOTE: From my use of PyCharm, the line from meinheld import server highlights as an error, but the server will run, so you can ignore the error.
My problem was solved by "threaded=True", but I want to give some background to distinguish my problem from others for which this may not do it.
My issue only arose when running Flask with python3. Switching to python2, I no longer had this issue.
My problem manifested only when accessing the api with Chrome, at which point, Chrome displayed the expected screen, but everything else hung (curl, ffx, etc) until I either reloaded or closed the Chrome tab, at which point everything else that was waiting around returned a result.
My best guess is that Chrome was trying to keep the session open and Flask was blocking the subsequent requests. As soon as the connection from Chrome was stopped or reset, everything else was processed.
In my case, threading fixed it. Of course, I'm now going through some of the links others have provided to make sure that it's not going to cause any other issues.
threaded=True works for me, but finally I figured out that the issue is due to foxyproxy on firefox. Since when the flask app is running on localhost, slow response happens if
foxyproxy is enabled on firefox
slow response won't happen if
foxyproxy is disabled on firefox
access the website using other browsers
The only solution I found is to disable foxyproxy, tried to add localhost to proxy blacklist and tweak settings but none of them worked.
I used Miheko's response to solve my issue.
::1 localhost was already commented out on my hosts file, and setting Threaded=true didn't work for me. Every REST request was taking 1 second to process instead of being instant.
I'm using python 3.6, and I got flask to be fast and responsive to REST requests by making flask use gevent as its WSGI.
To use gevent, install it with pip install gevent
Afterwards, I used the https://gist.github.com/viksit/b6733fe1afdf5bb84a40#file-async_flask-py-L41 to set flask to use gevent.
Incase the link goes down, here's the important parts of the script:
from flask import Flask, Response
from gevent.pywsgi import WSGIServer
from gevent import monkey
# need to patch sockets to make requests async
# you may also need to call this before importing other packages that setup ssl
monkey.patch_all()
app = Flask(__name__)
# define some REST endpoints...
def main():
# use gevent WSGI server instead of the Flask
# instead of 5000, you can define whatever port you want.
http = WSGIServer(('', 5000), app.wsgi_app)
# Serve your application
http.serve_forever()
if __name__ == '__main__':
main()
I got this error when running on hosts other than localhost as well, so for some, different underlying problems may exhibit the same symptoms.
I switched most of the things I've been using to Tornado, and anecdotally it's helped an amount. I've had a few slow page loads, but things seem generally more responsive. Also, very anecdotal, but I seem to notice that Flask alone will slow down over time, but Flask + Tornado less so. I imagine using Apache and mod_wsgi would make things even better, but Tornado's really simple to set up (see http://flask.pocoo.org/docs/deploying/others/).
(Also, a related question: Flask app occasionally hanging)
I had a different solution here. I just deleted all .pyc from the server's directory and started it again.
By the way, localhost was already commented out in my hosts file (Windows 8).
The server was freezing the whole time and now it works fine again.
I run Python 3.8.10 which works fine, but as soon as I switch to Python 3.10.6 responses will be awful slow.
I could get around this problem with changing the precedence to IPv4 in /etc/gai.conf

NoMoreData exception when using couchdbkit with gunicorn and eventlet

Hope someone might be able to shed some light on this issue I'm having.
I am using couchdbkit in a pyramid webapp. My server is gunicorn with eventlet workers.
I am using the eventlet manager for couchdbkit.
When my app is running, I get quite frequently NoMoreData exceptions from couchdbkit (actually http parser inside restkit).
My hunch is that this has something to do with one connection waiting for eventlet is getting the data of a different waiting connection but I am not sure.
Did anyone encounter this problem? Do you have an idea?
Thanks,
Reshef

How do I keep a python HTTP Server up forever?

I wrote a simple HTTP server in python to manage a database hosted on a server via a web UI. It is perfectly functional and works as intended. However it has one huge problem, it won't stay put. It will work for an hour or so, but if left unused for long periods of time when returning to use it I have to re-initialize it every time. Right now the method I use to make it serve is:
def main():
global db
db = DB("localhost")
server = HTTPServer(('', 8080), MyHandler)
print 'started httpserver...'
server.serve_forever()
if __name__ == '__main__':
main()
I run this in the background on a linux server so I would run a command like sudo python webserver.py & to detach it, but as I mentioned previously after a while it quits. Any advice is appreciated cause as it stands I don't see why it shuts down.
You can write a UNIX daemon in Python using the python-daemon package, or a Windows service using the pywin32.
Unfortunately, I know of no "portable" solution to writing daemon / service processes (in Python, or otherwise).
Here's one piece of advice in a story about driving. You certainly want to drive safely (figure out why your program is failing and fix it). In the (rare?) case of a crash, some monitoring infrastructure, like monit, can be helpful to restart crashed processes. You probably wouldn't want to use it to paper over a crash just like you wouldn't want to deploy your air bag every time you stopped the car.
Well, first step is to figure out why it's crashing. There's two likely possibilities:
The serve_forever call is throwing an exception.
The python process is crashing/being terminated.
In the former case, you can make it live forever by wrapping it in a loop, with a try-except. Probably a good idea to log the error details.
The latter case is a bit trickier, because it could be caused by a variety of things. Does it happen if you run the script in the foreground? If not, maybe there's some kind of maintenance service running that is terminating your script?
Not really a complete answer, but perhaps enough to help you diagnose the problem.
Have you tried running it from inside a screen session?
$ screen -L sudo python webserver.py
As an alternative to screen there is NoHup which will ensure the process carries on running after your logged out.
Its worth checking the logs to see why its killed/quitting as well as it may not be related to the operating system but an internal fault.

How to get Intellij-idea close Flask dev server properly?

I use IDEA 10.5 for my Flask experimentation. Flask has en embedded test server (like Django does)
When I launch my test class, the dev server launches as well on port 5000. All good.
* Running on http://127.0.0.1:5000/
When I click on the "Stop process" button (red square), I get the message saying the process is finished :
Process finished with exit code 143
However the server is still alive (responds to requests) and I can see I still have a python process running.
Obviously this prevents me from relaunching the test straight away, I have to kill the server process first.
How do you manage to get both your program and the server ending at the same time ?
I guess what happens is that you start your flask app which then is forking the development server as a new process. If you stop the app the forked process is still running.
This looks like a problem, that cannot easily be solved within the means of your IDE. You could add something to your main to kill the already running server process, before starting the app again, but that seems ugly.
But why don't you just start your app with app.run(debug=True) as described in flask doc? The server will reload automatically everytime you changed your app so you don't have to stop and restart it manually.
EDIT:
Something a bit quirky just came to my mind: if you just need a comfortable way to kill the server from within the IDE all you have to do is to introduce a syntactical error in one of the places the reloader monitors, save the file and the server will choke on it and die :)
This doesn't happen anymore with newer versions (tested with PyCharm 2.0)

Categories

Resources