Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 1 | ******************************* |
| 2 | HOWTO Use Python in the web |
| 3 | ******************************* |
| 4 | |
| 5 | :Author: Marek Kubica |
| 6 | |
| 7 | .. topic:: Abstract |
| 8 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 9 | This document shows how Python fits into the web. It presents some ways |
| 10 | to integrate Python with a web server, and general practices useful for |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 11 | developing web sites. |
| 12 | |
| 13 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 14 | Programming for the Web has become a hot topic since the rise of "Web 2.0", |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 15 | which focuses on user-generated content on web sites. It has always been |
| 16 | possible to use Python for creating web sites, but it was a rather tedious task. |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 17 | Therefore, many frameworks and helper tools have been created to assist |
| 18 | developers in creating faster and more robust sites. This HOWTO describes |
| 19 | some of the methods used to combine Python with a web server to create |
| 20 | dynamic content. It is not meant as a complete introduction, as this topic is |
| 21 | far too broad to be covered in one single document. However, a short overview |
| 22 | of the most popular libraries is provided. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 23 | |
| 24 | .. seealso:: |
| 25 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 26 | While this HOWTO tries to give an overview of Python in the web, it cannot |
| 27 | always be as up to date as desired. Web development in Python is rapidly |
| 28 | moving forward, so the wiki page on `Web Programming |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 29 | <https://wiki.python.org/moin/WebProgramming>`_ may be more in sync with |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 30 | recent development. |
| 31 | |
| 32 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 33 | The Low-Level View |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 34 | ================== |
| 35 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 36 | When a user enters a web site, their browser makes a connection to the site's |
| 37 | web server (this is called the *request*). The server looks up the file in the |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 38 | file system and sends it back to the user's browser, which displays it (this is |
Ezio Melotti | d72a628 | 2010-03-23 23:26:21 +0000 | [diff] [blame] | 39 | the *response*). This is roughly how the underlying protocol, HTTP, works. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 40 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 41 | Dynamic web sites are not based on files in the file system, but rather on |
| 42 | programs which are run by the web server when a request comes in, and which |
| 43 | *generate* the content that is returned to the user. They can do all sorts of |
| 44 | useful things, like display the postings of a bulletin board, show your email, |
| 45 | configure software, or just display the current time. These programs can be |
| 46 | written in any programming language the server supports. Since most servers |
| 47 | support Python, it is easy to use Python to create dynamic web sites. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 48 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 49 | Most HTTP servers are written in C or C++, so they cannot execute Python code |
| 50 | directly -- a bridge is needed between the server and the program. These |
| 51 | bridges, or rather interfaces, define how programs interact with the server. |
| 52 | There have been numerous attempts to create the best possible interface, but |
| 53 | there are only a few worth mentioning. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 54 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 55 | Not every web server supports every interface. Many web servers only support |
| 56 | old, now-obsolete interfaces; however, they can often be extended using |
| 57 | third-party modules to support newer ones. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 58 | |
| 59 | |
| 60 | Common Gateway Interface |
| 61 | ------------------------ |
| 62 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 63 | This interface, most commonly referred to as "CGI", is the oldest, and is |
| 64 | supported by nearly every web server out of the box. Programs using CGI to |
| 65 | communicate with their web server need to be started by the server for every |
| 66 | request. So, every request starts a new Python interpreter -- which takes some |
| 67 | time to start up -- thus making the whole interface only usable for low load |
| 68 | situations. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 69 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 70 | The upside of CGI is that it is simple -- writing a Python program which uses |
| 71 | CGI is a matter of about three lines of code. This simplicity comes at a |
| 72 | price: it does very few things to help the developer. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 73 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 74 | Writing CGI programs, while still possible, is no longer recommended. With |
| 75 | :ref:`WSGI <WSGI>`, a topic covered later in this document, it is possible to write |
| 76 | programs that emulate CGI, so they can be run as CGI if no better option is |
| 77 | available. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 78 | |
| 79 | .. seealso:: |
| 80 | |
| 81 | The Python standard library includes some modules that are helpful for |
| 82 | creating plain CGI programs: |
| 83 | |
| 84 | * :mod:`cgi` -- Handling of user input in CGI scripts |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 85 | * :mod:`cgitb` -- Displays nice tracebacks when errors happen in CGI |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 86 | applications, instead of presenting a "500 Internal Server Error" message |
| 87 | |
| 88 | The Python wiki features a page on `CGI scripts |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 89 | <https://wiki.python.org/moin/CgiScripts>`_ with some additional information |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 90 | about CGI in Python. |
| 91 | |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 92 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 93 | Simple script for testing CGI |
| 94 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 95 | |
| 96 | To test whether your web server works with CGI, you can use this short and |
| 97 | simple CGI program:: |
| 98 | |
| 99 | #!/usr/bin/env python |
| 100 | # -*- coding: UTF-8 -*- |
| 101 | |
| 102 | # enable debugging |
Georg Brandl | 6b5dbaa | 2009-02-20 08:22:21 +0000 | [diff] [blame] | 103 | import cgitb |
| 104 | cgitb.enable() |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 105 | |
| 106 | print "Content-Type: text/plain;charset=utf-8" |
| 107 | print |
| 108 | |
| 109 | print "Hello World!" |
| 110 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 111 | Depending on your web server configuration, you may need to save this code with |
| 112 | a ``.py`` or ``.cgi`` extension. Additionally, this file may also need to be |
| 113 | in a ``cgi-bin`` folder, for security reasons. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 114 | |
| 115 | You might wonder what the ``cgitb`` line is about. This line makes it possible |
| 116 | to display a nice traceback instead of just crashing and displaying an "Internal |
| 117 | Server Error" in the user's browser. This is useful for debugging, but it might |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 118 | risk exposing some confidential data to the user. You should not use ``cgitb`` |
| 119 | in production code for this reason. You should *always* catch exceptions, and |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 120 | display proper error pages -- end-users don't like to see nondescript "Internal |
| 121 | Server Errors" in their browsers. |
| 122 | |
| 123 | |
| 124 | Setting up CGI on your own server |
| 125 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 126 | |
| 127 | If you don't have your own web server, this does not apply to you. You can |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 128 | check whether it works as-is, and if not you will need to talk to the |
| 129 | administrator of your web server. If it is a big host, you can try filing a |
| 130 | ticket asking for Python support. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 131 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 132 | If you are your own administrator or want to set up CGI for testing purposes on |
| 133 | your own computers, you have to configure it by yourself. There is no single |
| 134 | way to configure CGI, as there are many web servers with different |
| 135 | configuration options. Currently the most widely used free web server is |
| 136 | `Apache HTTPd <http://httpd.apache.org/>`_, or Apache for short. Apache can be |
| 137 | easily installed on nearly every system using the system's package management |
| 138 | tool. `lighttpd <http://www.lighttpd.net>`_ is another alternative and is |
| 139 | said to have better performance. On many systems this server can also be |
| 140 | installed using the package management tool, so manually compiling the web |
| 141 | server may not be needed. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 142 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 143 | * On Apache you can take a look at the `Dynamic Content with CGI |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 144 | <http://httpd.apache.org/docs/2.2/howto/cgi.html>`_ tutorial, where everything |
| 145 | is described. Most of the time it is enough just to set ``+ExecCGI``. The |
| 146 | tutorial also describes the most common gotchas that might arise. |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 147 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 148 | * On lighttpd you need to use the `CGI module |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 149 | <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModCGI>`_\ , which can be configured |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 150 | in a straightforward way. It boils down to setting ``cgi.assign`` properly. |
| 151 | |
| 152 | |
| 153 | Common problems with CGI scripts |
| 154 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 155 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 156 | Using CGI sometimes leads to small annoyances while trying to get these |
| 157 | scripts to run. Sometimes a seemingly correct script does not work as |
| 158 | expected, the cause being some small hidden problem that's difficult to spot. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 159 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 160 | Some of these potential problems are: |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 161 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 162 | * The Python script is not marked as executable. When CGI scripts are not |
| 163 | executable most web servers will let the user download it, instead of |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 164 | running it and sending the output to the user. For CGI scripts to run |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 165 | properly on Unix-like operating systems, the ``+x`` bit needs to be set. |
| 166 | Using ``chmod a+x your_script.py`` may solve this problem. |
| 167 | |
| 168 | * On a Unix-like system, The line endings in the program file must be Unix |
| 169 | style line endings. This is important because the web server checks the |
| 170 | first line of the script (called shebang) and tries to run the program |
| 171 | specified there. It gets easily confused by Windows line endings (Carriage |
| 172 | Return & Line Feed, also called CRLF), so you have to convert the file to |
| 173 | Unix line endings (only Line Feed, LF). This can be done automatically by |
| 174 | uploading the file via FTP in text mode instead of binary mode, but the |
| 175 | preferred way is just telling your editor to save the files with Unix line |
| 176 | endings. Most editors support this. |
| 177 | |
| 178 | * Your web server must be able to read the file, and you need to make sure the |
| 179 | permissions are correct. On unix-like systems, the server often runs as user |
| 180 | and group ``www-data``, so it might be worth a try to change the file |
| 181 | ownership, or making the file world readable by using ``chmod a+r |
| 182 | your_script.py``. |
| 183 | |
| 184 | * The web server must know that the file you're trying to access is a CGI script. |
| 185 | Check the configuration of your web server, as it may be configured |
| 186 | to expect a specific file extension for CGI scripts. |
| 187 | |
| 188 | * On Unix-like systems, the path to the interpreter in the shebang |
| 189 | (``#!/usr/bin/env python``) must be correct. This line calls |
| 190 | ``/usr/bin/env`` to find Python, but it will fail if there is no |
| 191 | ``/usr/bin/env``, or if Python is not in the web server's path. If you know |
| 192 | where your Python is installed, you can also use that full path. The |
| 193 | commands ``whereis python`` and ``type -p python`` could help you find |
| 194 | where it is installed. Once you know the path, you can change the shebang |
| 195 | accordingly: ``#!/usr/bin/python``. |
| 196 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 197 | * The file must not contain a BOM (Byte Order Mark). The BOM is meant for |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 198 | determining the byte order of UTF-16 and UTF-32 encodings, but some editors |
| 199 | write this also into UTF-8 files. The BOM interferes with the shebang line, |
| 200 | so be sure to tell your editor not to write the BOM. |
| 201 | |
| 202 | * If the web server is using :ref:`mod-python`, ``mod_python`` may be having |
| 203 | problems. ``mod_python`` is able to handle CGI scripts by itself, but it can |
| 204 | also be a source of issues. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 205 | |
| 206 | |
| 207 | .. _mod-python: |
| 208 | |
| 209 | mod_python |
| 210 | ---------- |
| 211 | |
| 212 | People coming from PHP often find it hard to grasp how to use Python in the web. |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 213 | Their first thought is mostly `mod_python <http://modpython.org/>`_\ , |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 214 | because they think that this is the equivalent to ``mod_php``. Actually, there |
| 215 | are many differences. What ``mod_python`` does is embed the interpreter into |
| 216 | the Apache process, thus speeding up requests by not having to start a Python |
| 217 | interpreter for each request. On the other hand, it is not "Python intermixed |
| 218 | with HTML" in the way that PHP is often intermixed with HTML. The Python |
| 219 | equivalent of that is a template engine. ``mod_python`` itself is much more |
| 220 | powerful and provides more access to Apache internals. It can emulate CGI, |
| 221 | work in a "Python Server Pages" mode (similar to JSP) which is "HTML |
| 222 | intermingled with Python", and it has a "Publisher" which designates one file |
| 223 | to accept all requests and decide what to do with them. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 224 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 225 | ``mod_python`` does have some problems. Unlike the PHP interpreter, the Python |
| 226 | interpreter uses caching when executing files, so changes to a file will |
| 227 | require the web server to be restarted. Another problem is the basic concept |
| 228 | -- Apache starts child processes to handle the requests, and unfortunately |
| 229 | every child process needs to load the whole Python interpreter even if it does |
| 230 | not use it. This makes the whole web server slower. Another problem is that, |
| 231 | because ``mod_python`` is linked against a specific version of ``libpython``, |
| 232 | it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) |
| 233 | without recompiling ``mod_python``. ``mod_python`` is also bound to the Apache |
| 234 | web server, so programs written for ``mod_python`` cannot easily run on other |
| 235 | web servers. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 236 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 237 | These are the reasons why ``mod_python`` should be avoided when writing new |
| 238 | programs. In some circumstances it still might be a good idea to use |
| 239 | ``mod_python`` for deployment, but WSGI makes it possible to run WSGI programs |
| 240 | under ``mod_python`` as well. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 241 | |
| 242 | |
| 243 | FastCGI and SCGI |
| 244 | ---------------- |
| 245 | |
| 246 | FastCGI and SCGI try to solve the performance problem of CGI in another way. |
| 247 | Instead of embedding the interpreter into the web server, they create |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 248 | long-running background processes. There is still a module in the web server |
| 249 | which makes it possible for the web server to "speak" with the background |
| 250 | process. As the background process is independent of the server, it can be |
| 251 | written in any language, including Python. The language just needs to have a |
| 252 | library which handles the communication with the webserver. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 253 | |
| 254 | The difference between FastCGI and SCGI is very small, as SCGI is essentially |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 255 | just a "simpler FastCGI". As the web server support for SCGI is limited, |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 256 | most people use FastCGI instead, which works the same way. Almost everything |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 257 | that applies to SCGI also applies to FastCGI as well, so we'll only cover |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 258 | the latter. |
| 259 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 260 | These days, FastCGI is never used directly. Just like ``mod_python``, it is only |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 261 | used for the deployment of WSGI applications. |
| 262 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 263 | |
| 264 | Setting up FastCGI |
| 265 | ^^^^^^^^^^^^^^^^^^ |
| 266 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 267 | Each web server requires a specific module. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 268 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 269 | * Apache has both `mod_fastcgi <http://www.fastcgi.com/drupal/>`_ and `mod_fcgid |
Sandro Tosi | 117e1f0 | 2011-12-31 18:13:59 +0100 | [diff] [blame] | 270 | <http://httpd.apache.org/mod_fcgid/>`_. ``mod_fastcgi`` is the original one, but it |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 271 | has some licensing issues, which is why it is sometimes considered non-free. |
| 272 | ``mod_fcgid`` is a smaller, compatible alternative. One of these modules needs |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 273 | to be loaded by Apache. |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 274 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 275 | * lighttpd ships its own `FastCGI module |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 276 | <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI>`_ as well as an |
| 277 | `SCGI module <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSCGI>`_. |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 278 | |
| 279 | * `nginx <http://nginx.org/>`_ also supports `FastCGI |
| 280 | <http://wiki.nginx.org/NginxSimplePythonFCGI>`_. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 281 | |
| 282 | Once you have installed and configured the module, you can test it with the |
| 283 | following WSGI-application:: |
| 284 | |
| 285 | #!/usr/bin/env python |
| 286 | # -*- coding: UTF-8 -*- |
| 287 | |
| 288 | from cgi import escape |
Benjamin Peterson | a7b55a3 | 2009-02-20 03:31:23 +0000 | [diff] [blame] | 289 | import sys, os |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 290 | from flup.server.fcgi import WSGIServer |
| 291 | |
| 292 | def app(environ, start_response): |
| 293 | start_response('200 OK', [('Content-Type', 'text/html')]) |
| 294 | |
| 295 | yield '<h1>FastCGI Environment</h1>' |
| 296 | yield '<table>' |
| 297 | for k, v in sorted(environ.items()): |
| 298 | yield '<tr><th>%s</th><td>%s</td></tr>' % (escape(k), escape(v)) |
| 299 | yield '</table>' |
| 300 | |
| 301 | WSGIServer(app).run() |
| 302 | |
| 303 | This is a simple WSGI application, but you need to install `flup |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 304 | <https://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 305 | FastCGI access. |
| 306 | |
| 307 | .. seealso:: |
| 308 | |
| 309 | There is some documentation on `setting up Django with FastCGI |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 310 | <https://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 311 | which can be reused for other WSGI-compliant frameworks and libraries. |
| 312 | Only the ``manage.py`` part has to be changed, the example used here can be |
| 313 | used instead. Django does more or less the exact same thing. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 314 | |
| 315 | |
| 316 | mod_wsgi |
| 317 | -------- |
| 318 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 319 | `mod_wsgi <http://code.google.com/p/modwsgi/>`_ is an attempt to get rid of the |
| 320 | low level gateways. Given that FastCGI, SCGI, and mod_python are mostly used to |
| 321 | deploy WSGI applications, mod_wsgi was started to directly embed WSGI applications |
| 322 | into the Apache web server. mod_wsgi is specifically designed to host WSGI |
| 323 | applications. It makes the deployment of WSGI applications much easier than |
| 324 | deployment using other low level methods, which need glue code. The downside |
| 325 | is that mod_wsgi is limited to the Apache web server; other servers would need |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 326 | their own implementations of mod_wsgi. |
| 327 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 328 | mod_wsgi supports two modes: embedded mode, in which it integrates with the |
| 329 | Apache process, and daemon mode, which is more FastCGI-like. Unlike FastCGI, |
| 330 | mod_wsgi handles the worker-processes by itself, which makes administration |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 331 | easier. |
| 332 | |
| 333 | |
| 334 | .. _WSGI: |
| 335 | |
| 336 | Step back: WSGI |
| 337 | =============== |
| 338 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 339 | WSGI has already been mentioned several times, so it has to be something |
| 340 | important. In fact it really is, and now it is time to explain it. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 341 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 342 | The *Web Server Gateway Interface*, or WSGI for short, is defined in |
| 343 | :pep:`333` and is currently the best way to do Python web programming. While |
| 344 | it is great for programmers writing frameworks, a normal web developer does not |
| 345 | need to get in direct contact with it. When choosing a framework for web |
| 346 | development it is a good idea to choose one which supports WSGI. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 347 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 348 | The big benefit of WSGI is the unification of the application programming |
| 349 | interface. When your program is compatible with WSGI -- which at the outer |
| 350 | level means that the framework you are using has support for WSGI -- your |
| 351 | program can be deployed via any web server interface for which there are WSGI |
| 352 | wrappers. You do not need to care about whether the application user uses |
| 353 | mod_python or FastCGI or mod_wsgi -- with WSGI your application will work on |
| 354 | any gateway interface. The Python standard library contains its own WSGI |
| 355 | server, :mod:`wsgiref`, which is a small web server that can be used for |
| 356 | testing. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 357 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 358 | A really great WSGI feature is middleware. Middleware is a layer around your |
| 359 | program which can add various functionality to it. There is quite a bit of |
Sandro Tosi | 117e1f0 | 2011-12-31 18:13:59 +0100 | [diff] [blame] | 360 | `middleware <http://www.wsgi.org/en/latest/libraries.html>`_ already |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 361 | available. For example, instead of writing your own session management (HTTP |
| 362 | is a stateless protocol, so to associate multiple HTTP requests with a single |
| 363 | user your application must create and manage such state via a session), you can |
| 364 | just download middleware which does that, plug it in, and get on with coding |
| 365 | the unique parts of your application. The same thing with compression -- there |
| 366 | is existing middleware which handles compressing your HTML using gzip to save |
| 367 | on your server's bandwidth. Authentication is another a problem easily solved |
| 368 | using existing middleware. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 369 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 370 | Although WSGI may seem complex, the initial phase of learning can be very |
| 371 | rewarding because WSGI and the associated middleware already have solutions to |
| 372 | many problems that might arise while developing web sites. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 373 | |
| 374 | |
| 375 | WSGI Servers |
| 376 | ------------ |
| 377 | |
| 378 | The code that is used to connect to various low level gateways like CGI or |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 379 | mod_python is called a *WSGI server*. One of these servers is ``flup``, which |
| 380 | supports FastCGI and SCGI, as well as `AJP |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 381 | <http://en.wikipedia.org/wiki/Apache_JServ_Protocol>`_. Some of these servers |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 382 | are written in Python, as ``flup`` is, but there also exist others which are |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 383 | written in C and can be used as drop-in replacements. |
| 384 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 385 | There are many servers already available, so a Python web application |
| 386 | can be deployed nearly anywhere. This is one big advantage that Python has |
| 387 | compared with other web technologies. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 388 | |
| 389 | .. seealso:: |
| 390 | |
Sandro Tosi | 117e1f0 | 2011-12-31 18:13:59 +0100 | [diff] [blame] | 391 | A good overview of WSGI-related code can be found in the `WSGI homepage |
| 392 | <http://www.wsgi.org/en/latest/index.html>`_, which contains an extensive list of `WSGI servers |
| 393 | <http://www.wsgi.org/en/latest/servers.html>`_ which can be used by *any* application |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 394 | supporting WSGI. |
| 395 | |
| 396 | You might be interested in some WSGI-supporting modules already contained in |
| 397 | the standard library, namely: |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 398 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 399 | * :mod:`wsgiref` -- some tiny utilities and servers for WSGI |
| 400 | |
| 401 | |
| 402 | Case study: MoinMoin |
| 403 | -------------------- |
| 404 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 405 | What does WSGI give the web application developer? Let's take a look at |
| 406 | an application that's been around for a while, which was written in |
| 407 | Python without using WSGI. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 408 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 409 | One of the most widely used wiki software packages is `MoinMoin |
| 410 | <http://moinmo.in/>`_. It was created in 2000, so it predates WSGI by about |
| 411 | three years. Older versions needed separate code to run on CGI, mod_python, |
| 412 | FastCGI and standalone. |
| 413 | |
| 414 | It now includes support for WSGI. Using WSGI, it is possible to deploy |
| 415 | MoinMoin on any WSGI compliant server, with no additional glue code. |
| 416 | Unlike the pre-WSGI versions, this could include WSGI servers that the |
| 417 | authors of MoinMoin know nothing about. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 418 | |
| 419 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 420 | Model-View-Controller |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 421 | ===================== |
| 422 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 423 | The term *MVC* is often encountered in statements such as "framework *foo* |
| 424 | supports MVC". MVC is more about the overall organization of code, rather than |
| 425 | any particular API. Many web frameworks use this model to help the developer |
| 426 | bring structure to their program. Bigger web applications can have lots of |
| 427 | code, so it is a good idea to have an effective structure right from the beginning. |
| 428 | That way, even users of other frameworks (or even other languages, since MVC is |
| 429 | not Python-specific) can easily understand the code, given that they are |
| 430 | already familiar with the MVC structure. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 431 | |
| 432 | MVC stands for three components: |
| 433 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 434 | * The *model*. This is the data that will be displayed and modified. In |
| 435 | Python frameworks, this component is often represented by the classes used by |
| 436 | an object-relational mapper. |
| 437 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 438 | * The *view*. This component's job is to display the data of the model to the |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 439 | user. Typically this component is implemented via templates. |
| 440 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 441 | * The *controller*. This is the layer between the user and the model. The |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 442 | controller reacts to user actions (like opening some specific URL), tells |
| 443 | the model to modify the data if necessary, and tells the view code what to |
| 444 | display, |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 445 | |
| 446 | While one might think that MVC is a complex design pattern, in fact it is not. |
| 447 | It is used in Python because it has turned out to be useful for creating clean, |
| 448 | maintainable web sites. |
| 449 | |
| 450 | .. note:: |
| 451 | |
| 452 | While not all Python frameworks explicitly support MVC, it is often trivial |
Mark Dickinson | 3e4caeb | 2009-02-21 20:27:01 +0000 | [diff] [blame] | 453 | to create a web site which uses the MVC pattern by separating the data logic |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 454 | (the model) from the user interaction logic (the controller) and the |
Mark Dickinson | 3e4caeb | 2009-02-21 20:27:01 +0000 | [diff] [blame] | 455 | templates (the view). That's why it is important not to write unnecessary |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 456 | Python code in the templates -- it works against the MVC model and creates |
| 457 | chaos in the code base, making it harder to understand and modify. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 458 | |
| 459 | .. seealso:: |
| 460 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 461 | The English Wikipedia has an article about the `Model-View-Controller pattern |
| 462 | <http://en.wikipedia.org/wiki/Model-view-controller>`_. It includes a long |
| 463 | list of web frameworks for various programming languages. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 464 | |
| 465 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 466 | Ingredients for Websites |
| 467 | ======================== |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 468 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 469 | Websites are complex constructs, so tools have been created to help web |
| 470 | developers make their code easier to write and more maintainable. Tools like |
| 471 | these exist for all web frameworks in all languages. Developers are not forced |
| 472 | to use these tools, and often there is no "best" tool. It is worth learning |
| 473 | about the available tools because they can greatly simplify the process of |
| 474 | developing a web site. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 475 | |
| 476 | |
| 477 | .. seealso:: |
| 478 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 479 | There are far more components than can be presented here. The Python wiki |
| 480 | has a page about these components, called |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 481 | `Web Components <https://wiki.python.org/moin/WebComponents>`_. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 482 | |
| 483 | |
| 484 | Templates |
| 485 | --------- |
| 486 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 487 | Mixing of HTML and Python code is made possible by a few libraries. While |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 488 | convenient at first, it leads to horribly unmaintainable code. That's why |
| 489 | templates exist. Templates are, in the simplest case, just HTML files with |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 490 | placeholders. The HTML is sent to the user's browser after filling in the |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 491 | placeholders. |
| 492 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 493 | Python already includes two ways to build simple templates:: |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 494 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 495 | >>> template = "<html><body><h1>Hello %s!</h1></body></html>" |
| 496 | >>> print template % "Reader" |
| 497 | <html><body><h1>Hello Reader!</h1></body></html> |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 498 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 499 | >>> from string import Template |
| 500 | >>> template = Template("<html><body><h1>Hello ${name}</h1></body></html>") |
| 501 | >>> print template.substitute(dict(name='Dinsdale')) |
| 502 | <html><body><h1>Hello Dinsdale!</h1></body></html> |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 503 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 504 | To generate complex HTML based on non-trivial model data, conditional |
| 505 | and looping constructs like Python's *for* and *if* are generally needed. |
| 506 | *Template engines* support templates of this complexity. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 507 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 508 | There are a lot of template engines available for Python which can be used with |
| 509 | or without a `framework`_. Some of these define a plain-text programming |
| 510 | language which is easy to learn, partly because it is limited in scope. |
| 511 | Others use XML, and the template output is guaranteed to be always be valid |
| 512 | XML. There are many other variations. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 513 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 514 | Some `frameworks`_ ship their own template engine or recommend one in |
| 515 | particular. In the absence of a reason to use a different template engine, |
| 516 | using the one provided by or recommended by the framework is a good idea. |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 517 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 518 | Popular template engines include: |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 519 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 520 | * `Mako <http://www.makotemplates.org/>`_ |
| 521 | * `Genshi <http://genshi.edgewall.org/>`_ |
Georg Brandl | 0f5d6c0 | 2014-10-29 10:57:37 +0100 | [diff] [blame] | 522 | * `Jinja <http://jinja.pocoo.org/>`_ |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 523 | |
| 524 | .. seealso:: |
| 525 | |
Ezio Melotti | 056f33d | 2010-11-16 21:08:14 +0000 | [diff] [blame] | 526 | There are many template engines competing for attention, because it is |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 527 | pretty easy to create them in Python. The page `Templating |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 528 | <https://wiki.python.org/moin/Templating>`_ in the wiki lists a big, |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 529 | ever-growing number of these. The three listed above are considered "second |
| 530 | generation" template engines and are a good place to start. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 531 | |
| 532 | |
| 533 | Data persistence |
| 534 | ---------------- |
| 535 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 536 | *Data persistence*, while sounding very complicated, is just about storing data. |
| 537 | This data might be the text of blog entries, the postings on a bulletin board or |
| 538 | the text of a wiki page. There are, of course, a number of different ways to store |
| 539 | information on a web server. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 540 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 541 | Often, relational database engines like `MySQL <http://www.mysql.com/>`_ or |
| 542 | `PostgreSQL <http://www.postgresql.org/>`_ are used because of their good |
| 543 | performance when handling very large databases consisting of millions of |
| 544 | entries. There is also a small database engine called `SQLite |
| 545 | <http://www.sqlite.org/>`_, which is bundled with Python in the :mod:`sqlite3` |
| 546 | module, and which uses only one file. It has no other dependencies. For |
| 547 | smaller sites SQLite is just enough. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 548 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 549 | Relational databases are *queried* using a language called `SQL |
| 550 | <http://en.wikipedia.org/wiki/SQL>`_. Python programmers in general do not |
| 551 | like SQL too much, as they prefer to work with objects. It is possible to save |
| 552 | Python objects into a database using a technology called `ORM |
| 553 | <http://en.wikipedia.org/wiki/Object-relational_mapping>`_ (Object Relational |
| 554 | Mapping). ORM translates all object-oriented access into SQL code under the |
| 555 | hood, so the developer does not need to think about it. Most `frameworks`_ use |
| 556 | ORMs, and it works quite well. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 557 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 558 | A second possibility is storing data in normal, plain text files (some |
| 559 | times called "flat files"). This is very easy for simple sites, |
| 560 | but can be difficult to get right if the web site is performing many |
| 561 | updates to the stored data. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 562 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 563 | A third possibility are object oriented databases (also called "object |
| 564 | databases"). These databases store the object data in a form that closely |
| 565 | parallels the way the objects are structured in memory during program |
| 566 | execution. (By contrast, ORMs store the object data as rows of data in tables |
| 567 | and relations between those rows.) Storing the objects directly has the |
| 568 | advantage that nearly all objects can be saved in a straightforward way, unlike |
| 569 | in relational databases where some objects are very hard to represent. |
| 570 | |
| 571 | `Frameworks`_ often give hints on which data storage method to choose. It is |
| 572 | usually a good idea to stick to the data store recommended by the framework |
| 573 | unless the application has special requirements better satisfied by an |
| 574 | alternate storage mechanism. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 575 | |
| 576 | .. seealso:: |
| 577 | |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 578 | * `Persistence Tools <https://wiki.python.org/moin/PersistenceTools>`_ lists |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 579 | possibilities on how to save data in the file system. Some of these |
| 580 | modules are part of the standard library |
| 581 | |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 582 | * `Database Programming <https://wiki.python.org/moin/DatabaseProgramming>`_ |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 583 | helps with choosing a method for saving data |
| 584 | |
| 585 | * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper |
| 586 | for Python, and `Elixir <http://elixir.ematia.de/>`_, which makes |
| 587 | SQLAlchemy easier to use |
| 588 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 589 | * `SQLObject <http://www.sqlobject.org/>`_, another popular OR-Mapper |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 590 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 591 | * `ZODB <https://launchpad.net/zodb>`_ and `Durus |
| 592 | <http://www.mems-exchange.org/software/durus/>`_, two object oriented |
| 593 | databases |
| 594 | |
| 595 | |
| 596 | .. _framework: |
| 597 | |
| 598 | Frameworks |
| 599 | ========== |
| 600 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 601 | The process of creating code to run web sites involves writing code to provide |
| 602 | various services. The code to provide a particular service often works the |
| 603 | same way regardless of the complexity or purpose of the web site in question. |
| 604 | Abstracting these common solutions into reusable code produces what are called |
| 605 | "frameworks" for web development. Perhaps the most well-known framework for |
| 606 | web development is Ruby on Rails, but Python has its own frameworks. Some of |
| 607 | these were partly inspired by Rails, or borrowed ideas from Rails, but many |
| 608 | existed a long time before Rails. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 609 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 610 | Originally Python web frameworks tended to incorporate all of the services |
| 611 | needed to develop web sites as a giant, integrated set of tools. No two web |
| 612 | frameworks were interoperable: a program developed for one could not be |
| 613 | deployed on a different one without considerable re-engineering work. This led |
| 614 | to the development of "minimalist" web frameworks that provided just the tools |
| 615 | to communicate between the Python code and the http protocol, with all other |
| 616 | services to be added on top via separate components. Some ad hoc standards |
| 617 | were developed that allowed for limited interoperability between frameworks, |
| 618 | such as a standard that allowed different template engines to be used |
| 619 | interchangeably. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 620 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 621 | Since the advent of WSGI, the Python web framework world has been evolving |
| 622 | toward interoperability based on the WSGI standard. Now many web frameworks, |
| 623 | whether "full stack" (providing all the tools one needs to deploy the most |
| 624 | complex web sites) or minimalist, or anything in between, are built from |
| 625 | collections of reusable components that can be used with more than one |
| 626 | framework. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 627 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 628 | The majority of users will probably want to select a "full stack" framework |
| 629 | that has an active community. These frameworks tend to be well documented, |
| 630 | and provide the easiest path to producing a fully functional web site in |
| 631 | minimal time. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 632 | |
| 633 | |
| 634 | Some notable frameworks |
| 635 | ----------------------- |
| 636 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 637 | There are an incredible number of frameworks, so they cannot all be covered |
| 638 | here. Instead we will briefly touch on some of the most popular. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 639 | |
| 640 | |
| 641 | Django |
| 642 | ^^^^^^ |
| 643 | |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 644 | `Django <https://www.djangoproject.com/>`_ is a framework consisting of several |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 645 | tightly coupled elements which were written from scratch and work together very |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 646 | well. It includes an ORM which is quite powerful while being simple to use, |
| 647 | and has a great online administration interface which makes it possible to edit |
| 648 | the data in the database with a browser. The template engine is text-based and |
| 649 | is designed to be usable for page designers who cannot write Python. It |
| 650 | supports template inheritance and filters (which work like Unix pipes). Django |
| 651 | has many handy features bundled, such as creation of RSS feeds or generic views, |
| 652 | which make it possible to create web sites almost without writing any Python code. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 653 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 654 | It has a big, international community, the members of which have created many |
| 655 | web sites. There are also a lot of add-on projects which extend Django's normal |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 656 | functionality. This is partly due to Django's well written `online |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 657 | documentation <https://docs.djangoproject.com/>`_ and the `Django book |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 658 | <http://www.djangobook.com/>`_. |
| 659 | |
| 660 | |
| 661 | .. note:: |
| 662 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 663 | Although Django is an MVC-style framework, it names the elements |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 664 | differently, which is described in the `Django FAQ |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 665 | <https://docs.djangoproject.com/en/dev/faq/general/#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>`_. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 666 | |
| 667 | |
| 668 | TurboGears |
| 669 | ^^^^^^^^^^ |
| 670 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 671 | Another popular web framework for Python is `TurboGears |
| 672 | <http://www.turbogears.org/>`_. TurboGears takes the approach of using already |
| 673 | existing components and combining them with glue code to create a seamless |
| 674 | experience. TurboGears gives the user flexibility in choosing components. For |
| 675 | example the ORM and template engine can be changed to use packages different |
| 676 | from those used by default. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 677 | |
| 678 | The documentation can be found in the `TurboGears wiki |
| 679 | <http://docs.turbogears.org/>`_, where links to screencasts can be found. |
| 680 | TurboGears has also an active user community which can respond to most related |
| 681 | questions. There is also a `TurboGears book <http://turbogearsbook.com/>`_ |
| 682 | published, which is a good starting point. |
| 683 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 684 | The newest version of TurboGears, version 2.0, moves even further in direction |
| 685 | of WSGI support and a component-based architecture. TurboGears 2 is based on |
| 686 | the WSGI stack of another popular component-based web framework, `Pylons |
Senthil Kumaran | df0e8f9 | 2014-06-11 06:18:43 -0700 | [diff] [blame] | 687 | <http://www.pylonsproject.org/>`_. |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 688 | |
| 689 | |
| 690 | Zope |
| 691 | ^^^^ |
| 692 | |
| 693 | The Zope framework is one of the "old original" frameworks. Its current |
| 694 | incarnation in Zope2 is a tightly integrated full-stack framework. One of its |
| 695 | most interesting feature is its tight integration with a powerful object |
| 696 | database called the `ZODB <https://launchpad.net/zodb>`_ (Zope Object Database). |
| 697 | Because of its highly integrated nature, Zope wound up in a somewhat isolated |
| 698 | ecosystem: code written for Zope wasn't very usable outside of Zope, and |
| 699 | vice-versa. To solve this problem the Zope 3 effort was started. Zope 3 |
| 700 | re-engineers Zope as a set of more cleanly isolated components. This effort |
| 701 | was started before the advent of the WSGI standard, but there is WSGI support |
| 702 | for Zope 3 from the `Repoze <http://repoze.org/>`_ project. Zope components |
| 703 | have many years of production use behind them, and the Zope 3 project gives |
| 704 | access to these components to the wider Python community. There is even a |
| 705 | separate framework based on the Zope components: `Grok |
| 706 | <http://grok.zope.org/>`_. |
| 707 | |
Georg Brandl | 0ffb462 | 2014-10-29 09:37:43 +0100 | [diff] [blame] | 708 | Zope is also the infrastructure used by the `Plone <https://plone.org/>`_ content |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 709 | management system, one of the most powerful and popular content management |
| 710 | systems available. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 711 | |
| 712 | |
| 713 | Other notable frameworks |
| 714 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 715 | |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 716 | Of course these are not the only frameworks that are available. There are |
| 717 | many other frameworks worth mentioning. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 718 | |
| 719 | Another framework that's already been mentioned is `Pylons`_. Pylons is much |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 720 | like TurboGears, but with an even stronger emphasis on flexibility, which comes |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 721 | at the cost of being more difficult to use. Nearly every component can be |
Mark Dickinson | 3e4caeb | 2009-02-21 20:27:01 +0000 | [diff] [blame] | 722 | exchanged, which makes it necessary to use the documentation of every single |
Ezio Melotti | c0deec1 | 2010-04-05 03:51:38 +0000 | [diff] [blame] | 723 | component, of which there are many. Pylons builds upon `Paste |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 724 | <http://pythonpaste.org/>`_, an extensive set of tools which are handy for WSGI. |
| 725 | |
| 726 | And that's still not everything. The most up-to-date information can always be |
| 727 | found in the Python wiki. |
| 728 | |
| 729 | .. seealso:: |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 730 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 731 | The Python wiki contains an extensive list of `web frameworks |
Georg Brandl | 06f3b3b | 2014-10-29 08:36:35 +0100 | [diff] [blame] | 732 | <https://wiki.python.org/moin/WebFrameworks>`_. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 733 | |
| 734 | Most frameworks also have their own mailing lists and IRC channels, look out |
Benjamin Peterson | df611a9 | 2014-12-12 09:56:33 -0500 | [diff] [blame] | 735 | for these on the projects' web sites. |