Opened 19 years ago

Closed 19 years ago

Last modified 16 years ago

#172 closed enhancement (fixed)

Twisted (twisted.web2) support for Django

Reported by: jnoetzelman@… 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 Adrian Holovaty, 19 years ago

Resolution: fixed
Status: newclosed

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.

comment:2 by anonymous, 19 years ago

Is it possible to check this into the codebase somewhere so that it stays current?

comment:3 by slamb@…, 19 years ago

It looks like AdminMediaHandler has moved from django.core.handlers.wsgi to django.core.server.basehttp.

comment:4 by Dagur Páll Ammendrup, 19 years ago

This is very outdated

comment:5 by Jacob, 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 ToddB, 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 middletex, 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 bo@…, 19 years ago

Keywords: Twisted dynamic virtual host added
Type: defectenhancement
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 Glyph, 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.

Note: See TracTickets for help on using tickets.
Back to Top