Introduction

You're knee deep in learning the Python programming language. The syntax is beginning to make sense. The first few "AHA!" moments are hitting you. Now you are excited for direction to learn more.

Now what? Definitely read Kenneth Reitz's The Hitchhiker’s Guide to Python If you're not coming from a development background, you may find this post on Learning Python useful.

This guide has a different focus from the above resources. Here I focus on explaining several ways of setting up a Python web application stack from server infrastructure through JavaScript execution on a user's browser.

About the Author

I'm Matt Makai and I solve problems by developing software. I often use Python and occasionally work with languages in the Java Virtual Machine (JVM) stack.

In 2013 I will be traveling to 30 cities in the United States to visit with tech companies, attend and speak at tech meetups, and blog from an experienced software developer's perspective about the current state of technology in the United States. If you're reading this guide then you're likely someone I'm interested in meeting during my trip. Send me an email at matthew.makai@gmail.com or message me on Twitter. Read more about my upcoming trip that will take place between March 9 and August 15, 2013 at Coding Across America.

If there are typos, inaccurate statements, or general areas for improvement that you see in this guide, please issue a pull request on this website's Github repository. Thank you!

Servers

There are four options for setting up infrastructure to serve a web application:

  1. "Bare metal" servers
  2. Virtualized servers
  3. Infrastructure-as-a-service
  4. Platform-as-a-service

Bare metal

The term bare metal refers to purchasing the actual hardware and hooking it up to the Internet either through a business-class internet service provider (ISP) or co-locating the server with other servers. A "business-class" ISP is necessary because most residential Internet service agreements prohibt and will eventually block traffic to web servers. You may be able to get away with low traffic volume but if your site serves a lot of traffic it will catch an ISPs filters.

The bare metal option offers the most control over the server configuration, usually has the highest performance for the price, but also is the most expensive upfront option and the highest ongoing maintenance. With bare metal servers the ongoing operating cost is the electricity the server(s) use as well as handling repairs when server components malfunction. You're taking on manual labor working with hardware as well as the rest of the software stack.

Buy actual hardware from a vendor either pre-built or as a collection of components that you assemble yourself. Here is an example of a server buildout. The post is a couple of years old but those are the rough components you need to put together your own server. You can also buy pre-configured servers from Dell or HP. Those servers tend to be in smaller case form factors (called "blades") but are correspondingly more expensive than putting off-the-shelf components together yourself.

Virtualized servers

Virtual private servers (VPSs) are slices of hardware on top of a larger bare metal server. Virtualization software such as Xen and VMWare allow providers such as Linode and prgmr (as well as a many others) to provide fractions of a full server that appear as their own instances. For example, a server with an 8-core Xeon processor and 16 gigabytes of memory can be sliced into 8 pieces with the equivalent of 1-core and 2 gigabytes of memory.

The primary disadvantage of virtualized servers is that there is resource overhead in the virtualization process. In addition, physical constraints such as heavy I/O operations by a single virtualized instance on persistent storage can cause performance bottlenecks for other virtualized instances on the shared server. Choosing virtualized server hosting should be based on your needs for urgency of service ticket requests and the frequency you require for ongoing maintenance such as persistent storage backups.

Infrastructure-as-a-service

Infrastructure-as-a-service (IaaS) overlaps with virtualized servers because the resources are often presented in the same way. The difference between virtualized servers and IaaS is the granularity of the billing cycle. IaaS generally encourages a finer granularity based on minutes or hours of server usage instead of on monthly billing cycles.

IaaS can be used in combination with virtualized servers to provide dynamic upscaling for heavy traffic. When traffic is low then virtualized servers can solely be used. This combination of resources reduces cost at the expense of greater complexity in the dynamically scaled infrastructure.

The most common IaaS platforms are Amazon Web Services and Rackspace Cloud.

The disadvantage to IaaS platforms is the lock-in if you have to write custom code to deploy, dynamically scale, and generally understand your infrastructure. Every platform has its quirks. For example, Amazon's standard Elastic Block Store storage infrastructure has at least an order of magnitude worse I/O throughput than working with your local disk. Your application's database queries may work great locally but then when you deploy the performance is inadequate. Amazon has higher throughput EBS instances but you will pay correspondingly more for them. EBS throughput is just one of many quirks you need to understand before committing to an IaaS platform.

