Package: iiswsgi
Serving Python WSGI applications natively from IISTheiiswsgimodule implements a FastCGI toWSGIgateway that
is compatible withIIS’s variation of theFastCGI protocol.  It also
providesdistutilscommands for building, distributing and installingMicrosoft Web Deploy(MSDeploy) packages through theWeb Platform
Installer(WebPI).ContentsServing Python WSGI applications natively from IISQuick StartQuick Start for UsersQuick Start for DistributorsHow it WorksA Python DistributionCustom Set UpThe MSDeploy PackageThe WebPI FeedMSDeploy Package InstallationIIS HostingWeb Deploy Package ContentsSetup ScriptPython ManifestMSDeploy ManifestMSDeploy ParametersIIS Web ConfigIIS Install Stamp FileSetup CongigIIS WSGI Toolsiiswsgi FCGI GatewayBuild MSDeploy PackageInstall MSDeployTest MSDeployBuild MSDeploy DistributionMSDeploy Install BootstrapBuild WebPI Feed DistributionClean WebPI CachesDebuggingKnown IssuesChangelog0.3 - 2012-10-290.2 - 2012-10-130.1 -    UnknownQuick StartQuick Start for UsersTheiiswsgidistribution includes two sample IIS apps which can be
installed through WebPI once the custom feed has been added:Install and LaunchWeb Platform InstallerUse the search box in the upper-right to search forWeb MatrixClick add next to the most recentWeb Matrixentry, thenInstallin the lower-right and follow the instructionsOpen theOptionsdialog by clicking the link on the lower-rightUnderCustom Feeds, add the URL for latest*.webpi.xmlfile
from theiiswsgi downloadsand clickAdd feedUnderWhich Web Server…?, checkIIS Expressand then clickOKUse the search box in the upper-right to search forpyramidClick add next toPyramid ApplicationthenInstallin the
lower-right and follow the instructionsQuick Start for DistributorsAssuming an existingPythondistribution with aSetup Scriptusingsetuptoolsand aWSGI*.iniPaste config file, roughly
the following steps could be used to released to WebPI:Installiiswsgiinto the Python environment used to build releases:>C:\Python27\Scripts\easy_install.exe -U iiswsgiCopy the following to the dist root and adjust as appropriate:examples/pyramid.msdeploy/Manifest.xml.inexamples/pyramid.msdeploy/Parameters.xmlexamples/pyramid.msdeploy/iis_install.stamp.inexamples/pyramid.msdeploy/web.config.inAdd custom setup tosetup.py:...
from iiswsgi import install_msdeploy
...
class install_custom_msdeploy(install_msdeploy.install_msdeploy):
    def run(self):
        """Perform custom tasks."""
        os.environ['WEB_CONFIG_VAR'] = 'foo'
        self.pre_install()
        CUSTOM_SETUP
        self.post_install()
