#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 , 19 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:2 by , 19 years ago
Is it possible to check this into the codebase somewhere so that it stays current?
comment:3 by , 19 years ago
It looks like AdminMediaHandler has moved from django.core.handlers.wsgi to django.core.server.basehttp.
comment:5 by , 19 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 , 19 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 , 19 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 , 16 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.