Platform-as-a-service

A platform-as-a-service (PaaS) provides infrastructure and a software layer on which a web application is deployed. The PaaS layer defines how the application accesses resources such as computing time, files, and external services. The PaaS provides a higher-level abstraction for working with computing resources than deploying an application to a server or IaaS.

A PaaS makes deployment and operations easier because it forces the developer to conform applications to the PaaS architecture.

Heroku, Google App Engine, Gondor, and OpenShift are platform-as-services that support Python web applications. Each one requires varying tradeoffs to deploy to their respective platforms.

If you go the PaaS route, you can skip over the operating system and web server sections because they are baked into PaaS offerings. PaaS offerings generally start at the WSGI server layer.

Server Monitoring

Server uptime, that the server is powered and reachable over the network, must be monitored on this level. That means an outside host must perform the monitoring to ensure availablity. Other attributes of the server such as CPU and memory utilization are grouped under the "Operating System" section.

Server Resources

How to set up a safe and secure Web server (Ars Technica)

Staging Servers, Source Control & Deploy Workflows, And Other Stuff Nobody Teaches You (Patrick McKenzie)

Choosing Heroku (Randall Degges)

Choosing a low cost VPS

boto is an amazing Python library for working with Amazon Web Services

Operating System

The operating system runs on top of the server or virtual server and controls access to computing resources. The only operating system I can recommend for production Python web stack deployments is a flavor of Linux. Ubuntu Long Term Support (LTS) releases, Red Hat Enterprise Linux, and CentOS are all viable options.

Side note: Mac OS X is fine for development activities but not for test/production deployments.

Ubuntu

Ubuntu is a Linux distribution packaged by the Canonical Ltd company. Ubuntu uses the Debian distribution as a base for packages, including the aptitude package manager. For desktop versions of Ubuntu, GNOME (until the 11.04 release) or Unity (11.10 through current) is added to the distribution to provide a user interface.

Ubuntu Long Term Support (LTS) releases are the recommended versions to use for deployments. LTS versions receive five years of post-release updates from Canonical. Every two years, Canonical creates a new LTS release, which allows for an easy upgrade path as well as flexibility in skipping every other LTS release if necessary.

Red Hat and CentOS

Red Hat Enterprise Linux (RHEL) and Community ENTerprise Operating System (CentOS) are the same distribution. The only difference between the two (other than the name) is that CentOS is an open source, liberally licensed free derivative of RHEL.

RHEL and CentOS use a different package manager and command-line interface from Debian-based Linux distributions: RPM Package Manager (RPM) and the Yellowdog Updater, Modified (YUM). RPM has a specific .rpm file format to handle the packaging and installation of libraries and applications. YUM provides a command-line interface for interacting with the RPM system.

Monitoring

There are several important resources to monitor on the operating system and network level of a web stack.

  1. CPU utilization
  2. Memory utilization
  3. Persistence storage consumed versus free
  4. Network bandwidth and latency

Operating System Resources

Securing an Ubuntu Server

Web Server

A web server handles Hypertext Transfer Protocol (HTTP) requests from clients. The client is usually a browser such as Internet Explorer, Firefox, and Chrome, but it can also be a headless browser like phantomjs (commonly used for testing), a commandline utility like wget or curl, or a web crawler. The web server processes the request and sends a status code and depending on the status code a content response as well.

In a simple case, the client will request a static asset such as a picture or JavaScript file. The file sits on the file system in a location the web server is authorized to access and the web server sends the file to the clinet with a 200 status code. If the client already requested the file and the file has not changed, the web server will pass back a 304 "Not modified" response indicating the client already has the latest version of that file.

Web server and web browser request-response cycles

A web server sends files to a web browser based on the web browser's request. In the first request, the browser accessed the "www.example.com" address and the server responded with the index.html HTML-formatted file. That HTML file contained references to other files, such as style.css and script.js that the browser then requested from the server.