...
setup(
...
      cmdclass=dict(install_msdeploy=install_custom_msdeploy),
...Build a MSDeploy package:>C:\Python27\python.exe setup.py bdist_msdeployAdd WebPI dependencies tosetup.py:...
setup(
...
      extras_require=dict(install_msdeploy=['virtualenv'],
                          webpi_eggs=['virtualenv', 'iiswsgi']),
...Add WebPI feed metadata tosetup.py:Seeexamples/pyramid.msdeploy/setup.pyfor an example.Install theWeb Platform Installer:Install fciv.exeto generate SHA1 hashes:Must be placed on the%PATH%.  The recommended place would be%ProgramFiles%\Microsoft\WebPlatform Installerbecause it’s
placed on the path when WebPI is installed.Build a localWebPI feed:>C:\Python27\python.exe setup.py bdist_webpi -u "{msdeploy_package_url}" -m .Test locally:Launch the Web Platform InstallerClick on theoptionslink to the bottom right,Enter the feed URL below and clickAdd Feed:file:///C:/Users/%USERNAME%/Documents/GitHub/%DIST_NAME%/dist/%DIST_NAME%-%VERSION%-py2.7-win32.webpi.xmlClickOKand wait for WebPI to parse the feedSearch for your dist and installWatch WebPI launch Web Matrix and open the site in a browserUpload/Release:>C:\Python27\python.exe setup.py bdist_msdeploy bdist_webpi -m . uploadIf everything is working correctly, both a MSDeploy zip package and
the WebPI feed should be uploaded toPyPI.  Then you can instruct
users to add the feed to WebPI and they can install your package.How it WorksReleasing a WSGI app on IIS involves several steps and moving pieces.
See theWeb Deploy Package ContentsandIIS WSGI Toolssections
for more technical details.  Here is an overview of the process and
the technologies involved.A Python DistributionThis is a pre-requisite and is not at all specific to IIS, MSDeploy or
WebPI, only Python.  This is just a directory with asetup.pySetup Scriptthat defines the distribution and it’s metadata and
very little is done differently from the standard Pythondistutilsandsetuptoolsways of doing things.  IOW, wherever possible,iiswsgitries to re-usesetup.pymetadata and where it needs new
metadata it usessetuptoolsentry pointsto addsetup kwargs.Custom Set UpIf the app requires extra set up beyond just setting up avirtualenvand installing dependencies, this can also be
implemented insetup.pyby subclassing theinstall_msdeployInstall MSDeploycommand.  See theQuick Startand theInstall
MSDeploycommand for more details.The MSDeploy PackageMicrosoft’s Web Deploy Tool is what WebPI uses to install an IIS app
and expects aMSDeploy package, simple zip file with some metadata
in it.  There somespecial filesand threeiiswsgidistutilscommands that help in defining and building a MSDeploy package.  The
commands can also be run indiviually or run all at once by running
just the last step which will run the others first.  Running them
individually is useful to debug packaging problems.Build MSDeploy Packagebuild_msdeploycommandInstall MSDeployinstall_msdeploycommandTest MSDeploytest_msdeploycommandBuild MSDeploy Distributionbdist_msdeploycommandOn completion of the last command a MSDeploy zip file will be in thedistdirectory just like any other dist command, such assdist.  You can also upload the package using theuploadcommand.Logging output or managing verbosity for building the package is no
different than for any other disutils/setup.py uses, output is on the
console and can be redirected if you wan to capture it.  See>C:\Python27\python.exesetup.py--helpfor more details.The WebPI FeedThe Web Platform installer can be given additional feeds in it’s
options dialog.  This feed can define things that can be installed
along with their metadata including dependencies.  Thebdist_webpicommand can build this feed as another dist file, and can thus also be
released using theuploadcommand.To test locally, use thebdist_webpi-u"{msdeploy_package_url}"option to putfile:///...download URLs for the MSDeploy packages
in the feed.  Then use thefile:///...URL for the feed
itself in WebPI’s options dialog that is printed to the console when
thebdist_webpicommand is run.WebPI logs information while processing the feed in the%LOCALAPPDATA%\Microsoft/WebPlatform Installer/logs/webpidiretory.  When debugging feed issues just look at the most recently
modifiedwebpi#.txtfile in that directory.MSDeploy Package InstallationOnce the feed is included in WebPI, the entries can be searched for
and installed.  After installation, but before WebPI reports
completion, anyrunCommandproviders in theMSDeploy Manifestare
run which is wheniiswsgi_install.exescript is invoked to find the
installed app and to run distutils setup commands,install_msdeployandtest_msdeployby default, in that distribution.  Most apps will
want to use theiiswsgi_install.exe-eoption to setup a
virtualenv before running setup commands.  SeeMSDeploy Manifestandinstall_msdeployfor more details and considerations.While installing, WebPI and MSDeploy log output into%LOCALAPPDATA%\Microsoft/WebPlatform Installer/logs/install.
When debugging installation issues just look at theApp Title.txtfile in the most recently modified date-stamped direstory within that
directory.  Verbosity can be controlled by adding theiiswsgi_install.exe-voption in yourManifest.xml<runCommandpath=...attribute.  It’s also often valuable to run
theinstall_msdeploycommand locally in the installed app after an
installation error to debug further.IIS HostingIf installation has completed, there will be a<fastCgi><application...in the global IIS config, a corresponding
handler in the app’sweb.configand when a request comes in for
the app, IIS will invoke the handler specified.  Foriiswsgi, the
handler will be anpaster serveinvocation that uses theegg:iiswsgi#iisFCGI server.  To use a general purposePasteDeploy
INI configuration file, you can use a handler likepaster.exe serve-s"egg:iiswsgi#iis" ...to use theiiswsgiFCGI server with
a configuration file that doesn’t specify it.IIS swallows all FCGI process output if there are any errors starting
up which can make startup issues really hard to debug.  The first step
should be manually invoking the FCGI process using thefullPathandargumentsattributes from the<application...element inweb.config.  In case that doesn’t reproduce the error, theegg:iiswsgi#iisFCGI server tries to be conservative during startup
to ensure that output is loggedsomewhere.  Check the following
locations for output:%IIS_USER_HOME%\Logs\%IISEXPRESS_SITENAME%\iiswsgi.log%IIS_USER_HOME%\Logs\iiswsgi.log%TEMP%\iiswsgi.log\iiswsgi.logVerbosity is controlled by giving thepaster serve-v...option toPasteScriptin theweb.config.intemplate.Web Deploy Package ContentsA developer releasing a MSDeploy package of a Python web app,
interacts withiiswsgithough the following files in a Python
distribution.  Aside from these files, a Web Deploy package usingiiswsgiis no different than any other Python distribution or
project nor should any of theiiswsgipieces interfere with any
other uses of the same distribution.  In particular, it should be
possible to build and upload MSDeploy package and WebPI feed dists in
the same command as building and uploading any other dist.Setup ScriptAs with other Python build, distribute, and install tasks, thesetup.pyscript is where to control how the MSDeploy package is
built, what is distributed, and how it’s installed.Python ManifestUse Python’s source distributionMANIFEST.intemplate format to
declare what will be in the package.MSDeploy ManifestUse theManifest.xml.intemplate to generate theWeb Deploy
manifest.  When usingiiswsgi, it contains arunCommandprovider that invokes theiswsgi_install.exeMSDeploy Install
Bootstrapscript.  Most packages will want to install into avirtualenvby including a-eoption toiiswsgi_install.exe.Thebuild_msdeploycommand can be used to writerunCommand option
attributesinto the hash that MSDeploy uses when processing the
manifest during installation.  Most apps will want to include thesuccessReturnCodes="0x0"attribute to ensure that failures in the
command are reported back to the user.  Many apps will also want to
adjust thewaitAttempts="5"and/orwaitInterval="1000"attributes to give the commands enough time to complete.MSDeploy ParametersTheParameters.xmlfile defines the parameters WebPI will prompt
the user for when installing.  Seeexamples/pyramid.msdeploy/Parameters.xmlfor an example of using
parameters to influence custom setup.IIS Web ConfigUse theweb.config.intemplate to generate theIIS site
configuration file.  When usingiiswsgi, it contains afastCgiapplication that invokes theegg:iiswsgi#iisiiswsgi FCGI
Gateway.  Most packages will want to adjust the<application…attributes that control process behavior.  This is also where the*.iniconfig file orapp_factory entry pointthat define the
WSGI app to run are specified.IIS Install Stamp FileTheiis_install.stamp.intemplate copied into place to serve as
theiis_install.stampstamp file used by theiiswsgi_install.exeMSDeploy Install Bootstrapscript to find
the rightAPPL_PHYSICAL_PATHat install time.Setup CongigThesetup.cfgfile is only necessary if yourSetup Scriptis not
usingsetuptools.  IOW, undersetuptoolsthe commands are
automatically available isiiswsgiis installed and there’s no
need for this file.  Withoutsetuptools, use the following to make
theiiswsgidistutils commands available to your package:[global]
command_packages = iiswsgiIIS WSGI ToolsThe moving parts ofiiswsgiare as follows:iiswsgi FCGI GatewayTheegg:iiswsgi#iispaste.server_runnerorpaste.server_factoryis the FastCGI to WSGI gateway.  IIS invokes
thepasterscript fromPasteScriptwith aPasteDeploy INI
configuration fileto start a Python WSGI app as a FastCGI process.
Tellpasterto use the IIS FCGI gateway withpaster.exe serve-s"egg:iiswsgi#iis" ...or in thePasteDeploy INI configuration
file:[server:iis]
use = egg:iiswsgi#iisThis is not intrinsically related to thedistutilscommands and can
be used independently of them if a project should need to.IIS’ implementation of the FastCGI protocol is not fully compliant.
Most significantly, what is passed in onSTDIN_FILENOis not a
handle to an open socket but rather to aWindows named pipe.  This
names pipe does not support socket-like behavior, at least under
Python.  As such, theegg:iiswsgi#iisgateway extendsflup’s WSGI
to FCGI gatewayto support usingSTDIN_FILENOopened twice, once
each approximating therecvandsendend of a socket as is
specified in FastCGI.Build MSDeploy PackageThebuild_msdeploydistutils command compiles a MSDeployManifest.xmlconverting anyrunCommandattributes into the
necessary hash.  It will also copy into place theIIS Install Stamp
Fileiis_install.stampstamp file used by theMSDeploy Install
Bootstrapiiswsgi_install.exescript to find the rightAPPL_PHYSICAL_PATHat install time.Install MSDeployTheinstall_msdeploydistutils command performs common actions
needed to deploy Python web apps on IIS: install dependencies, do
variable substitution inweb.config, and install the FastCGI
application into the IIS global config.Since most apps will require path or parameter specific bits in theweb.configfile, theinstall_msdeploycommand will perform
variable substitution while writing theweb.config.intemplate toweb.config.  To add variables to the substitution, just useCustom Set Upto put them intoos.environbefore calling the
base class’srun()method.Since<fastCgi><application...elements don’t take effect in theweb.config, theinstall_msdeploycommand will use.  For
reference or debugging here’s an example:> appcmd.exe set config -section:system.webServer/fastCgi /+"[fullPath='%SystemDrive%\Python27\python.exe',arguments='-u %SystemDrive%\Python27\Scripts\iiswsgi-script.py -c %HOMEDRIVE%%HOMEPATH%\Documents\My Web Sites\FooApp\test.ini',maxInstances='%NUMBER_OF_PROCESSORS%',monitorChangesTo='C:\Users\Administrator\Documents\My Web Sites\FooApp\test.ini']" /commit:apphostSee theIIS FastCGI Referencefor
more details on how to configure IIS for FastCGI.  Note that you
cannot use environment variable in themonitorChangesToargument,
IIS will return an opaque 500 error.This is also where toCustom Set Upby subclassing theinstall_msdeployInstall MSDeploycommand in thesetup.pySetup Scriptand using the distutilscmdclasskwarg tosetup().  SeeQuick Startfor a small example orexamples\pyramid.msdeploy\setup.pyfor a working example.Test MSDeployThetest_msdeploydistutils command usespaster requestwith aPasteDeploy INI configuration fileto simulate sending a request to
the app.  If it fails, the command fails, making this useful to run
duringMSDeploy Package Installationto ensure the user sees an
error in WebPI if the app isn’t working even though the rest of the
install succeeded.  See>C:\Python27\python.exesetup.py test_msdeploy--helpfor more details.Build MSDeploy DistributionThebdist_msdeploydistutils command assembles an actual MSDeploy
package: It starts by running thebuild_msdeployBuild MSDeploy
Packagecommand.  Then it runs theinstall_msdeployInstall
MSDeploycommand in case your package needs any of the results of
the installation process and to test the installation process.
Finally, it creates aMSDeploy packagezip file with the contents
contolled by the same tools thatdistutilsprovides forsdistdistributions, includingMANIFEST.in.MSDeploy Install BootstrapTheiiswsgi_install.exescript bootstraps the MSDeploy package
install process optionally setting up a virtualenv first.  It finds
the correctAPPL_PHYSICAL_PATH, changes to that directory and
invokes theSetup Scriptwith arguments.This console script attempts to workaround the fact that WebPI and
MSDeploy don’t provide any context to the app being installed.
Specifically, when using therunCommandMSDeploy provider in theManifest.xml, the process started byrunCommandhas no way to
know which app it’s being invoked for on install: not the current
working directory, not in an argument, nor in any environment
variable.As such this script has to search for the app before calling it’sSetup Script.  It usesappcmd.exeto look in virtual directories
whose site matches the app name and which contain a stamp file still
in place.  See>Scripts\iiswsgi_install.exe--helpfor more
details.Build WebPI Feed DistributionThebdist_webpidistutils command assembles a WebPI feed from one
or more MSDeploy packages with dependencies.  The MSDeploy packages to
include are defined by passing paths to distrubutions withsetup.pyfiles whose MSDeploy dist zip files have previously been
built in the--msdeploy-bdistscommand option separated byshlex.split.  The download URLs for the MSDeploy zip files is
determined by expanding themsdeploy_url_templatesetup()kwarg withPython string.format().The global feed metadata is taken from the distribution the command is
being run for.  Entries are added to the feed for the distributions
lited in the--msdeploy-bdistscommand option and thewebpi_eggsdepdencies inextras_require. The WebPI dependencies
and related products are taken from the lists given in theinstall_msdeployandinstall_webpisetup()kwargs
respectivels.  The metadata for those entries is taken from the
corresponding distributions.  The following are additionalsetup()kwargs that are used in the feed if defined for a given distrubution:titleauthor_urllicense_urldisplay_urlhelp_urlpublishedicon_urlscreenshot_urldiscovery_fileClean WebPI CachesTheclean_webpidistutils command clears theWebPI cachesfor
one or more MSDeploy package downloads and the feed itself.  The
MSDeploy packages to be cleared from the cache are taken from the same--msdeploy-bdistscommand option.DebuggingOne of the more important goals ofiiswsgiis to bring some greater
transparency and introspection to the process of integrating with
IIS.  It’s a very common experience for developers in the
non-Window/UNIX world that developing and even deploying on Windows is
much more fragile and opaque than on any other OS.  Here’s some of
whatiiswsgidoes to try and address that.Graceful Degredation on non-WindowsFist and foremost,iiswsgitries to degrade gracefully when run
on non-windows platforms.  Specifically, when some executable,
environment variable, or other Windows specific piece of the
environment is missing, theiiswsgioperation will not raise an
exception but only log an error.  This allows developing and, to a
limited extent, testing MSDeploy packages onNIX platforms.  A
side-effect of this is that some errors may be missed when there
is a lot of console output from one of the `distutils`_ commands
when running *on Windows, so check your output carefully.LoggingFinding information about what went wrong when some part of the
process fails can be a lot more difficult on Windows than it is on
other platforms.  See the sections ofHow it Worksfor where to
look for log files for each part of the process.Known IssuesFCGI Process not launching under IISThe sample app will deploy just fine to IISExpress/Web Matrix, but
when switched over to full IIS, it reports that the FCGI process
exited prematurely.  Even after instrumenting the very top of the
script with writes to a file followed byflush()andfsync()the file still has nothing in it.  So it seems like
IIS is never actually launching the processs.  If anyone can test
this and give some insight, it would be greatly appreciated.Can’t accessAPPL_PHYSICAL_PATHinrunCommandproviderThe current method of searching for the  is far too fragile and it would
be vastly preferable if MSDeploy or WebPI set the
APPL_PHYSICAL_PATH environment variable forrunCommand.
Anyone with a MS support contract, please submit a request about
this.<fastCgi><application>doesn’t take effect inweb.configIt should be possible toregister a FCGI application in the
web.configfile but that doesn’t work.  Henceinstall_msdeployworks around this by reading theweb.configand usingAppCmd.exeto do the actually FCGI app
installation.  It would be much better ifweb.configworked as
it should.  Anyone with a MS support contract, please submit a
request about this.System.IO.FileNotFoundException: Could not find file'\\?\C:\...I’ve run into this error on Windows 7 on two different machines
and multiple installs, one OEM and one vanilla Windows 7 Extreme.
When this happens, it seems to happen when the “Web Platform
Installer” has been run, then exited, and then run again without
rebooting the machine in between.  To workaround this, you may
have to reboot the machine.  See the stack overflow questionMS
WebPI package runCommand not working in Manifest.xmlfor more
information.  As such, it’s not advisable to exit and re-launch
WebPI.  As such, the best way to get feed changes to take effect
in WebPI may be to:Click on theoptionslink in the bottom right of WebPIClick theXnext to your feed to remove itClickOKand wait for WebPI to finish updating the remaining feedsRuniiswsgi_webpi.exeClick on theoptionslink again in WebPIEnter the feed URL and clickAdd Feedto restore the feedClickOKand wait for WebPI againNow your feed changes should be reflected in WebPI.System.IO.FileNotFoundException: Could not load file or assemblyThis error happens when using WebPI to install on full IIS, IOW
when not using IIS Express and Web Matrix.  It can be worked
around by installing the “Web Deploy Tool” in WebPI.  Thebdist_webpicommand works around this by adding it as a
dependency for all MSDeploy packages.  Here’s the error from the
logs:DownloadManager Error: 0 : System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
File name: 'Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at Microsoft.Web.PlatformInstaller.MSDeployProxy.GetDeclaredParameters()
   at Microsoft.Web.PlatformInstaller.MSDeployPackage.get_DeclaredParameters()
   at Microsoft.Web.PlatformInstaller.UI.AppSitePage.GetApplicationName(MSDeployPackage package, String& appName)
   at Microsoft.Web.PlatformInstaller.UI.AppSitePage.InitializeComponent()retrieving the com class factory for remote component CLSID2b72133b-3f5b-4602-8952-803546CE3344error 80040154This error happens when using WebPI to install on full IIS, IOW
when not using IIS Express and Web Matrix.  It can be worked
around by installing the “IIS Management Console” in WebPI
dependencyWebPI Errors May be BurriedOn occasion, WebPI may burry error messages behind the WebPI
window.  So if WebPI has been hung for a long time, try usingAlt-TABto see if there’s an error window hidden behind the
WebPI window.WebPI getting cached feeds and MSDeploy packagesDespite theclean_webpihelper and manually clearing all the
caches under%LOCALAPPDATA%\Microsoft/WebPlatform Installer,
there have been several times when WebPI has still gotten stale
content causing validation errors against the SHA1 in the feed and
other problems.  When this happens, a workaround may be to
download the stale WebPI resources in IE.Changelog0.3 - 2012-10-29Convert server to a Paste serverUse distutils/setuptools commands for build and install process0.2 - 2012-10-13Custom build script approach0.1 -    UnknownInitial release