I was doing a bit of searching today to see what I could dig up to improve how the development server operates on Windows. I found this which is pretty close to what I want to do. It comes from Turbo Gears. Is there any interest from anyone else to help me implement the light development server as a Window Service?

I plan to rewrite this a bit for Django. I just think it would be cleaner and logs could be written to file as opposed to stdout. I am not so familiar with Windows but more Mac and Unix which is reason it would be nice for someone with Windows to help me out on this. I don't think it would require too much to provide this functionality. I think in light of the fact that most people are likely developing on windows boxes, it would be a plus. I looked at the httpserver code and I don't think it would much to fit this in.

Regards,
David

From Turbo Gears ...

import cherrypy
import pkg_resources
pkg_resources.require("TurboGears")

import sys
import os
from os.path import *

import win32serviceutil
import win32service
from win32com.client import constants

class TGWindowsService(win32serviceutil.ServiceFramework):
    """TurboGears Windows Service helper class.

    The TGWindowsService class contains all the functionality required
    for running a TurboGears application as a Windows Service.  The only
    user edits required for this class are located in the following class
    variables:

_svc_name_: The name of the service (used in the Windows registry). _svc_display_name_: The name that will appear in the Windows Service Manager.
    code_dir:           The full path to the base directory of the user's
                        TG app code (usually where <project_name>-start.py
                        and the *.cfg files are located).
    root_class:         The fully qualified Root class name
                        (e.g. wiki20.controllers.Root)
    log_dir:            The desired location of the stdout and stderr
                        log files.

    For information on installing the application, please refer to the
    documentation at the end of this module or navigate to the directory
    where this module is located and type "service.py" from the command
    prompt.
    """

    # -- START USER EDIT SECTION
    # -- Users must edit this section before installing the service.
    _svc_name_ = ''          # (Required) The name of the service.
    _svc_display_name_ = ''  # (Required) The Service Manager display name.
code_dir = r'' # (Required) The base directory of the TG app code. root_class = '' # (Required) The fully qualified Root class name. log_dir = r'' # (Optional) The log directory. Default = code_dir.
    # -- END USER EDIT SECTION

    def SvcDoRun(self):
        """ Called when the Windows Service runs. """

        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        self.tg_init()
        cherrypy.root = self.root()
        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
        cherrypy.server.start()

    def SvcStop(self):
        """Called when Windows receives a service stop request."""

        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        cherrypy.server.stop()
        self.ReportServiceStatus(win32service.SERVICE_STOPPED)

    def tg_init(self):
""" Checks for the required data and initializes the application. """

        if TGWindowsService.code_dir:
            os.chdir(TGWindowsService.code_dir)
            sys.path.append(TGWindowsService.code_dir)
# Redirect stdout and stderr to avoid buffer crashes. sys.stdout = open(join(TGWindowsService.log_dir, 'stdout.log'),'a') sys.stderr = open(join(TGWindowsService.log_dir, 'stderr.log'),'a')
        else:
            raise ValueError("""The code directory setting is missing.
                                The Windows Service will not run
                                without this setting.""")

        if not TGWindowsService.root_class:
            raise ValueError("""The fully qualified root class name must
                                be provided.""")

        if not TGWindowsService.log_dir:
            TGWindowsService.log_dir = '.'

        if exists(join(TGWindowsService.code_dir, "setup.py")):
            cherrypy.config.update(file="dev.cfg")
        else:
            cherrypy.config.update(file="prod.cfg")

        # Set environment to production to disable auto-reload.
cherrypy.config.update({'global': {'server.environment': 'production'},})

        # Parse out the root class information and set it to self.root
        full_class_name = TGWindowsService.root_class
        last_mark = full_class_name.rfind('.')

        if (last_mark < 1) or (last_mark + 1) == len(full_class_name):
            raise ValueError("""The user-defined class name is invalid.
                                Please make sure to include a fully
                                qualified class name for the root_class
                                value (e.g. wiki20.controllers.Root).""")

        package_name = full_class_name[:last_mark]
        class_name = full_class_name[last_mark+1:]
        exec('from %s import %s as Root' % (package_name, class_name))
        self.root = Root

if __name__ == '__main__':
# The following are the most common command-line arguments that are used
    # with this module:
    #  service.py install (Installs the service with manual startup)
# service.py --startup auto install (Installs the service with auto startup)
    #  service.py start (Starts the service)
    #  service.py stop (Stops the service)
    #  service.py remove (Removes the service)
    #
    # For a full list of arguments, simply type "service.py".
    win32serviceutil.HandleCommandLine(TGWindowsService)

Reply via email to