57

I am a big fan of Flask - in part because it is simple and in part because has a lot of extensions. However, Flask is meant to be used in a WSGI environment, and WSGI is not a non-blocking, so (I believe) it doesn't scale as well as Tornado for certain kinds of applications.

Since each one has an URL dispatcher which will call a function, and both will use Python files (in Django you dont launch the python file but in flask or tornado you do) do does it make sense to have two seperate parts to your website - one part running the non-blocking jobs with Tornado, and the other part written with Flask?

If this is a good idea, how would you go about sharing cookies / sessions between Flask and Tornado? Will I run into issues, since Flask will use it own system and Tornado will use its own system?

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
Abdelouahab
  • 7,331
  • 11
  • 52
  • 82
  • 1
    @TimMcNamara i dont know why i fall in love with flask! it's the framework that when i begin to write my first tutorial, it WORKED! i got 2 months to understand the first step to django just because i thought django is python, and python is run a file and see....and it is not the case of how to launch django projects ;) – Abdelouahab Nov 15 '11 at 21:28
  • 2
    I updated your question a bit - let me know if I didn't get it quite right :-) – Sean Vieira Nov 15 '11 at 22:45
  • flawless, thank you :) now it's more professional :D – Abdelouahab Nov 16 '11 at 09:13

2 Answers2

91

i think i got 50% of the solution, the cookies are not tested yet, but now i can load Flask application using Tornado, and mixing Tornado + Flask together :)

first here is flasky.py the file where the flask application is:

from flask import Flask
app = Flask(__name__)

@app.route('/flask')
def hello_world():
  return 'This comes from Flask ^_^'

and then the cyclone.py the file which will load the flask application and the tornado server + a simple tornado application, hope there is no module called "cyclone" ^_^

from tornado.wsgi import WSGIContainer
from tornado.ioloop import IOLoop
from tornado.web import FallbackHandler, RequestHandler, Application
from flasky import app

class MainHandler(RequestHandler):
  def get(self):
    self.write("This message comes from Tornado ^_^")

tr = WSGIContainer(app)

application = Application([
(r"/tornado", MainHandler),
(r".*", FallbackHandler, dict(fallback=tr)),
])

if __name__ == "__main__":
  application.listen(8000)
  IOLoop.instance().start()

hope this will help someone that wants to mix them :)

Abdelouahab
  • 7,331
  • 11
  • 52
  • 82
  • 6
    How would you add the async methods within Tornado? Could you use the async on flask routes? – Merlin Sep 04 '12 at 19:01
  • 2
    I get that Flask is a microframework. But isn't Tornado a micro framework in much the same way - but has a robust http server within it. Say you didn't need to concern yourself with the potential swapping of the WSGI "container", why not just develop with what Tornado has to offer? – Jason Oct 27 '12 at 18:40
  • 1
    Flask is good due to its extensions, everything has an extension on Flask, so no need to reinvent the wheel. @Merlin i think it will not be an easy way, Flask uses WSGI and WSGI is not asynchronous. – Abdelouahab Pp Nov 04 '12 at 14:02
  • 4
    Is this actually viable? Did you end up using this, or just using Tornado? – Mittenchops Apr 07 '14 at 20:08
  • @AbdelouahabPp, although Flask uses WSGI and WSGI is not async, however, tornado can accept connections async and then we each request can run in a different thread(i am not sure), then we can have the async tornado instead use Gunicorn with sync worker class just like Apache pre-fork module. – andy Oct 15 '15 at 03:48
4

Based on 1 and 2, the combined and shorter answer is

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":

    from tornado.wsgi import WSGIContainer
    from tornado.httpserver import HTTPServer
    from tornado.ioloop import IOLoop

    http_server = HTTPServer(WSGIContainer(app))
    http_server.listen(8000)
    IOLoop.instance().start()

Please consider the warning about performance that has been mentioned on 2 , 3

Community
  • 1
  • 1
Ahmad Yoosofan
  • 961
  • 12
  • 21