#172 closed enhancement (fixed)
Twisted (twisted.web2) support for Django
| Reported by: | Owned by: | Adrian Holovaty | |
|---|---|---|---|
| Component: | Tools | Version: | dev |
| Severity: | normal | Keywords: | Twisted dynamic virtual host |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
I've implemented a basic module to use Twisted Web2 to drive Django. It's based on the demo.py provided with Twisted.Web2. It retains an MIT license as it's derived from Twisted.
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
# See LICENSE for details.
"""I am a simple test resource.
"""
import os.path, os
from twisted.web2 import log, wsgi
from twisted.internet import reactor
# This part gets run when you run this file via: "twistd -noy demo.py"
if __name__ == '__builtin__':
from twisted.application import service, strports
from twisted.web2 import server, vhost, channel
#from twisted.internet.ssl import DefaultOpenSSLContextFactory
from twisted.python import util
# Create the resource we will be serving
from django.core.handlers.wsgi import AdminMediaHandler, WSGIHandler
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings.admin'
test = wsgi.WSGIResource(AdminMediaHandler(WSGIHandler()))
# Setup default common access logging
res = log.LogWrapperResource(test)
log.DefaultCommonAccessLoggingObserver().start()
# Create the site and application objects
site = server.Site(res)
application = service.Application("demo")
# Serve it via standard HTTP on port 8080
s = strports.service('tcp:8080', channel.HTTPFactory(site))
s.setServiceParent(application)
# Serve it via HTTPs on port 8081
#s = strports.service('ssl:8081:privateKey=doc/core/examples/server.pem', channel.HTTPFactory(site))
#s.setServiceParent(application)
Change History (9)
comment:1 by , 20 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
comment:2 by , 20 years ago
Is it possible to check this into the codebase somewhere so that it stays current?
comment:3 by , 20 years ago
It looks like AdminMediaHandler has moved from django.core.handlers.wsgi to django.core.server.basehttp.
comment:5 by , 20 years ago
Yeah, this is out of date. If anyone has an updated patch against trunk and is willing to commit to maintaining it, please reopen this ticket.
comment:6 by , 20 years ago
I have been playing with this, and did get it to work with current twisted-web2, however, twisted-web2 is under heavy development currently. Now I am looking to get this working with twisted-web, haven't decided if going to build minimal wsgi interface, or try to figure out how modpython interfaces. Unsure what the best way to do this is as of yet, if I ever do get it working decently will let you guys know.
comment:7 by , 20 years ago
I made a few changes to denote the new location of channel/HTTPFactory and the settings module string and was able to get this up and running for twisted-2.1.0, twisted.web2-0.1, and django-0.91. web2 is still under heavy development, but maybe it'll start to solidify soon. For now you can use the code below to bring up django under twisted.
# Copyright (c) 2001-2004 Twisted Matrix Laboratories. # See LICENSE for details. """I am a simple test resource. """ import os.path, os from twisted.web2 import log, wsgi from twisted.internet import reactor # This part gets run when you run this file via: "twistd -noy demo.py" if __name__ == '__builtin__': from twisted.application import service, strports from twisted.web2 import server, vhost from twisted.web2 import http as channel from twisted.web import http #from twisted.internet.ssl import DefaultOpenSSLContextFactory from twisted.python import util # Create the resource we will be serving from django.core.handlers.wsgi import WSGIHandler from django.core.servers.basehttp import AdminMediaHandler os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings' test = wsgi.WSGIResource(AdminMediaHandler(WSGIHandler())) # Setup default common access logging res = log.LogWrapperResource(test) log.DefaultCommonAccessLoggingObserver().start() # Create the site and application objects site = server.Site(res) application = service.Application("demo") # Serve it via standard HTTP on port 8080 s = strports.service('tcp:8080', channel.HTTPFactory(site)) s.setServiceParent(application) # Serve it via HTTPs on port 8081 #s = strports.service('ssl:8081:privateKey=doc/core/examples/server.pem', channel.HTTPFactory(site)) #s.setServiceParent(application)
comment:8 by , 19 years ago
| Keywords: | Twisted dynamic virtual host added |
|---|---|
| Type: | defect → enhancement |
| Version: | → SVN |
Here we have a little technique, only Twisted can do.
the problem:
You have many virtual hosts all used the same code base on your system, but you really do not want to
have zillions of different FCGI processes, as the only thing different about them is the Db (and maybe
paths to static dirs.
the solution:
need a way to dynamically set the settings modules when the REQUEST is made (not before as in the standard FLUP fcgi startup)
import os.path, os, sys
#set your paths to the settings file locations
from twisted.web2 import log, wsgi, resource
from twisted.internet import reactor
import re
# Create the resource we will be serving
def make_wsgi(req):
#needed for basehttp to determin the proper path of things
os.environ['PATH_INFO'] = req.path
MAIN_MOD = 'mysite.settings'
#CHANGE THE SETTINGS BASED ON SOMETHING ABOUT THE REQUEST
# req.host or req.path, etc
#if re.search('anothersite.moo.org', req.host):
# MAIN_MOD = "anothersite.settings"
from django.core.handlers.wsgi import WSGIHandler
from django.core.servers.basehttp import AdminMediaHandler
os.environ['DJANGO_SETTINGS_MODULE'] = MAIN_MOD
return wsgi.WSGIResource(AdminMediaHandler(WSGIHandler()))
### ArbitrarySettingsDecide.
## you can even set up static file URL here to save things going all the
## way back to django
class ArbitrarySettingsDecide(resource.Resource):
# addSlash=True to make sure it's treated as a directory-like resource
addSlash = True
#all paths go to the make_wsgi request
def locateChild(self, request, segments):
return self, ()
def renderHTTP(self, request):
return make_wsgi(request)
# This part gets run when you run this file via: "twistd -noy demo.py"
if __name__ == '__builtin__':
from twisted.application import service, strports
from twisted.web2 import server, vhost
from twisted.web2 import channel
#from twisted.internet.ssl import DefaultOpenSSLContextFactory
from twisted.python import util
choose_site = ArbitrarySettingsDecide()
# Setup default common access logging
res = log.LogWrapperResource(choose_site)
log.DefaultCommonAccessLoggingObserver().start()
# Create the site and application objects
site = server.Site(res)
application = service.Application("photopost")
# Serve it via standard HTTP on port 8080
s = strports.service('tcp:8080', channel.HTTPFactory(site))
s.setServiceParent(application)
# Serve it via FastCGI on port 1026
s = strports.service('tcp:1026', channel.FastCGIFactory(site))
s.setServiceParent(application)
# Serve it via HTTPs on port 8081
#s = strports.service('ssl:8081:privateKey=doc/core/examples/server.pem', channel.HTTPFactory(site))
#s.setServiceParent(application)
comment:9 by , 17 years ago
Twisted (like, the actual supported version of Twisted, not twisted.web2) now supports Django via WSGI. David Reid wrote about it here:
http://lackingcredibility.blogspot.com/2009/03/twisted-django-it-wont-burn-down-your.html
In general people should be doing Twisted integration that way, now.
Thanks for this example! I'm closing the ticket, because it's not really a bug, but this page is linked-to from the ServerArrangements page.