HttpServer as a Windows Service

98 views
Skip to first unread message

David Pratt

unread,
Dec 19, 2005, 12:03:43 AM12/19/05
to django-d...@googlegroups.com
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)

Ian Holsman

unread,
Dec 19, 2005, 2:46:18 AM12/19/05
to django-d...@googlegroups.com
doesn't Apache HTTP 2.0 run as a service on windows?


--
I...@Holsman.net -- blog: http://feh.holsman.net/ -- PH: ++61-3-9877-0909

If everything seems under control, you're not going fast enough. -
Mario Andretti

David Pratt

unread,
Dec 19, 2005, 9:00:03 AM12/19/05
to django-d...@googlegroups.com
Hi Ian. Thanks for your reply. It does, however I was looking at this
from the perspective of running the small httpserver as its own service
when Django is installed on a Windows machine for development. Is there
any interest in this?

Regards,
David

PythonistL

unread,
Dec 19, 2005, 11:04:35 AM12/19/05
to Django developers

Adrian Holovaty

unread,
Dec 19, 2005, 11:18:55 AM12/19/05
to django-d...@googlegroups.com
On 12/19/05, David Pratt <fair...@eastlink.ca> wrote:
> Hi Ian. Thanks for your reply. It does, however I was looking at this
> from the perspective of running the small httpserver as its own service
> when Django is installed on a Windows machine for development. Is there
> any interest in this?

Hi David,

I don't use Windows myself, but I could definitely see some use in
this for our friends in the Windows world.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com | chicagocrime.org

David Pratt

unread,
Dec 19, 2005, 1:45:15 PM12/19/05
to django-d...@googlegroups.com
Thanks for this. I have been reading up quite a bit on threading and
also windows services. I am not much of a windows user but sometimes
you find yourself needing to do things with it. For me Mac is great and
Unix of course.

Regards,
David

Dody Suria Wijaya

unread,
Dec 19, 2005, 1:52:06 PM12/19/05
to django-d...@googlegroups.com
I agree. Part of the reason Plone was really popular because it's so
easy to install, and behave like normal Windows software. This means
daemon-like software always present as Windows Service, and get
started/stopped via familiar interface. Django so far has not as easy as
it could be. Packaging all-in-one (Python + eveything needed) with
installation script + shortcuts on Start-Program with nice icons,
traybar monitor utility ala Apache, and .CHM document would be awesome.

David Pratt

unread,
Dec 19, 2005, 1:53:23 PM12/19/05
to django-d...@googlegroups.com
Hi Adrian. I have been doing a bit more investigating today and some
threading experiments first. Maybe something will come from it. Like I
say, I am not a Windows person myself ;-). I will also likely try a
couple other servers to see where this goes. It may just be
experimentation for now until I understand everything a bit more clearly.

Regards,
David

Adrian Holovaty

unread,
Dec 19, 2005, 4:29:44 PM12/19/05
to django-d...@googlegroups.com
On 12/19/05, Dody Suria Wijaya <dod...@gmail.com> wrote:
> I agree. Part of the reason Plone was really popular because it's so
> easy to install, and behave like normal Windows software. This means
> daemon-like software always present as Windows Service, and get
> started/stopped via familiar interface. Django so far has not as easy as
> it could be. Packaging all-in-one (Python + eveything needed) with
> installation script + shortcuts on Start-Program with nice icons,
> traybar monitor utility ala Apache, and .CHM document would be awesome.

Would any Windows experts like to take on this project?

David Pratt

unread,
Dec 20, 2005, 9:17:39 AM12/20/05
to django-d...@googlegroups.com
Hi Adrian. I think the first part of this is to get the server to spin
off its thread with a cgi to start and stop. This can then be wrapped
with win32service to make this a windows service as with similar code I
put up the other day. I noticed that Django is already using the
cherrypy autoreloader. Modifying _cpserver from cherrypy for Django can
provide the initial thread.

Another thought is to not duplicate efforts and but use the cherrypy
wsgi server as the development webserver. This has all the functionality
for django as is and is being actively maintained and developed where
the wsgiref server that is being used now is not. Further it can it
would provide a reliable service for development since it is in fact a
deployable server as it stands.

I have experimented with this in a basic way yesterday since
_cpwsgiserver was specifically written to be adaptable for other
projects. In fact, cherrypy developed their own wrapper for it to
ensure that the core wsgiserver could be used in other projects.

I think this solution is the best. I did not have a problem starting the
service with the wsgiserver but was getting a traceback on urls. Is
there someone that could help me sort this since the issue is with the
app being passed to the wsgiserver since it generates a traceback in the
common middleware as a result. In any case I think this is viable. I
would appreciate some feedback on this or who might be best to perhaps
help me get the request from the middleware all the way through to the
server without trouble.

Further, if cherrypy wsgiserver is used, the cgi for windows service has
already been written and get Django a bit futher along for some sort of
packaging as been suggested for Windows.

Regards,
David

Adrian Holovaty

unread,
Dec 20, 2005, 9:39:09 AM12/20/05
to django-d...@googlegroups.com
On 12/20/05, David Pratt <fair...@eastlink.ca> wrote:
> Further, if cherrypy wsgiserver is used, the cgi for windows service has
> already been written and get Django a bit futher along for some sort of
> packaging as been suggested for Windows.

Hi David,

This sounds fine to me. If the license is OK and you put together a
patch, we can take a look and integrate it.

David Pratt

unread,
Dec 20, 2005, 10:16:56 AM12/20/05
to django-d...@googlegroups.com
License is BSD so all is well in that regard. There is still an issue
with the app that gets passed to the server to deliver the request
properly. It would be great is there is someone interested in helping
that understands this aspect of Django well that could lend a hand.

Regards,
David

David Pratt

unread,
Dec 23, 2005, 10:03:40 AM12/23/05
to django-d...@googlegroups.com
Hi Adrian. I have got the CherryPy server working as a
development/deployment server for Django for my own needs. It consists
of class that wraps the wsgi server and a modification to the cherrypy's
core wsgi server. This was the issue I spoke of in my last mail. I
figured out the problem that was causing the request to die in the
middleware. Basically I have got this down to two files.

1. httpserver: Contains app, server, and server wrapper
2. httpctl: Contains controls for start, stop, gracefully restart etc.

Let me know how you feel about possible integration with Django since
the use of the server creates a dependency upon CherryPy. There would be
a need to integrate a development/production server configuration and
modify management for the command line tool.

Regards,
David

Reply all
Reply to author
Forward
0 new messages