EliAndrewC / sideboard

BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Add utility classes/methods for running Django apps in a Sideboard plugin #43

Closed EliAndrewC closed 8 years ago

EliAndrewC commented 10 years ago

We've done the proof of concept on this, and when we have the spare cycles it would be cool to add the necessary utilities to sideboard.lib and write a tutorial on running Django in a Sideboard plugin. Although it's theoretically as simple as just running Django inside CherryPy, it'd be nice to make it super-easy and add a tutorial section.

One of the main benefits would be to emphasize that Sideboard isn't trying to be another Python web framework like Django, and instead is just a container for WSGI apps, with a set of helpful libraries that you can take or leave.

Here's the proof of concept code I originally used to get my test app running in Sideboard like 6 months ago:

from __future__ import unicode_literals
import os
import sys

import cherrypy

import django
from django.conf import settings
from django.core.handlers.wsgi import WSGIHandler

from sideboard import parse_config
config = parse_config(__file__)

class Handler(WSGIHandler):
    def __init__(self, settings_module):
        self.settings_module = settings_module
        WSGIHandler.__init__(self)

    def __call__(self, environ, start_response):
        prev_settings = os.environ.get('DJANGO_SETTINGS_MODULE')
        os.environ['DJANGO_SETTINGS_MODULE'] = self.settings_module
        sys.path.extend([
            config['root'],
            '/'.join(django.__file__.split('/')[:-2])
        ])
        environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO']
        environ['SCRIPT_NAME'] = ''
        try:
            return WSGIHandler.__call__(self, environ, start_response)
        finally:
            del sys.path[-2:]
            if prev_settings:
                os.environ['DJANGO_SETTINGS_MODULE'] = prev_settings

# I'm not sure how people configure the Admin's static stuff with Apache in production with Django, so we should probably do whatever that is instead of this
class Static(object):
    admin = cherrypy.tools.staticdir.handler(
        section="/admin",
        dir=config['root'] + '/env/lib/python2.7/site-packages/django/contrib/admin/static/admin'
    )

cherrypy.tree.graft(Handler('unchained.settings'), '/unchained')
cherrypy.tree.mount(Static(), '/unchained/static')

That might need to be updated, but it looks good overall and I don't see anything that I wouldn't expect to work with Sideboard. The main thing we need is the tutorial walking you through it, and to put the Handler class in sideboard.lib under some sensible name like DjangoWSGIHandler.

EliAndrewC commented 8 years ago

Fixed in current version.