Windows¶
There are four possible deployment options for Windows:
Run as a Windows service with a Python based web server like CherryPy or Twisted
Run as a Windows service behind another web server (either IIS or Apache) using a reverse proxy
Inside IIS using the WSGI bridge with ISAPI-WSGI
Inside IIS using the WSGI bridge with PyISAPIe
Options 1 and 2: run as a Windows service¶
Both Options 1 and 2 are quite similar to running the development server, except that debugging info is turned off and you want to run the process as a Windows service.
Install dependencies¶
Running as a Windows service depends on the PyWin32 project. You will need to download the pre-built binary that matches your version of Python.
You can install directly into the virtualenv if you run easy_install
on
the downloaded installer. For example:
easy_install pywin32-217.win32-py2.7.exe
Since the web server for CherryPy has good Windows support, is available for Python 2 and 3, and can be gracefully started and stopped on demand from the service, we'll use that as the web server. You could also substitute another web server, like the one from Twisted.
To install CherryPy run:
pip install cherrypy
Create a Windows service¶
Create a new file called pyramidsvc.py
with the following code to define
your service:
1# uncomment the next import line to get print to show up or see early
2# exceptions if there are errors then run
3# python -m win32traceutil
4# to see the output
5#import win32traceutil
6import win32serviceutil
7
8PORT_TO_BIND = 80
9CONFIG_FILE = 'production.ini'
10SERVER_NAME = 'www.pyramid.example'
11
12SERVICE_NAME = "PyramidWebService"
13SERVICE_DISPLAY_NAME = "Pyramid Web Service"
14SERVICE_DESCRIPTION = """This will be displayed as a description \
15of the serivice in the Services snap-in for the Microsoft \
16Management Console."""
17
18class PyWebService(win32serviceutil.ServiceFramework):
19 """Python Web Service."""
20
21 _svc_name_ = SERVICE_NAME
22 _svc_display_name_ = SERVICE_DISPLAY_NAME
23 _svc_deps_ = None # sequence of service names on which this depends
24 # Only exists on Windows 2000 or later, ignored on Windows NT
25 _svc_description_ = SERVICE_DESCRIPTION
26
27 def SvcDoRun(self):
28 from cheroot import wsgi
29 from pyramid.paster import get_app
30 import os, sys
31
32 path = os.path.dirname(os.path.abspath(__file__))
33
34 os.chdir(path)
35
36 app = get_app(CONFIG_FILE)
37
38 self.server = wsgi.Server(
39 ('0.0.0.0', PORT_TO_BIND), app,
40 server_name=SERVER_NAME)
41
42 self.server.start()
43
44
45 def SvcStop(self):
46 self.server.stop()
47
48
49if __name__ == '__main__':
50 win32serviceutil.HandleCommandLine(PyWebService)
The if __name__ == '__main__'
block provides an interface to register the
service. You can register the service with the system by running:
python pyramidsvc.py install
Your service is now ready to start, you can do this through the normal service snap-in for the Microsoft Management Console or by running:
python pyramidsvc.py start
If you want your service to start automatically you can run:
python pyramidsvc.py update --start=auto
Reverse proxy (optional)¶
If you want to run many Pyramid applications on the same machine you will need to run each of them on a different port and in a separate Service. If you want to be able to access each one through a different host name on port 80, then you will need to run another web server (IIS or Apache) up front and proxy back to the appropriate service.
There are several options available for reverse proxy with IIS. In versions starting with IIS 7, you can install and use the Application Request Routing if you want to use a Microsoft-provided solution. Another option is one of the several solutions from Helicon Tech. Helicon Ape is available without cost for up to 3 sites.
If you aren't already using IIS, Apache is available for Windows and works well. There are many reverse proxy tutorials available for Apache, and they are all applicable to Windows.
Options 3 and 4: Inside IIS using the WSGI bridge with ISAPI-WSGI¶
IIS configuration¶
Turn on Windows feature for IIS.
Control panel -> "Turn Windows features on off" and select:
Internet Information service (all)
World Wide Web Services (all)
Create website¶
Go to Internet Information Services Manager and add website.
Site name (your choice)
Physical path (point to the directory of your Pyramid porject)
select port
select the name of your website
Python¶
Install PyWin32, according to your 32- or 64-bit installation
Install isapi-wsgi
Create bridging script¶
Create a file install_website.py
, and place it in your pyramid project:
1# path to your site packages in your environment
2# needs to be put in here
3import site
4site.addsitedir('/path/to/your/site-packages')
5
6# this is used for debugging
7# after everything was installed and is ready to meka a http request
8# run this from the command line:
9# python -m python -m win32traceutil
10# It will give you debug output from this script
11# (remove the 3 lines for production use)
12import sys
13if hasattr(sys, "isapidllhandle"):
14 import win32traceutil
15
16
17# this is for setting up a path to a temporary
18# directory for egg cache.
19import os
20os.environ['PYTHON_EGG_CACHE'] = '/path/to/writable/dir'
21
22# The entry point for the ISAPI extension.
23def __ExtensionFactory__():
24 from paste.deploy import loadapp
25 import isapi_wsgi
26 from logging.config import fileConfig
27
28 appdir = '/path/to/your/pyramid/project'
29 configfile = 'production.ini'
30 con = appdir + configfile
31
32 fileConfig(con)
33 application = loadapp('config:' + configfile, relative_to=appdir)
34 return isapi_wsgi.ISAPIThreadPoolHandler(application)
35
36# ISAPI installation
37if __name__ == '__main__':
38 from isapi.install import ISAPIParameters, ScriptMapParams, VirtualDirParameters, HandleCommandLine
39
40 params = ISAPIParameters()
41 sm = [
42 ScriptMapParams(Extension="*", Flags=0)
43 ]
44
45 # if name = "/" then it will install on root
46 # if any other name then it will install on virtual host for that name
47 vd = VirtualDirParameters(Name="/",
48 Description="Description of your proj",
49 ScriptMaps=sm,
50 ScriptMapUpdate="replace"
51 )
52
53 params.VirtualDirs = [vd]
54 HandleCommandLine(params)
Install your Pyramid project as Virtual Host or root feature¶
Activate your virtual env and run the stript:
python install_website.py install --server=<name of your website>
Restart your website from IIS.