Code

Opened 9 years ago

Closed 9 years ago

Last modified 5 years ago

#172 closed enhancement (fixed)

Twisted (twisted.web2) support for Django

Reported by: jnoetzelman@… Owned by: adrian
Component: Tools Version: master
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: UI/UX:

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)

Attachments (0)

Change History (9)

comment:1 Changed 9 years ago by adrian

  • Resolution set to fixed
  • Status changed from new to closed

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 Changed 9 years ago by anonymous

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

comment:3 Changed 9 years ago by slamb@…

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

comment:4 Changed 9 years ago by Dagur

This is very outdated

comment:5 Changed 9 years ago by jacob

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 Changed 8 years ago by ToddB

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 Changed 8 years ago by middletex

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 Changed 8 years ago by bo@…

  • Keywords Twisted dynamic virtual host added
  • Type changed from defect to enhancement
  • Version set to 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 Changed 5 years ago by glyph

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.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.