<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>HOWTO Use Python in the web — Python v3.1.1 documentation</title> <link rel="stylesheet" href="../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '3.1.1', COLLAPSE_MODINDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <link rel="search" type="application/opensearchdescription+xml" title="Search within Python v3.1.1 documentation" href="../_static/opensearch.xml"/> <link rel="author" title="About these documents" href="../about.html" /> <link rel="copyright" title="Copyright" href="../copyright.html" /> <link rel="top" title="Python v3.1.1 documentation" href="../index.html" /> <link rel="up" title="Python HOWTOs" href="index.html" /> <link rel="next" title="Glossary" href="../glossary.html" /> <link rel="prev" title="HOWTO Fetch Internet Resources Using The urllib Package" href="urllib2.html" /> <link rel="shortcut icon" type="image/png" href="../_static/py.png" /> </head> <body> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="../modindex.html" title="Global Module Index" accesskey="M">modules</a> |</li> <li class="right" > <a href="../glossary.html" title="Glossary" accesskey="N">next</a> |</li> <li class="right" > <a href="urllib2.html" title="HOWTO Fetch Internet Resources Using The urllib Package" accesskey="P">previous</a> |</li> <li><img src="../_static/py.png" alt="" style="vertical-align: middle; margin-top: -1px"/></li> <li><a href="../index.html">Python v3.1.1 documentation</a> »</li> <li><a href="index.html" accesskey="U">Python HOWTOs</a> »</li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="howto-use-python-in-the-web"> <h1>HOWTO Use Python in the web<a class="headerlink" href="#howto-use-python-in-the-web" title="Permalink to this headline">¶</a></h1> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">Author:</th><td class="field-body">Marek Kubica</td> </tr> </tbody> </table> <div class="topic"> <p class="topic-title first">Abstract</p> <p>This document shows how Python fits into the web. It presents some ways on how to integrate Python with the web server and general practices useful for developing web sites.</p> </div> <p>Programming for the Web has become a hot topic since the raise of the “Web 2.0”, which focuses on user-generated content on web sites. It has always been possible to use Python for creating web sites, but it was a rather tedious task. Therefore, many so-called “frameworks” and helper tools were created to help developers creating sites faster and these sites being more robust. This HOWTO describes some of the methods used to combine Python with a web server to create dynamic content. It is not meant as a general introduction as this topic is far too broad to be covered in one single document. However, a short overview of the most popular libraries is provided.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p class="last">While this HOWTO tries to give an overview over Python in the Web, it cannot always be as up to date as desired. Web development in Python is moving forward rapidly, so the wiki page on <a class="reference external" href="http://wiki.python.org/moin/WebProgramming">Web Programming</a> might be more in sync with recent development.</p> </div> <div class="section" id="the-low-level-view"> <h2>The low-level view<a class="headerlink" href="#the-low-level-view" title="Permalink to this headline">¶</a></h2> <p>When a user enters a web site, his browser makes a connection to the site’s webserver (this is called the <em>request</em>). The server looks up the file in the file system and sends it back to the user’s browser, which displays it (this is the <em>response</em>). This is roughly how the unterlying protocol, HTTP works.</p> <p>Now, dynamic web sites are not files in the file system, but rather programs which are run by the web server when a request comes in. They can do all sorts of useful things, like display the postings of a bulletin board, show your mails, configurate software or just display the current time. These programs can be written in about any programming language the server supports, so it is easy to use Python for creating dynamic web sites.</p> <p>As most of HTTP servers are written in C or C++, they cannot execute Python code in a simple way – a bridge is needed between the server and the program. These bridges or rather interfaces define how programs interact with the server. In the past there have been numerous attempts to create the best possible interface, but there are only a few worth mentioning.</p> <p>Not every web server supports every interface. Many web servers do support only old, now-obsolete interfaces. But they can often be extended using some third-party modules to support new interfaces.</p> <div class="section" id="common-gateway-interface"> <h3>Common Gateway Interface<a class="headerlink" href="#common-gateway-interface" title="Permalink to this headline">¶</a></h3> <p>This interface is the oldest one, supported by nearly every web server out of the box. Programs using CGI to communicate with their web server need to be started by the server for every request. So, every request starts a new Python interpreter – which takes some time to start up – thus making the whole interface only usable for low load situations.</p> <p>The upside of CGI is that it is simple – writing a program which uses CGI is a matter of about three lines of code. But this simplicity comes at a price: it does very few things to help the developer.</p> <p>Writing CGI programs, while still possible, is not recommended anymore. With WSGI (more on that later) it is possible to write programs that emulate CGI, so they can be run as CGI if no better option is available.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p>The Python standard library includes some modules that are helpful for creating plain CGI programs:</p> <ul class="simple"> <li><a title="Helpers for running Python scripts via the Common Gateway Interface." class="reference external" href="../library/cgi.html#module-cgi"><tt class="xref docutils literal"><span class="pre">cgi</span></tt></a> – Handling of user input in CGI scripts</li> <li><a title="Configurable traceback handler for CGI scripts." class="reference external" href="../library/cgitb.html#module-cgitb"><tt class="xref docutils literal"><span class="pre">cgitb</span></tt></a> – Displays nice tracebacks when errors happen in of CGI applications, instead of presenting a “500 Internal Server Error” message</li> </ul> <p class="last">The Python wiki features a page on <a class="reference external" href="http://wiki.python.org/moin/CgiScripts">CGI scripts</a> with some additional information about CGI in Python.</p> </div> <div class="section" id="simple-script-for-testing-cgi"> <h4>Simple script for testing CGI<a class="headerlink" href="#simple-script-for-testing-cgi" title="Permalink to this headline">¶</a></h4> <p>To test whether your web server works with CGI, you can use this short and simple CGI program:</p> <div class="highlight-python3"><div class="highlight"><pre><span class="c">#!/usr/bin/env python</span> <span class="c"># -*- coding: UTF-8 -*-</span> <span class="c"># enable debugging</span> <span class="kn">import</span> <span class="nn">cgitb</span> <span class="n">cgitb</span><span class="o">.</span><span class="n">enable</span><span class="p">()</span> <span class="nb">print</span><span class="p">(</span><span class="s">"Content-Type: text/plain;charset=utf-8"</span><span class="p">)</span> <span class="nb">print</span><span class="p">()</span> <span class="nb">print</span><span class="p">(</span><span class="s">"Hello World!"</span><span class="p">)</span> </pre></div> </div> <p>You need to write this code into a file with a <tt class="docutils literal"><span class="pre">.py</span></tt> or <tt class="docutils literal"><span class="pre">.cgi</span></tt> extension, this depends on your web server configuration. Depending on your web server configuration, this file may also need to be in a <tt class="docutils literal"><span class="pre">cgi-bin</span></tt> folder, for security reasons.</p> <p>You might wonder what the <tt class="docutils literal"><span class="pre">cgitb</span></tt> line is about. This line makes it possible to display a nice traceback instead of just crashing and displaying an “Internal Server Error” in the user’s browser. This is useful for debugging, but it might risk exposing some confident data to the user. Don’t use it when the script is ready for production use. Still, you should <em>always</em> catch exceptions, and display proper error pages – end-users don’t like to see nondescript “Internal Server Errors” in their browsers.</p> </div> <div class="section" id="setting-up-cgi-on-your-own-server"> <h4>Setting up CGI on your own server<a class="headerlink" href="#setting-up-cgi-on-your-own-server" title="Permalink to this headline">¶</a></h4> <p>If you don’t have your own web server, this does not apply to you. You can check whether if works as-is and if not you need to talk to the administrator of your web server anyway. If it is a big hoster, you can try filing a ticket asking for Python support.</p> <p>If you’re your own administrator or want to install it for testing purposes on your own computers, you have to configure it by yourself. There is no one and single way on how to configure CGI, as there are many web servers with different configuration options. The currently most widely used free web server is <a class="reference external" href="http://httpd.apache.org/">Apache HTTPd</a>, Apache for short – this is the one that most people use, it can be easily installed on nearly every system using the systems’ package management. But <a class="reference external" href="http://www.lighttpd.net">lighttpd</a> has been gaining attention since some time and is said to have a better performance. On many systems this server can also be installed using the package management, so manually compiling the web server is never needed.</p> <ul class="simple"> <li>On Apache you can take a look into the <a class="reference external" href="http://httpd.apache.org/docs/2.2/howto/cgi.html">Dynamic Content with CGI</a> tutorial, where everything is described. Most of the time it is enough just to set <tt class="docutils literal"><span class="pre">+ExecCGI</span></tt>. The tutorial also describes the most common gotchas that might arise.</li> <li>On lighttpd you need to use the <a class="reference external" href="http://trac.lighttpd.net/trac/wiki/Docs%3AModCGI">CGI module</a> which can be configured in a straightforward way. It boils down to setting <tt class="docutils literal"><span class="pre">cgi.assign</span></tt> properly.</li> </ul> </div> <div class="section" id="common-problems-with-cgi-scripts"> <h4>Common problems with CGI scripts<a class="headerlink" href="#common-problems-with-cgi-scripts" title="Permalink to this headline">¶</a></h4> <p>Trying to use CGI sometimes leads to small annoyances that one might experience while trying to get these scripts to run. Sometimes it happens that a seemingly correct script does not work as expected, which is caused by some small hidden reason that’s difficult to spot.</p> <p>Some of these reasons are:</p> <ul class="simple"> <li>The Python script is not marked executable. When CGI scripts are not executable most of the web servers will let the user download it, instead of running it and sending the output to the user. For CGI scripts to run properly the <tt class="docutils literal"><span class="pre">+x</span></tt> bit needs to be set. Using <tt class="docutils literal"><span class="pre">chmod</span> <span class="pre">a+x</span> <span class="pre">your_script.py</span></tt> might already solve the problem.</li> <li>The line endings must be of Unix-type. This is important because the web server checks the first line of the script (called shebang) and tries to run the program specified there. It gets easily confused by Windows line endings (Carriage Return & Line Feed, also called CRLF), so you have to convert the file to Unix line endings (only Line Feed, LF). This can be done automatically by uploading the file via FTP in text mode instead of binary mode, but the preferred way is just telling your editor to save the files with Unix line endings. Most proper editors support this.</li> <li>Your web server must be able to read the file, you need to make sure the permissions are fine. Often the server runs as user and group <tt class="docutils literal"><span class="pre">www-data</span></tt>, so it might be worth a try to change the file ownership or making the file world readable by using <tt class="docutils literal"><span class="pre">chmod</span> <span class="pre">a+r</span> <span class="pre">your_script.py</span></tt>.</li> <li>The webserver must be able to know that the file you’re trying to access is a CGI script. Check the configuration of your web server, maybe there is some mistake.</li> <li>The path to the interpreter in the shebang (<tt class="docutils literal"><span class="pre">#!/usr/bin/env</span> <span class="pre">python</span></tt>) must be currect. This line calls <tt class="docutils literal"><span class="pre">/usr/bin/env</span></tt> to find Python, but it’ll fail if there is no <tt class="docutils literal"><span class="pre">/usr/bin/env</span></tt>. If you know where your Python is installed, you can also use that path. The commands <tt class="docutils literal"><span class="pre">whereis</span> <span class="pre">python</span></tt> and <tt class="docutils literal"><span class="pre">type</span> <span class="pre">-p</span> <span class="pre">python</span></tt> might also help to find where it is installed. Once this is known, the shebang line can be changed accordingly: <tt class="docutils literal"><span class="pre">#!/usr/bin/python</span></tt>.</li> <li>The file must not contain a BOM (Byte Order Mark). The BOM is meant for determining the byte order of UTF-16 encodings, but some editors write this also into UTF-8 files. The BOM interferes with the shebang line, so be sure to tell your editor not to write the BOM.</li> <li><a class="reference internal" href="#mod-python"><em>mod_python</em></a> might be making problems. mod_python is able to handle CGI scripts by itself, but it can also be a source for problems. Be sure you disable it.</li> </ul> </div> </div> <div class="section" id="mod-python"> <span id="id1"></span><h3>mod_python<a class="headerlink" href="#mod-python" title="Permalink to this headline">¶</a></h3> <p>People coming from PHP often find it hard to grasp how to use Python in the web. Their first thought is mostly <a class="reference external" href="http://www.modpython.org/">mod_python</a> because they think that this is the equivalent to <tt class="docutils literal"><span class="pre">mod_php</span></tt>. Actually it is not really. It does embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python interpreter every request. On the other hand, it is by far not “Python intermixed with HTML” as PHP often does. The Python equivalent of that is a template engine. mod_python itself is much more powerful and gives more access to Apache internals. It can emulate CGI, it can work an a “Python Server Pages” mode similar to JSP which is “HTML intermangled with Python” and it has a “Publisher” which destignates one file to accept all requests and decide on what to do then.</p> <p>But mod_python has some problems. Unlike the PHP interpreter the Python interpreter uses caching when executing files, so when changing a file the whole web server needs to be re-started to update. Another problem ist the basic concept – Apache starts some child processes to handle the requests and unfortunately every child process needs to load the whole Python interpreter even if it does not use it. This makes the whole web server slower. Another problem is that as mod_python is linked against a specific version of <tt class="docutils literal"><span class="pre">libpython</span></tt>, it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to the Apache web server, so programs written for mod_python cannot easily run on other web servers.</p> <p>These are the reasons why mod_python should be avoided when writing new programs. In some circumstances it might be still a good idea to use mod_python for deployment, but WSGI makes it possible to run WSGI programs under mod_python as well.</p> </div> <div class="section" id="fastcgi-and-scgi"> <h3>FastCGI and SCGI<a class="headerlink" href="#fastcgi-and-scgi" title="Permalink to this headline">¶</a></h3> <p>FastCGI and SCGI try to solve the performance problem of CGI in another way. Instead of embedding the interpreter into the web server, they create long-running processes which run in the background. There still is some module in the web server which makes it possible for the web server to “speak” with the background process. As the background process is independent from the server, it can be written in any language of course also in Python. The language just needs to have a library which handles the communication with the web server.</p> <p>The difference between FastCGI and SCGI is very small, as SCGI is essentially just a “simpler FastCGI”. But as the web server support for SCGI is limited most people use FastCGI instead, which works the same way. Almost everything that applies to SCGI also applies to FastCGI as well, so we’ll only write about the latter.</p> <p>These days, FastCGI is never used directly. Just like <tt class="docutils literal"><span class="pre">mod_python</span></tt> it is only used for the deployment of WSGI applications.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <ul class="last simple"> <li><a class="reference external" href="http://www.vmunix.com/mark/blog/archives/2006/01/02/fastcgi-scgi-and-apache-background-and-future/">FastCGI, SCGI, and Apache: Background and Future</a> is a discussion on why the concept of FastCGI and SCGI is better that that of mod_python.</li> </ul> </div> <div class="section" id="setting-up-fastcgi"> <h4>Setting up FastCGI<a class="headerlink" href="#setting-up-fastcgi" title="Permalink to this headline">¶</a></h4> <p>Depending on the web server you need to have a special module.</p> <ul class="simple"> <li>Apache has both <a class="reference external" href="http://www.fastcgi.com/">mod_fastcgi</a> and <a class="reference external" href="http://fastcgi.coremail.cn/">mod_fcgid</a>. <tt class="docutils literal"><span class="pre">mod_fastcgi</span></tt> is the original one, but it has some licensing issues that’s why it is sometimes considered non-free. <tt class="docutils literal"><span class="pre">mod_fcgid</span></tt> is a smaller, compatible alternative. One of these modules needs to be loaded by Apache.</li> <li>lighttpd ships its own <a class="reference external" href="http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI">FastCGI module</a> as well as an <a class="reference external" href="http://trac.lighttpd.net/trac/wiki/Docs%3AModSCGI">SCGI module</a>.</li> <li>nginx also supports <a class="reference external" href="http://wiki.codemongers.com/NginxSimplePythonFCGI">FastCGI</a>.</li> </ul> <p>Once you have installed and configured the module, you can test it with the following WSGI-application:</p> <div class="highlight-python3"><div class="highlight"><pre><span class="c">#!/usr/bin/env python</span> <span class="c"># -*- coding: UTF-8 -*-</span> <span class="kn">import</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">os</span> <span class="kn">from</span> <span class="nn">cgi</span> <span class="k">import</span> <span class="n">escape</span> <span class="kn">from</span> <span class="nn">flup.server.fcgi</span> <span class="k">import</span> <span class="n">WSGIServer</span> <span class="k">def</span> <span class="nf">app</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span> <span class="n">start_response</span><span class="p">(</span><span class="s">'200 OK'</span><span class="p">,</span> <span class="p">[(</span><span class="s">'Content-Type'</span><span class="p">,</span> <span class="s">'text/html'</span><span class="p">)])</span> <span class="k">yield</span> <span class="s">'<h1>FastCGI Environment</h1>'</span> <span class="k">yield</span> <span class="s">'<table>'</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">environ</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span> <span class="k">yield</span> <span class="s">'<tr><th>{0}</th><td>{1}</td></tr>'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span> <span class="n">escape</span><span class="p">(</span><span class="n">k</span><span class="p">),</span> <span class="n">escape</span><span class="p">(</span><span class="n">v</span><span class="p">))</span> <span class="k">yield</span> <span class="s">'</table>'</span> <span class="n">WSGIServer</span><span class="p">(</span><span class="n">app</span><span class="p">)</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> </pre></div> </div> <p>This is a simple WSGI application, but you need to install <a class="reference external" href="http://pypi.python.org/pypi/flup/1.0">flup</a> first, as flup handles the low level FastCGI access.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p class="last">There is some documentation on <a class="reference external" href="http://www.djangoproject.com/documentation/fastcgi/">setting up Django with FastCGI</a>, most of which can be reused for other WSGI-compliant frameworks and libraries. Only the <tt class="docutils literal"><span class="pre">manage.py</span></tt> part has to be changed, the example used here can be used instead. Django does more or less the exact same thing.</p> </div> </div> </div> <div class="section" id="mod-wsgi"> <h3>mod_wsgi<a class="headerlink" href="#mod-wsgi" title="Permalink to this headline">¶</a></h3> <p><a class="reference external" href="http://www.modwsgi.org/">mod_wsgi</a> is an attempt to get rid of the low level gateways. As FastCGI, SCGI, mod_python are mostly used to deploy WSGI applications anyway, mod_wsgi was started to directly embed WSGI aplications into the Apache web server. The benefit from this approach is that WSGI applications can be deployed much easier as is is specially designed to host WSGI applications – unlike the other low level methods which have glue code to host WSGI applications (like flup which was mentioned before). The downside is that mod_wsgi is limited to the Apache web server, other servers would need their own implementations of mod_wsgi.</p> <p>It supports two modes: the embedded mode in which it integrates with the Apache process and the daemon mode which is more FastCGI-like. Contrary to FastCGI, mod_wsgi handles the worker-processes by itself which makes administration easier.</p> </div> </div> <div class="section" id="step-back-wsgi"> <span id="wsgi"></span><h2>Step back: WSGI<a class="headerlink" href="#step-back-wsgi" title="Permalink to this headline">¶</a></h2> <p>WSGI was already mentioned several times so it has to be something important. In fact it really is, so now it’s time to explain.</p> <p>The <em>Web Server Gateway Interface</em>, <span class="target" id="index-164"></span><a class="reference external" href="http://www.python.org/dev/peps/pep-0333"><strong>PEP 333</strong></a> or WSGI for short is currently the best possible way to Python web programming. While it is great for programmers writing frameworks, the normal person does not need to get in direct contact with it. But when choosing a framework for web development it is a good idea to take one which supports WSGI.</p> <p>The big profit from WSGI is the unification. When your program is compatible with WSGI – that means that your framework has support for WSGI, your program can be deployed on every web server interface for which there are WSGI wrappers. So you do not need to care about whether the user uses mod_python or FastCGI – with WSGI it just works on any gateway interface. The Python standard library contains its own WSGI server <a title="WSGI Utilities and Reference Implementation." class="reference external" href="../library/wsgiref.html#module-wsgiref"><tt class="xref docutils literal"><span class="pre">wsgiref</span></tt></a>, which is a small web server that can be used for testing.</p> <p>A really great WSGI feature are the middlewares. Middlewares are layers around your program which can add various functionality to it. There is a <a class="reference external" href="http://wsgi.org/wsgi/Middleware_and_Utilities">number of middlewares</a> already available. For example, instead of writing your own session management (to identify a user in subsequent requests, as HTTP does not maintain state, so it does now know that the requests belong to the same user) you can just take one middleware, plug it in and you can rely an already existing functionality. The same thing is compression – say you want to compress your HTML using gzip, to save your server’s bandwidth. So you only need to plug-in a middleware and you’re done. Authentication is also a problem easily solved using a middleware.</p> <p>So, generally – although WSGI may seem complex, the initial phase of learning can be very rewarding as WSGI does already have solutions to many problems that might arise while writing web sites.</p> <div class="section" id="wsgi-servers"> <h3>WSGI Servers<a class="headerlink" href="#wsgi-servers" title="Permalink to this headline">¶</a></h3> <p>The code that is used to connect to various low level gateways like CGI or mod_python is called <em>WSGI server</em>. One of these servers is <tt class="docutils literal"><span class="pre">flup</span></tt> which was already mentioned and supports FastCGI, SCGI as well as <a class="reference external" href="http://en.wikipedia.org/wiki/Apache_JServ_Protocol">AJP</a>. Some of these servers are written in Python as <tt class="docutils literal"><span class="pre">flup</span></tt> is, but there also exist others which are written in C and can be used as drop-in replacements.</p> <p>There are quite a lot of servers already available, so a Python web application can be deployed nearly everywhere. This is one big advantage that Python has compared with other web techniques.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p>A good overview of all WSGI-related code can be found in the <a class="reference external" href="http://wsgi.org/wsgi">WSGI wiki</a>, which contains an extensive list of <a class="reference external" href="http://wsgi.org/wsgi/Servers">WSGI servers</a>, which can be used by <em>every</em> application supporting WSGI.</p> <p>You might be interested in some WSGI-supporting modules already contained in the standard library, namely:</p> <ul class="last simple"> <li><a title="WSGI Utilities and Reference Implementation." class="reference external" href="../library/wsgiref.html#module-wsgiref"><tt class="xref docutils literal"><span class="pre">wsgiref</span></tt></a> – some tiny utilities and servers for WSGI</li> </ul> </div> </div> <div class="section" id="case-study-moinmoin"> <h3>Case study: MoinMoin<a class="headerlink" href="#case-study-moinmoin" title="Permalink to this headline">¶</a></h3> <p>What does WSGI give the web application developer? Let’s take a look on one long existing web application written in Python without using WSGI.</p> <p>One of the most widely used wiki software is <a class="reference external" href="http://moinmo.in/">MoinMoin</a>. It was created in 2000, so it predates WSGI by about three years. While it now includes support for WSGI, older versions needed separate code to run on CGI, mod_python, FastCGI and standalone. Now, this all is possible by using WSGI and the already-written gateways. For running with on FastCGI <tt class="docutils literal"><span class="pre">flup</span></tt> can be used, for running a standalone server <a title="WSGI Utilities and Reference Implementation." class="reference external" href="../library/wsgiref.html#module-wsgiref"><tt class="xref docutils literal"><span class="pre">wsgiref</span></tt></a> is the way to go.</p> </div> </div> <div class="section" id="model-view-controller"> <h2>Model-view-controller<a class="headerlink" href="#model-view-controller" title="Permalink to this headline">¶</a></h2> <p>The term <em>MVC</em> is often heard in statements like “framework <em>foo</em> supports MVC”. While MVC is not really something technical but rather organisational, many web frameworks use this model to help the developer to bring structure into his program. Bigger web applications can have lots of code so it is a good idea to have structure in the program right from the beginnings. That way, even users of other frameworks (or even languages, as MVC is nothing Python-specific) can understand the existing code easier, as they are already familiar with the structure.</p> <p>MVC stands for three components:</p> <ul class="simple"> <li>The <em>model</em>. This is the data that is meant to modify. In Python frameworks this component is often represented by the classes used by the object-relational mapper. So, all declarations go here.</li> <li>The <em>view</em>. This component’s job is to display the data of the model to the user. Typically this component is represented by the templates.</li> <li>The <em>controller</em>. This is the layer between the user and the model. The controller reacts on user actions (like opening some specific URL) and tells the model to modify the data if necessary.</li> </ul> <p>While one might think that MVC is a complex design pattern, in fact it is not. It is used in Python because it has turned out to be useful for creating clean, maintainable web sites.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">While not all Python frameworks explicitly support MVC, it is often trivial to create a web site which uses the MVC pattern by separating the data logic (the model) from the user interaction logic (the controller) and the templates (the view). That’s why it is important not to write unnecessary Python code in the templates – it is against MVC and creates more chaos.</p> </div> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p class="last">The english Wikipedia has an article about the <a class="reference external" href="http://en.wikipedia.org/wiki/Model-view-controller">Model-View-Controller pattern</a>, which includes a long list of web frameworks for different programming languages.</p> </div> </div> <div class="section" id="ingredients-for-web-sites"> <h2>Ingredients for web sites<a class="headerlink" href="#ingredients-for-web-sites" title="Permalink to this headline">¶</a></h2> <p>Web sites are complex constructs, so tools were created to help the web site developer to make his work maintainable. None of these tools are in any way Python specific, they also exist for other programming languages as well. Of course, developers are not forced to use these tools and often there is no “best” tool, but it is worth informing yourself before choosing something because of the big number of helpers that the developer can use.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p class="last">People have written far more components that can be combined than these presented here. The Python wiki has a page about these components, called <a class="reference external" href="http://wiki.python.org/moin/WebComponents">Web Components</a>.</p> </div> <div class="section" id="templates"> <h3>Templates<a class="headerlink" href="#templates" title="Permalink to this headline">¶</a></h3> <p>Mixing of HTML and Python code is possible with some libraries. While convenient at first, it leads to horribly unmaintainable code. That’s why templates exist. Templates are, in the simplest case, just HTML files with placeholders. The HTML is sent to the user’s browser after filling out the placeholders.</p> <p>Python already includes such simple templates:</p> <div class="highlight-python3"><div class="highlight"><pre><span class="c"># a simple template</span> <span class="n">template</span> <span class="o">=</span> <span class="s">"<html><body><h1>Hello {who}!</h1></body></html>"</span> <span class="nb">print</span><span class="p">(</span><span class="n">template</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">who</span><span class="o">=</span><span class="s">"Reader"</span><span class="p">))</span> </pre></div> </div> <p>The Python standard library also includes some more advanced templates usable through <a title="string.Template" class="reference external" href="../library/string.html#string.Template"><tt class="xref docutils literal"><span class="pre">string.Template</span></tt></a>, but in HTML templates it is needed to use conditional and looping contructs like Python’s <em>for</em> and <em>if</em>. So, some <em>template engine</em> is needed.</p> <p>Now, Python has a lot of template engines which can be used with or without a <a class="reference internal" href="#framework">framework</a>. Some of these are using a plain-text programming language which is very easy to learn as it is quite limited while others use XML so the template output is always guaranteed to be valid XML. Some <a class="reference internal" href="#frameworks">frameworks</a> ship their own template engine or recommend one particular. If one is not yet sure, using these is a good idea.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p>While Python has quite a lot of different template engines it usually does not make sense to use a homebrewed template system. The time needed to evaluate all templating systems is not really worth it, better invest the time in looking through the most popular ones. Some frameworks have their own template engine or have a recommentation for one. It’s wise to use these.</p> <p>Popular template engines include:</p> <ul class="last simple"> <li>Mako</li> <li>Genshi</li> <li>Jinja</li> </ul> </div> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p class="last">Lots of different template engines divide the attention between themselves because it’s easy to create them in Python. The page <a class="reference external" href="http://wiki.python.org/moin/Templating">Templating</a> in the wiki lists a big, ever-growing number of these.</p> </div> </div> <div class="section" id="data-persistence"> <h3>Data persistence<a class="headerlink" href="#data-persistence" title="Permalink to this headline">¶</a></h3> <p><em>Data persistence</em>, while sounding very complicated is just about storing data. This data might be the text of blog entries, the postings of a bulletin board or the text of a wiki page. As always, there are different ways to store informations on a web server.</p> <p>Often relational database engines like <a class="reference external" href="http://www.mysql.com/">MySQL</a> or <a class="reference external" href="http://http://www.postgresql.org/">PostgreSQL</a> are used due to their good performance handling very large databases consisting of up to millions of entries. These are <em>queried</em> using a language called <a class="reference external" href="http://en.wikipedia.org/wiki/SQL">SQL</a>. Python programmers in general do not like SQL too much, they prefer to work with objects. It is possible to save Python objects into a database using a technology called <a class="reference external" href="http://en.wikipedia.org/wiki/Object-relational_mapping">ORM</a>. ORM translates all object-oriented access into SQL code under the hood, the user does not need to think about it. Most <a class="reference internal" href="#frameworks">frameworks</a> use ORMs and it works quite well.</p> <p>A second possibility is using files that are saved on the hard disk (sometimes called flatfiles). This is very easy, but is not too fast. There is even a small database engine called <a class="reference external" href="http://www.sqlite.org/">SQLite</a> which is bundled with Python in the <tt class="xref docutils literal"><span class="pre">sqlite</span></tt> module and uses only one file. This database can be used to store objects via an ORM and has no other dependencies. For smaller sites SQLite is just enough. But it is not the only way in which data can be saved into the file systems. Sometimes normal, plain text files are enough.</p> <p>The third and least used possibility are so-called object oriented databases. These databases store the <em>actual objects</em> instead of the relations that OR-mapping creates between rows in a database. This has the advantage that nearly all objects can be saven in a straightforward way, unlike in relational databases where some objects are very hard to represent with ORMs.</p> <p><a class="reference internal" href="#frameworks">Frameworks</a> often give the users hints on which method to choose, it is usually a good idea to stick to these unless there are some special requirements which require to use the one method and not the other.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <ul class="last simple"> <li><a class="reference external" href="http://wiki.python.org/moin/PersistenceTools">Persistence Tools</a> lists possibilities on how to save data in the file system, some of these modules are part of the standard library</li> <li><a class="reference external" href="http://wiki.python.org/moin/DatabaseProgramming">Database Programming</a> helps on choosing a method on how to save the data</li> <li><a class="reference external" href="http://www.sqlalchemy.org/">SQLAlchemy</a>, the most powerful OR-Mapper for Python and <a class="reference external" href="http://elixir.ematia.de/">Elixir</a> which makes it easier to use</li> <li><a class="reference external" href="http://www.sqlobject.org/">SQLObject</a>, another popular OR-Mapper</li> <li><a class="reference external" href="https://launchpad.net/zodb">ZODB</a> and <a class="reference external" href="http://www.mems-exchange.org/software/durus/">Durus</a>, two object oriented databases</li> </ul> </div> </div> </div> <div class="section" id="frameworks"> <span id="framework"></span><h2>Frameworks<a class="headerlink" href="#frameworks" title="Permalink to this headline">¶</a></h2> <p>As web sites can easily become quite large, there are so-called frameworks which were created to help the developer with making these sites. Although the most well-known framework is Ruby on Rails, Python does also have its own frameworks which are partly inspired by Rails or which were existing a long time before Rails.</p> <p>Two possible approaches to web frameworks exist: the minimalistic approach and the all-inclusive approach (somtimes called <em>full-stack</em>). Frameworks which are all-inclusive give you everything you need to start working, like a template engine, some way to save and access data in databases and many features more. Most users are best off using these as they are widely used by lots of other users and well documented in form of books and tutorials. Other web frameworks go the minimalistic approach trying to be as flexible as possible leaving the user the freedom to choose what’s best for him.</p> <p>The majority of users is best off with all-inclusive framewors. They bring everything along so a user can just jump in and start to code. While they do have some limitations they can fullfill 80% of what one will ever want to perfectly. They consist of various components which are designed to work together as good as possible.</p> <p>The multitude of web frameworks written in Python demonstrates that it is really easy to write one. One of the most well-known web applications written in Python is <a class="reference external" href="http://www.zope.org/">Zope</a> which can be regarded as some kind of big framework. But Zope was not the only framework, there were some others which are by now nearly forgotten. These do not need to be mentioned anymore, because most people that used them moved on to newer ones.</p> <div class="section" id="some-notable-frameworks"> <h3>Some notable frameworks<a class="headerlink" href="#some-notable-frameworks" title="Permalink to this headline">¶</a></h3> <p>There is an incredible number of frameworks, so there is no way to describe them all. It is not even necessary, as most of these frameworks are nothing special and everything that can be done with these can also be done with one of the popular ones.</p> <div class="section" id="django"> <h4>Django<a class="headerlink" href="#django" title="Permalink to this headline">¶</a></h4> <p><a class="reference external" href="http://www.djangoproject.com/">Django</a> is a framework consisting of several tightly coupled elements which were written from scratch and work together very well. It includes an ORM which is quite powerful while being simple to use and has a great online administration interface which makes it possible to edit the data in the database with a browser. The template engine is text-based and is designed to be usable for page designers who cannot write Python. It supports so-called template inheritance and filters (which work like Unix pipes). Django has many handy features bundled, like creation of RSS feeds or generic views which make it possible to write web sites nearly without any Python code.</p> <p>It has a big, international community which has created many sites using Django. There are also quite a lot of add-on projects which extend Django’s normal functionality. This is partly due to Django’s well written <a class="reference external" href="http://doc.djangoproject.com/">online documentation</a> and the <a class="reference external" href="http://www.djangobook.com/">Django book</a>.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">Although Django is an MVC-style framework, it calls the components differently, which is described in the <a class="reference external" href="http://www.djangoproject.com/documentation/faq/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names">Django FAQ</a>.</p> </div> </div> <div class="section" id="turbogears"> <h4>TurboGears<a class="headerlink" href="#turbogears" title="Permalink to this headline">¶</a></h4> <p>The other popular web framework in Python is <a class="reference external" href="http://www.turbogears.org/">TurboGears</a>. It takes the approach of using already existing components and combining them with glue code to create a seamless experience. TurboGears gives the user more flexibility on which components to choose, the ORM can be switched between some easy to use but limited and complex but very powerful. Same goes for the template engine. One strong point about TurboGears is that the components that it consists of can be used easily in other projects without depending on TurboGears, for example the underlying web server CherryPy.</p> <p>The documentation can be found in the <a class="reference external" href="http://docs.turbogears.org/">TurboGears wiki</a>, where links to screencasts can be found. TurboGears has also an active user community which can respond to most related questions. There is also a <a class="reference external" href="http://turbogearsbook.com/">TurboGears book</a> published, which is a good starting point.</p> <p>The plan for the next major version of TurboGears, version 2.0 is to switch to a more flexible base provided by another very flexible web framework called <a class="reference external" href="http://pylonshq.com/">Pylons</a>.</p> </div> <div class="section" id="other-notable-frameworks"> <h4>Other notable frameworks<a class="headerlink" href="#other-notable-frameworks" title="Permalink to this headline">¶</a></h4> <p>These two are of course not the only frameworks that are available, there are also some less-popular frameworks worth mentioning.</p> <p>One of these is the already mentioned Zope, which has been around for quite a long time. With Zope 2.x having been known as rather un-pythonic, the newer Zope 3.x tries to change that and therefore gets more acceptance from Python programmers. These efforts already showed results, there is a project which connects Zope with WSGI called <a class="reference external" href="http://repoze.org/">Repoze</a> and another project called <a class="reference external" href="http://grok.zope.org/">Grok</a> which makes it possible for “normal” Python programmers use the very mature Zope components.</p> <p>Another framework that’s already been mentioned is <a class="reference external" href="http://pylonshq.com/">Pylons</a>. Pylons is much like TurboGears with ab even stronger emphasis on flexibility, which is bought at the cost of being more difficult to use. Nearly every component can be exchanged, which makes it necessary to use the documentation of every single component, because there are so many Pylons combinations possible that can satisfy every requirement. Pylons builds upon <a class="reference external" href="http://pythonpaste.org/">Paste</a>, an extensive set of tools which are handy for WSGI.</p> <p>And that’s still not everything. The most up-to-date information can always be found in the Python wiki.</p> <div class="admonition-see-also admonition seealso"> <p class="first admonition-title">See also</p> <p>The Python wiki contains an extensive list of <a class="reference external" href="http://wiki.python.org/moin/WebFrameworks">web frameworks</a>.</p> <p class="last">Most frameworks also have their own mailing lists and IRC channels, look out for these on the projects’ websites. There is also a general “Python in the Web” IRC channel on freenode called <a class="reference external" href="http://wiki.python.org/moin/PoundPythonWeb">#python.web</a>.</p> </div> </div> </div> </div> </div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference external" href="">HOWTO Use Python in the web</a><ul> <li><a class="reference external" href="#the-low-level-view">The low-level view</a><ul> <li><a class="reference external" href="#common-gateway-interface">Common Gateway Interface</a><ul> <li><a class="reference external" href="#simple-script-for-testing-cgi">Simple script for testing CGI</a></li> <li><a class="reference external" href="#setting-up-cgi-on-your-own-server">Setting up CGI on your own server</a></li> <li><a class="reference external" href="#common-problems-with-cgi-scripts">Common problems with CGI scripts</a></li> </ul> </li> <li><a class="reference external" href="#mod-python">mod_python</a></li> <li><a class="reference external" href="#fastcgi-and-scgi">FastCGI and SCGI</a><ul> <li><a class="reference external" href="#setting-up-fastcgi">Setting up FastCGI</a></li> </ul> </li> <li><a class="reference external" href="#mod-wsgi">mod_wsgi</a></li> </ul> </li> <li><a class="reference external" href="#step-back-wsgi">Step back: WSGI</a><ul> <li><a class="reference external" href="#wsgi-servers">WSGI Servers</a></li> <li><a class="reference external" href="#case-study-moinmoin">Case study: MoinMoin</a></li> </ul> </li> <li><a class="reference external" href="#model-view-controller">Model-view-controller</a></li> <li><a class="reference external" href="#ingredients-for-web-sites">Ingredients for web sites</a><ul> <li><a class="reference external" href="#templates">Templates</a></li> <li><a class="reference external" href="#data-persistence">Data persistence</a></li> </ul> </li> <li><a class="reference external" href="#frameworks">Frameworks</a><ul> <li><a class="reference external" href="#some-notable-frameworks">Some notable frameworks</a><ul> <li><a class="reference external" href="#django">Django</a></li> <li><a class="reference external" href="#turbogears">TurboGears</a></li> <li><a class="reference external" href="#other-notable-frameworks">Other notable frameworks</a></li> </ul> </li> </ul> </li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="urllib2.html" title="previous chapter">HOWTO Fetch Internet Resources Using The urllib Package</a></p> <h4>Next topic</h4> <p class="topless"><a href="../glossary.html" title="next chapter">Glossary</a></p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../_sources/howto/webservers.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" size="18" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="../modindex.html" title="Global Module Index" >modules</a> |</li> <li class="right" > <a href="../glossary.html" title="Glossary" >next</a> |</li> <li class="right" > <a href="urllib2.html" title="HOWTO Fetch Internet Resources Using The urllib Package" >previous</a> |</li> <li><img src="../_static/py.png" alt="" style="vertical-align: middle; margin-top: -1px"/></li> <li><a href="../index.html">Python v3.1.1 documentation</a> »</li> <li><a href="index.html" >Python HOWTOs</a> »</li> </ul> </div> <div class="footer"> © <a href="../copyright.html">Copyright</a> 1990-2009, Python Software Foundation. <br /> The Python Software Foundation is a non-profit corporation. <a href="http://www.python.org/psf/donations/">Please donate.</a> <br /> Last updated on Aug 16, 2009. Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.2. </div> </body> </html>