Tornado, long-polling and Django as backend

697 views
Skip to first unread message

Grigory Fateyev

unread,
Feb 5, 2010, 6:44:44 AM2/5/10
to Tornado server
Hello!

I use Tornado in few django projects as WSGI server + Nginx, its' like
traditional HTTP. Now I need to write liveblog service using django as
backand, signls will send response about updating the model.

Does it possible to use Tornado for that? If somebody use django and
tornado for comet, please share some code or give me any advise?

Thanks!
--
Всего наилучшего!

Andrew Gwozdziewycz

unread,
Feb 5, 2010, 9:47:54 AM2/5/10
to python-...@googlegroups.com
I don't think it's really possible with Django due to the way it
handles requests. There's not really a way to keep a connection open.
However, since you are using nginx, all hope is not lost. There's a
3rd party module http://pushmodule.slact.net/, which will keep the
connection open and give you a url to post messages back to.

So, what you could do is have your django app fill a job queue with a
url to return to, and have the results posted back to it, and
delivered through nginx. There may be other ways to do it as well, but
this seems like the easiest to integrate them all, though I have to
wonder why you're even using Tornado here to begin with. Nginx +
Django should be suitable enough.

Andrew

--
http://www.apgwoz.com

Grigory Fateyev

unread,
Feb 5, 2010, 11:17:50 AM2/5/10
to python-...@googlegroups.com
Hello Andrew Gwozdziewycz!
On Fri, 5 Feb 2010 09:47:54 -0500 you wrote:

[...]

> So, what you could do is have your django app fill a job queue with a
> url to return to, and have the results posted back to it, and
> delivered through nginx. There may be other ways to do it as well, but
> this seems like the easiest to integrate them all, though I have to
> wonder why you're even using Tornado here to begin with. Nginx +
> Django should be suitable enough.

Andrew, thank you very much, you are "opened" my eyes to nginx.

--
Всего наилучшего!

Ben Darnell

unread,
Feb 5, 2010, 1:59:52 PM2/5/10
to python-...@googlegroups.com
Brizzly is using a combination of tornado and django with long
polling. You can have a combination of tornado and django handlers in
the same app. Any long-polling handlers have to be tornado
asynchronous RequestHandlers, but they can still use the django ORM
stuff etc.

To mix tornado and django in one app, you'd do something like this:

