Sat, 10 Dec 2011

Tutorial: Running a Python Web Application in Windows Azure

The Windows Azure SDK includes command-line tools that make it easy to package and deploy almost anything to the cloud. In this tutorial, I’ll walk through how to use those tools to package a Python web application and deploy it to the cloud, assuming no prior Windows Azure experience.

Prerequisites

To follow this tutorial, you’ll need to install the Windows Azure SDK. Because this tutorial uses Python, you’ll also want to install Python 2.7.2. Python will automatically be installed in the cloud when you deploy this application, but to develop the app and test in the Windows Azure emulator, you’ll need Python installed locally.

To complete the last step of deploying to the cloud, you’ll need a Windows Azure account. (Sign up at http://windowsazure.com.)

Quick Walkthrough

  1. Download the code at https://github.com/smarx/pythonrole. You can either click the “zip” link at the top of the page, or you can use the git command-line tools:
    git clone git://github.com/smarx/pythonrole .
  2. Run %ProgramFiles%\Windows Azure SDK\<version>\bin\setenv to add the Windows Azure SDK tools to your path, and then change directory back to where you downloaded pythonrole.
  3. Add python.exe to your path if it isn’t already there.
  4. Type run to run the application locally. Open up the browser to the address and port you see in the output of run. You should see the text “Hello, World!”
  5. Type pack to create a Windows Azure package containing the application.
  6. Browse to the Windows Azure portal and deploy the application by clicking the “new hosted service” button and filling out the dialog. The “package location” and “configuration file” should be PackAndDeploy.cspkg and ServiceConfiguration.Cloud.cscfg in the root of your packanddeploy project.

How It Works

To understand the basics of how the project is structured, first read my “Running the Mongoose Web Server in Windows Azure” tutorial. Where this project differs is around installing and executing Python.

Because installing Python requires elevated privileges, the installation is separated into a startup task. Startup tasks in Windows Azure run before the main application is started. Because they can be set to run as an elevated user (independent of whether the main application runs elevated), they’re useful for tasks like installing prerequisite components or otherwise setting up the environment. Startup tasks are defined in ServiceDefinition.csdef. The pythonrole project defines two startup tasks:

<Startup>
  <Task commandLine="installPython.cmd" executionContext="elevated">
    <Environment>
      <Variable name="EMULATED">
        <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
      </Variable>
      <Variable name="PYTHON_PATH">
        <RoleInstanceValue
          xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='python']/@path" />
      </Variable>
    </Environment>
  </Task>
  <Task commandLine="installDependencies.cmd">
    <Environment>
      <Variable name="PYTHON_PATH">
        <RoleInstanceValue
          xpath="/RoleEnvironment/CurrentInstance/LocalResources/LocalResource[@name='python']/@path" />
      </Variable>
    </Environment>
  </Task>
</Startup>

The first startup task (installPython.cmd) installs Python by downloading the Python installer and executing it (line break inserted for formatting):

powershell -c "(new-object System.Net.WebClient).DownloadFile('http://python.org/ftp/python/2.7.2/python-2.7.2.msi', 'python.msi')"
start /w msiexec /i python.msi /qn TARGETDIR="%PYTHON_PATH%"

The second startup task (installDependencies.cmd) creates a virtual Python environment using virtualenv and installs any modules our application depends on by running pip:

python virtualenv.py --no-site-packages .
call scripts\activate
cd app
pip install -r requirements.txt

requirements.txt is a simple text file with names of modules (and optionally versions). It follows the format emitted by pip freeze.

After all the startup tasks have run, the main entry point of the application (run.cmd) is executed. This activates the Python virtual environment and launches the app with python app.py. As in the Mongoose tutorial, environment variables are used to pass the correct IP address and port to the application.

More Information

For more information about the basic techniques used in this project, read the “Running the Mongoose Web Server in Windows Azure” tutorial.

View the full source code for pythonrole on GitHub: https://github.com/smarx/pythonrole.