Sending static assets (such as CSS and JavaScript files) can eat up a large amount of bandwidth which is why using a Content Delivery Network (CDN) is important when possible (see the content delivery network section for a more detailed explanation).

Database

A database provides an abstraction on top of a file system for creating, reading, updating, and deleting persistent data. The abstraction most commonly represented is a set of relational tables, known as a relational database management system (RDBMS). Alternative abstractions include graph databases where data is stored in both nodes and edges of a graph.

Database resources

PostgreSQL and MySQL are two of the most common open source databases.

SQLite is a database that is stored in a single file on disk. SQLite is built into Python but is only built for access by a single connection at a time.

WSGI Server

A Web Server Gateway Interface (WSGI) server implements the web server side of the WSGI interface for running Python web applications. The WSGI standard v1.0 is specified in PEP 0333. As of September 2010, WSGI v1.0 is superseded by PEP 3333, which defines the v1.0.1 WSGI standard.


WSGI Server <-> Web server <-> Browser

Requests from the browser that are not for static assets (this is specified in the web server's configuration which requests are for static assets and which are not) are passed to the WSGI server. Once the request is processed by the WSGI server, the request is passed back through the web server and onto the browser.


WSGI Resources

PEP 0333 WSGI v1.0 and PEP 3333 WSGI v1.0.1 specifications.

Green Unicorn, mod_wsgi, uWSGI, and gevent are common WSGI server implementations.

Complete single server Django stack tutorial is thorough and informative for non-paas hosting choices.

Web Framework

A web application framework is a collection of libraries that provide functionality to accomplish common operations for the web. These common operations include:

  1. URL routing
  2. HTML, XML, JSON, and other output templating
  3. Database manipulation
  4. Cross-site request forgery (CSRF) and Cross-site scripting (XSS) protection

Not all web frameworks include functionality for all of the above functionality. Frameworks must balance between "being all things to all people but very complicated" or doing only certain things well without prescription for how to do other functions.

For example, the Django web application framework includes an Object-Relational Mapping (ORM) layer that abstracts relational database read, write, query, and delete operations. However, the ORM layer in Django does not work (without modification) on non-relational databases such MongoDB and Riak. Other web frameworks such as Flask and Pyramid are generally easier to use with non-relational databases by incorporating external Python libraries.

Web Framework Monitoring

Logging is a common mechanism for monitoring web applications written with a web framework. Runtime exceptions that prevent code from running are important to log to investigate and fix the source of the problems. Informational and debugging logging also helps to understand how the application is performing even if code is working as intended.

Logging is often grouped into several categories:

  1. Information
  2. Debug
  3. Warning
  4. Error

Web Framework Resources

Django, Flask, Bottle, Pyramid, and web.py are the most common Python web frameworks.

CDN

A content delivery network (CDN) serves static file assets. Amazon CloudFront, Akamai, and Rackspace Cloud Files are examples of CDNs. The purpose of a CDN is to remove the load of static file requests from web servers that are handling dynamic web content. For example, if you have an nginx server that handles both static files and acts as a front for a Green Unicorn WSGI server on a 512 megabyte virtual private server, the nginx server will run into resource constraints under heavy traffic. A CDN can remove the need to serve static assets from that nginx server so it can purely act as a pass through for requests to the Green Unicorn WSGI server.

CDNs distribute request load globally by using data centers in different locations.

Web Analytics

Web analytics involves a mix of collecting and analyzing data generated by visitors to a website.

Web Analytics Resources

Google Analytics for Developers

Caching

Caching can reduce load on servers by storing the results of common operations and serving the precomputed answers to clients.

Caching Resources

memcached is a common in-memory caching system.

Change Log

2013.01.11: Fleshing out server section, particularly IaaS and PaaS.

2013.01.04: Added initial trial of a WSGI server -> web server -> browser diagram. Updated web server and OS sections.

2013.01.02: Minor updates to OS section.

2012.12.30: Updated introduction with improved wording. Working on CDN section. Added very basic database content and removed stub from that section.

2012.12.27: Added beginning of section on Python web frameworks. Added stub for content delivery network.

2012.12.25: Initial incomplete release on fullstackpython.com.