28

How do I use Django with the Tornado web server?

George Stocker
  • 57,289
  • 29
  • 176
  • 237
xRobot
  • 25,579
  • 69
  • 184
  • 304

4 Answers4

46

it's very simple ( especially with django 1.4) .

1 - just build your django project( and apps ) and make sure it works fine.

2- create a new python file at the root folder ( same dir where you used django-admin.py startproject)

3- then copy the code below , edit the os.environ['DJANGO_SETTINGS_MODULE'] line, and paste it in that new .py file.

import os
import tornado.httpserver
import tornado.ioloop
import tornado.wsgi
import sys
import django.core.handlers.wsgi
#sys.path.append('/home/lawgon/') # path to your project ( if you have it in another dir).


def main():
    os.environ['DJANGO_SETTINGS_MODULE'] = 'myProject.settings' # path to your settings module
    application = django.core.handlers.wsgi.WSGIHandler()
    container = tornado.wsgi.WSGIContainer(application)
    http_server = tornado.httpserver.HTTPServer(container)
    http_server.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()

Django 1.6+ it should be like this:

import os
import tornado.httpserver
import tornado.ioloop
import tornado.wsgi
from django.core.wsgi import get_wsgi_application

def main():
    os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings' # path to your settings module
    application = get_wsgi_application()
    container = tornado.wsgi.WSGIContainer(application)
    http_server = tornado.httpserver.HTTPServer(container)
    http_server.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()
Community
  • 1
  • 1
Moayyad Yaghi
  • 3,622
  • 13
  • 51
  • 67
  • 1
    Bravo! I am really looking forward to try that! – Jon Feb 11 '14 at 16:42
  • How to call the new.py file – Shiva May 01 '14 at 11:19
  • 1
    Doubt: this, of course, won't make Django magically asynchronous, and Python is not such a great multithreading language. So, this server won't support serving multiple concurrent requests, am I right? – Alan Franzoni Nov 17 '16 at 20:45
  • 1
    Note that this wont serve the static files. – Marco Lavagnino Mar 07 '17 at 18:51
  • @AlanFranzoni Tornado is more than just async. The point is it is a much faster & lighter weight thing to get up and running than Apache or Nginx and way way easier to manage. – uchuugaka Mar 16 '17 at 02:35
  • @uchuugaka of course it's lighter.. it's single threaded! Define 'faster', though... it may be faster at starting up and serving a SINGLE request, but will choke with more than one concurrent request! http://www.tornadoweb.org/en/stable/wsgi.html - by the way, my opinion was not on Tornado vs Django, it was on Django WITH Tornado. – Alan Franzoni Mar 17 '17 at 10:49
  • What does the tornado.ioloop.IOLoop.instance().start() mean? – user571102 Feb 01 '23 at 15:02
6

UPDATE:

I created a minimal working demo which shows how to use the Tornado web server to run nicely with django:

https://github.com/tamasgal/django-tornado

ORIGINAL POST:

Just a remark: The WSGI application workflow has been changed from 1.6 to 1.7. You have to replace the import

import django.core.handlers.wsgi

with

from django.core.wsgi import get_wsgi_application

and change the application initialisation from

application = django.core.handlers.wsgi.WSGIHandler()

to

application = get_wsgi_application()

This is the modified code from the Moayyad Yaghi's answer:

import os
import tornado.httpserver
import tornado.ioloop
import tornado.wsgi
import sys
import django.core.handlers.wsgi
from django.core.wsgi import get_wsgi_application
#sys.path.append('/home/lawgon/') # path to your project ( if you have it in another dir).


def main():
    os.environ['DJANGO_SETTINGS_MODULE'] = 'myProject.settings' # path to your settings module
    application = django.core.handlers.wsgi.WSGIHandler()
    application = get_wsgi_application()
    container = tornado.wsgi.WSGIContainer(application)
    http_server = tornado.httpserver.HTTPServer(container)
    http_server.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()
tamasgal
  • 24,826
  • 18
  • 96
  • 135
4

There's a project called tornado-proxy that would help you. But I would like to recommend that you use Nginx. In the Nginx config you could now use proxy_pass to direct your calls like this:

location /comet {
  proxy_pass http://localhost:8081;
}

location / {
  proxy_pass http://localhost:8080;
}
MyGGaN
  • 1,766
  • 3
  • 30
  • 41
  • 23
    Django is not a web server. It comes with a basic web server to aid in developing Django projects, but which is not suitable to be used in production environments. – Ignacio Vazquez-Abrams Mar 28 '10 at 22:30
  • 1
    Completely right, though I assumed that xRobot was using Django (with it's webserver) as a complete webserver/framework for building his web project. I spared him the details. – MyGGaN Mar 28 '10 at 22:38
  • I have played with chat and tornado on my computer and it works perfectly. On my server I am using nginx and django framework but I don't know where to put Tornado. P.s. Have you tried also the Push Module for Nginx ? Thanks ;) – xRobot Mar 28 '10 at 23:49
  • Sorry, I have not. But what do you mean with "put Tornado"? I have my Tornado source in a subfolder for my project and then I start it with: sudo nginx -c conf/nginx.conf – MyGGaN Mar 29 '10 at 01:59
  • ah ok... I will insert Tornado source in a subfolder. Thanks ^_^ – xRobot Mar 29 '10 at 08:49
2

In real world you would connect Django and some production-ready webserver with WSGI. This demo shows how you can run Tornado (and it's webserver) and Django side by side from one python module serving different URL prefixes: https://github.com/bdarnell/django-tornado-demo. Tornado would block on serving any request directed to Django, though.

mike_k
  • 1,831
  • 2
  • 14
  • 12