wsgi_app = tornado.wsgi.WSGIContainer(
django.core.handlers.wsgi.WSGIHandler())
tornado_app = tornado.web.Application([
('/api/updates', UpdateHandler),
('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
])
server = tornado.HTTPServer(tornado_app)

This will call the tornado-style UpdateHandler for /api/updates, but
use django (configured through DJANGO_SETTINGS_MODULE as usual) for
everything else.

-Ben

Peter Portante

unread,
Feb 5, 2010, 2:30:05 PM2/5/10
to Ben Darnell, Tornado Mailing List
What is the advantage of doing that instead of having a reverse proxy like
nginx do that? -peter

Elias Torres

unread,
Feb 5, 2010, 2:31:02 PM2/5/10
to python-...@googlegroups.com
I'm losing my mind here. Are you saying that nginx + tornado + django
work together on the same process w/o a problem? A small but complete
sample would be very sweet if you could share with us.

-Elias

Ben Darnell

unread,
Feb 5, 2010, 3:05:25 PM2/5/10
to Peter Portante, Tornado Mailing List
2010/2/5 Peter Portante <peter.a....@gmail.com>:

> What is the advantage of doing that instead of having a reverse proxy like
> nginx do that? -peter

Ease of deployment, mainly. This way we only have to manage tornado
processes instead of tornado and apache. It also makes it easier to
convert urls one at a time from django to tornado, since it's a single
push instead of adding a handler to tornado, changing nginx, and then
removing from django.

-Ben

Ben Darnell

unread,
Feb 5, 2010, 3:45:44 PM2/5/10
to python-...@googlegroups.com
2010/2/5 Elias Torres <el...@torrez.us>:

> I'm losing my mind here. Are you saying that nginx + tornado + django
> work together on the same process w/o a problem? A small but complete
> sample would be very sweet if you could share with us.

http://github.com/bdarnell/django-tornado-demo/tree/master/testsite/

-Ben

Elias Torres

unread,
Feb 5, 2010, 5:19:01 PM2/5/10
to python-...@googlegroups.com
This is really good. I wish I had know this earlier, but it still is a
very good thing to know we have this option.

Thanks again.

Ben, do you guys use Django ORM for all DB work? In other words,
anything that's synchronous you leave to Django and only pass the
asynchronous calls to Tornado for Brizzly?

-Elias

2010/2/5 Ben Darnell <ben.d...@gmail.com>:

Andrew Gwozdziewycz

unread,
Feb 5, 2010, 5:33:15 PM2/5/10
to python-...@googlegroups.com
On Fri, Feb 5, 2010 at 1:59 PM, Ben Darnell <ben.d...@gmail.com> wrote:
> Brizzly is using a combination of tornado and django with long
> polling.  You can have a combination of tornado and django handlers in
> the same app.  Any long-polling handlers have to be tornado
> asynchronous RequestHandlers, but they can still use the django ORM
> stuff etc.
>
> To mix tornado and django in one app, you'd do something like this:
>
> wsgi_app = tornado.wsgi.WSGIContainer(
>  django.core.handlers.wsgi.WSGIHandler())
> tornado_app = tornado.web.Application([
>  ('/api/updates', UpdateHandler),
>  ('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
>  ])
> server = tornado.HTTPServer(tornado_app)
>
> This will call the tornado-style UpdateHandler for /api/updates, but
> use django (configured through DJANGO_SETTINGS_MODULE as usual) for
> everything else.

This is an interesting approach. So, you're using tornado standalone
with some other load balancer in front I'm guessing?

--
http://www.apgwoz.com

Ben Darnell

unread,
Feb 5, 2010, 6:16:07 PM2/5/10
to python-...@googlegroups.com
2010/2/5 Elias Torres <el...@torrez.us>:

> This is really good. I wish I had know this earlier, but it still is a
> very good thing to know we have this option.
>
> Thanks again.
>
> Ben, do you guys use Django ORM for all DB work? In other words,
> anything that's synchronous you leave to Django and only pass the
> asynchronous calls to Tornado for Brizzly?

We're currently using Django's ORM but considering switching to
SQLAlchemy (primarily because Django won't support multiple databases
until the upcoming 1.2 release). Note that we can and do access
Django's ORM objects from Tornado asynchronous handlers. We're using
tornado for all new development whether it's async or not, but in
general we're not going back and rewriting our old django handlers in
tornado unless they'd benefit from being asynchronous.

-Ben

Ben Darnell

unread,
Feb 5, 2010, 6:16:55 PM2/5/10
to python-...@googlegroups.com
Yes, multiple tornado instances behind nginx.

-Ben

Elias Torres

unread,
Feb 5, 2010, 6:34:03 PM2/5/10
to python-...@googlegroups.com
I have been using SQLAlchemy for a few months now with Tornado. I'd
love to exchange notes with you guys once you get into it. My biggest
lesson was learning that I cannot share state between asynchronous
requests because there's only thread running. At least for the setup
I'm using (single-threaded scoped session).

I'm also using sqlalchemy-migrate and elixir. It's tricky to say the
least. But I still think it's been better than me writing raw SQL all
of the time, 30 db migrations later as well.

dakila

unread,
Feb 7, 2010, 10:21:33 AM2/7/10
to Tornado Web Server
Im interested in using SQLAlchemy and Tornado, do you by any chance
have a small but complete sample you can share?

TIA,

Dakila

On Feb 6, 7:34 am, Elias Torres <el...@torrez.us> wrote:
> I have been using SQLAlchemy for a few months now with Tornado. I'd
> love to exchange notes with you guys once you get into it. My biggest
> lesson was learning that I cannot share state between asynchronous
> requests because there's only thread running. At least for the setup
> I'm using (single-threaded scoped session).
>
> I'm also using sqlalchemy-migrate and elixir. It's tricky to say the
> least. But I still think it's been better than me writing raw SQL all
> of the time, 30 db migrations later as well.
>
> -Elias
>

> 2010/2/5 Ben Darnell <ben.darn...@gmail.com>:


>
>
>
> > 2010/2/5 Elias Torres <el...@torrez.us>:
> >> This is really good. I wish I had know this earlier, but it still is a
> >> very good thing to know we have this option.
>
> >> Thanks again.
>
> >> Ben, do you guys use Django ORM for all DB work? In other words,
> >> anything that's synchronous you leave to Django and only pass the
> >> asynchronous calls to Tornado for Brizzly?
>
> > We're currently using Django's ORM but considering switching to
> > SQLAlchemy (primarily because Django won't support multiple databases

> > until the upcoming 1.2 release). šNote that we can and do access
> > Django's ORM objects from Tornado asynchronous handlers. šWe're using


> > tornado for all new development whether it's async or not, but in
> > general we're not going back and rewriting our old django handlers in
> > tornado unless they'd benefit from being asynchronous.
>
> > -Ben
>
> >> -Elias
>

> >> 2010/2/5 Ben Darnell <ben.darn...@gmail.com>:


> >>> 2010/2/5 Elias Torres <el...@torrez.us>:
> >>>> I'm losing my mind here. Are you saying that nginx + tornado + django
> >>>> work together on the same process w/o a problem? A small but complete
> >>>> sample would be very sweet if you could share with us.
>
> >>>http://github.com/bdarnell/django-tornado-demo/tree/master/testsite/
>
> >>> -Ben
>
> >>>> -Elias
>

> >>>> On Fri, Feb 5, 2010 at 1:59 PM, Ben Darnell <ben.darn...@gmail.com> wrote:
> >>>>> Brizzly is using a combination of tornado and django with long

> >>>>> polling. šYou can have a combination of tornado and django handlers in
> >>>>> the same app. šAny long-polling handlers have to be tornado


> >>>>> asynchronous RequestHandlers, but they can still use the django ORM
> >>>>> stuff etc.
>
> >>>>> To mix tornado and django in one app, you'd do something like this:
>
> >>>>> wsgi_app = tornado.wsgi.WSGIContainer(

> >>>>> šdjango.core.handlers.wsgi.WSGIHandler())
> >>>>> tornado_app = tornado.web.Application([
> >>>>> š('/api/updates', UpdateHandler),
> >>>>> š('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
> >>>>> š])


> >>>>> server = tornado.HTTPServer(tornado_app)
>
> >>>>> This will call the tornado-style UpdateHandler for /api/updates, but
> >>>>> use django (configured through DJANGO_SETTINGS_MODULE as usual) for
> >>>>> everything else.
>
> >>>>> -Ben
>
> >>>>> On Fri, Feb 5, 2010 at 3:44 AM, Grigory Fateyev <gfb...@gmail.com> wrote:
> >>>>>> Hello!
>
> >>>>>> I use Tornado in few django projects as WSGI server + Nginx, its' like
> >>>>>> traditional HTTP. Now I need to write liveblog service using django as
> >>>>>> backand, signls will send response about updating the model.
>
> >>>>>> Does it possible to use Tornado for that? If somebody use django and
> >>>>>> tornado for comet, please share some code or give me any advise?
>
> >>>>>> Thanks!
> >>>>>> --

> >>>>>> ÷ÓÅÇÏ ÎÁÉÌÕÞÛÅÇÏ!

huimies

unread,
Feb 8, 2010, 4:01:28 PM2/8/10
to Tornado Web Server
On Feb 5, 10:45 pm, Ben Darnell <ben.darn...@gmail.com> wrote:
> 2010/2/5 Elias Torres <el...@torrez.us>:
>
> > I'm losing my mind here. Are you saying that nginx + tornado + django
> > work together on the same process w/o a problem? A small but complete
> > sample would be very sweet if you could share with us.
>
> http://github.com/bdarnell/django-tornado-demo/tree/master/testsite/
>
> -Ben

This is good stuff, but how about authentication?

Lets say you use django's authentication. How do you check in tornado
handler if user is authenticated and passes some additional permission
checks?

Ben Darnell

unread,
Feb 8, 2010, 8:11:34 PM2/8/10
to python-...@googlegroups.com
If you put something like this in the base class of your
RequestHandlers, the tornado current_user property will be set to the
django user object.

def get_django_session(self):
engine = django.utils.importlib.import_module(
django.conf.settings.SESSION_ENGINE)
session_key = self.get_cookie(django.conf.settings.SESSION_COOKIE_NAME)
return engine.SessionStore(session_key)

def get_current_user(self):
# get_user needs a django request object, but only looks at the session
class Dummy(object): pass
django_request = Dummy()
django_request.session = self.get_django_session()
user = django.contrib.auth.get_user(django_request)
if user.is_authenticated():
return user
else:
return None

Elias Torres

unread,
Feb 8, 2010, 10:51:14 PM2/8/10
to python-...@googlegroups.com
I found this on github that uses Elixir (I do too). Let me know if
this is a good start for you.

http://github.com/anarcher/blizzard

-Elias

dakila

unread,
Feb 10, 2010, 8:57:44 AM2/10/10
to Tornado Web Server
Thanks a lot for the link!
I think its simple enough to understand how to get started with
tornado with SQLAlchemy!
Reply all
Reply to author
Forward
0 new messages