I had implemented a multi-threaded web server using the Flask micro framework. Basically, my server has a task queue and a thread pool. Hence, it can handle multiple requests. Since Flask is implemented in Python and Python threads are not truly concurrent, my web app is a bit laggy.
Are there are any alternatives to Flask to overcome the issue of multi-threading?
I came across this question and I was a little disappointed nobody had pointed out how flask (and most python web apps are meant to be deployed). See: http://flask.pocoo.org/docs/deploying/#deployment
My preferred deployment option is the super-simple Tornado which works equally well on Linux and Windows (if I am deploying it alongside existing websites, or even a hybrid deployment as part of an existing site, I usually use IIS Application Request Routing [ARR] as a Reverse Proxy to Tornado). I've also used gevent on both with great success.
Tornado is an open source version of the scalable, non-blocking web server and tools that power FriendFeed. Because it is non-blocking and uses epoll, it can handle thousands of simultaneous standing connections, which means it is ideal for real-time web services. Integrating this service with Flask is straightforward:
So, if your flask application is in yourapplication.py, you might create another called tornado_web.py and use it to serve your application like so:
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from yourapplication import app
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5000)
IOLoop.instance().start()
via: http://flask.pocoo.org/docs/deploying/wsgi-standalone/#tornado
This isn't Flask's fault, it is a limitation in the Python interpreter, so any framework that you use will be subject to it.
But there is a great way to avoid this problem. To have true concurrence you can use a pool of processes instead of threads. The multiprocessing module provides an API that is compatible with that of the threading module, but it creates child processes for the workers. I have used this module to create background workers for Flask applications and found to work very well.
There is a new package in the trend now which is robust for production also, it is implemented in python and its easy to understand. Please do have a look at it.
FastAPI
Related
I am building a system that was some components that will be run in its own process or thread. They need to communicate with each other. One of those components is a Django application, the internal communication with the Django app will not be done through HTTP. Looking for networking libraries I found Twisted (awesome library!), reading its documentation I found that Twisted implements the WSGI specification too, so I thought its Web server could serve WSGI applications like Django. Following the docs I come with the following script to serve the Django app:
from twisted.web import server
from twisted.internet import reactor, endpoints
from twisted.web.wsgi import WSGIResource
from twisted.python.threadpool import ThreadPool
from mysite.wsgi import application as django_application
# Create and start a thread pool to handle incoming HTTP requests
djangoweb_threadpool = ThreadPool()
djangoweb_threadpool.start()
# Cleanup the threads when Twisted stops
reactor.addSystemEventTrigger('after', 'shutdown', djangoweb_threadpool.stop)
# Setup a twisted Service that will run the Django web app
djangoweb_request_handler = server.Site(WSGIResource(reactor, djangoweb_threadpool, django_application))
djangoweb_server = endpoints.TCP4ServerEndpoint(reactor, 8000)
djangoweb_server.listen(djangoweb_request_handler)
reactor.run()
Save it in a file like runserver.py in the same directory of manage.py, you can start the WSGI server by running python runserver.py.
I made a django view that does a blocking call to time.sleep() to test it, it worked fine. Since it's multithread, it did not block other requests. So I think it works well with the synchronous Django code. I could setup another service with a custom protocol as a gateway for internal communication.
1) Does that script properly loads the Django app? It will work the same way as other WSGI servers like gunicorn and uwsgi?
2) Will that threads be run in parallel?
hendrix is a project that lets you run django via twisted. It looks like it can run other twisted services if desired (https://hendrix.readthedocs.io/en/latest/deploying-other-services/).
If you're in the early stages of developement, consider klein. It's more akin to flask than django though.
I am writing a Gevent/Flask server in Python. Some of the requests my Flask app takes need to run in the background; there is an endpoint for the client to poll the server for the task's result.
If you search the wisdom of the Internet for the best way to do this, everybody seems to be in favor of setting up one or several worker processes such as Celery or RQ, with a message queue or store such as RabbitMQ or Redis.
My app is small and my deployment is modest. This seems like too much of a hassle for me. I already have cooperative multitasking with Gevent, so I thought I'd just create a greenlet to do the background work in-process, that is, within the Flask app process itself.
This is not the mainstream solution, so my question is: Am I missing something? What am I missing? Is there something in this solution that makes it particularly bad?
I have a Flask app on one machine, and a second machine where some queries are required to be run from. The second machine doesn't render any pages, it will just be doing things behind the scenes for the first app. If I create a Flask app on the second machine to control those queries, how do I communicate with it from the first app? Is making a second Flask app with an API correct, or is there a simpler way to do this?
You communicate with it like you would any other HTTP server: by making HTTP requests. Python has the built-in urllib, or you could consider the easy to use requests library.
If all the second machine is doing is running background tasks, there's no reason to set up another Flask app. You can use a task queue such as Celery instead, or an RPC library such as Pyro.
To give a little background, I'm writing (or am going to write) a daemon in Python for scheduling tasks to run at user-specified dates. The scheduler daemon also needs to have a JSON-based HTTP web service interface (buzzword mania, I know) for adding tasks to the queue and monitoring the scheduler's status. The interface needs to receive requests while the daemon is running, so they either need to run in a separate thread or cooperatively multitask somehow. Ideally the web service interface should run in the same process as the daemon, too.
I could think of a few ways to do it, but I'm wondering if there's some obvious module out there that's specifically tailored for this kind of thing. Any suggestions about what to use, or about the project in general are quite welcome. Thanks! :)
Check out the class BaseHTTPServer -- a "Basic HTTP server" bundled with Python.
http://docs.python.org/library/basehttpserver.html
You can spin up a second thread and have it serve your requests for you very easily (probably < 30 lines of code). And it all runs in the same process and Python interpreter space, so it can access all your objects, etc.
I'm not sure I understand your question properly, but take a look at Twisted
I believed all kinds of python web framework is useful.
You can pick up one like CherryPy, which is small enough to integrate into your system. Also CherryPy includes a pure python WSGI server for production.
Also the performance may not be as good as apache, but it's already very stable.
Don't re-invent the bicycle!
Run jobs via cron script, and create a separate web interface using, for example, Django or Tornado.
Connect them via a database. Even sqlite will do the job if you don't want to scale on more machines.
I'm trying to make a cherrypy application with a wxpython ui. The problem is both libraries use closed loop event handlers. Is there a way for this to work? If I have the wx ui start cherrypy is that going to lock up the ui?
See my answer at CherryPy interferes with Twisted shutting down on Windows
In short, CherryPy handles the main loop by default, but it definitely doesn't need to. Stop using quickstart and call engine.start without engine.block, and CP will run in its own threads and leave the main thread for your other framework to control.
If you use threading, you should be able to start up the CherryPy server in one thread and run wxPython in the other. This article (http://wiki.wxpython.org/LongRunningTasks) on the wxPython wiki has some info on threading, and the CherryPy server source code (http://www.cherrypy.org/browser/trunk/cherrypy/wsgiserver/__init__.py) has some documentation on how the server works, and possibly how you could get it to interact with threads.
One way to decouple them would be to start them up as two separate processes and have them communicate via some kind of IPC mechanism. You might have to write a small adaptor to have them speak a common protocol.
Since you're doing CherryPy, you might also be able to expose a control interface via HTTP which the wx GUI can use to drive your server.
I would encourage you to take a look at the Calibre (e-book manager) source. It is written in PyQT, but uses CherryPy to allow people to view their library from outside their LAN.