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 | |
| 9 | This document shows how Python fits into the web. It presents some ways on |
| 10 | how to integrate Python with the web server and general practices useful for |
| 11 | developing web sites. |
| 12 | |
| 13 | |
| 14 | Programming for the Web has become a hot topic since the raise of the "Web 2.0", |
| 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. |
| 17 | Therefore, many so-called "frameworks" and helper tools were created to help |
| 18 | developers creating sites faster and these sites being more robust. This HOWTO |
| 19 | describes some of the methods used to combine Python with a web server to create |
| 20 | dynamic content. It is not meant as a general introduction as this topic is far |
| 21 | too broad to be covered in one single document. However, a short overview of |
| 22 | the most popular libraries is provided. |
| 23 | |
| 24 | .. seealso:: |
| 25 | |
| 26 | While this HOWTO tries to give an overview over Python in the Web, it cannot |
| 27 | always be as up to date as desired. Web development in Python is moving |
| 28 | forward rapidly, so the wiki page on `Web Programming |
| 29 | <http://wiki.python.org/moin/WebProgramming>`_ might be more in sync with |
| 30 | recent development. |
| 31 | |
| 32 | |
| 33 | The low-level view |
| 34 | ================== |
| 35 | |
| 36 | .. .. image:: http.png |
| 37 | |
| 38 | When a user enters a web site, his browser makes a connection to the site's |
| 39 | webserver (this is called the *request*). The server looks up the file in the |
| 40 | file system and sends it back to the user's browser, which displays it (this is |
| 41 | the *response*). This is roughly how the unterlying protocol, HTTP works. |
| 42 | |
| 43 | Now, dynamic web sites are not files in the file system, but rather programs |
| 44 | which are run by the web server when a request comes in. They can do all sorts |
| 45 | of useful things, like display the postings of a bulletin board, show your |
| 46 | mails, configurate software or just display the current time. These programs |
| 47 | can be written in about any programming language the server supports, so it is |
| 48 | easy to use Python for creating dynamic web sites. |
| 49 | |
| 50 | As most of HTTP servers are written in C or C++, they cannot execute Python code |
| 51 | in a simple way -- a bridge is needed between the server and the program. These |
| 52 | bridges or rather interfaces define how programs interact with the server. In |
| 53 | the past there have been numerous attempts to create the best possible |
| 54 | interface, but there are only a few worth mentioning. |
| 55 | |
| 56 | Not every web server supports every interface. Many web servers do support only |
| 57 | old, now-obsolete interfaces. But they can often be extended using some |
| 58 | third-party modules to support new interfaces. |
| 59 | |
| 60 | |
| 61 | Common Gateway Interface |
| 62 | ------------------------ |
| 63 | |
| 64 | This interface is the oldest one, supported by nearly every web server out of |
| 65 | the box. Programs using CGI to communicate with their web server need to be |
| 66 | started by the server for every request. So, every request starts a new Python |
| 67 | interpreter -- which takes some time to start up -- thus making the whole |
| 68 | interface only usable for low load situations. |
| 69 | |
| 70 | The upside of CGI is that it is simple -- writing a program which uses CGI is a |
| 71 | matter of about three lines of code. But this simplicity comes at a price: it |
| 72 | does very few things to help the developer. |
| 73 | |
| 74 | Writing CGI programs, while still possible, is not recommended anymore. With |
| 75 | WSGI (more on that later) it is possible to write programs that emulate CGI, so |
| 76 | they can be run as CGI if no better option is available. |
| 77 | |
| 78 | .. seealso:: |
| 79 | |
| 80 | The Python standard library includes some modules that are helpful for |
| 81 | creating plain CGI programs: |
| 82 | |
| 83 | * :mod:`cgi` -- Handling of user input in CGI scripts |
| 84 | * :mod:`cgitb` -- Displays nice tracebacks when errors happen in of CGI |
| 85 | applications, instead of presenting a "500 Internal Server Error" message |
| 86 | |
| 87 | The Python wiki features a page on `CGI scripts |
| 88 | <http://wiki.python.org/moin/CgiScripts>`_ with some additional information |
| 89 | about CGI in Python. |
| 90 | |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 91 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 92 | Simple script for testing CGI |
| 93 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 94 | |
| 95 | To test whether your web server works with CGI, you can use this short and |
| 96 | simple CGI program:: |
| 97 | |
| 98 | #!/usr/bin/env python |
| 99 | # -*- coding: UTF-8 -*- |
| 100 | |
| 101 | # enable debugging |
Georg Brandl | 6b5dbaa | 2009-02-20 08:22:21 +0000 | [diff] [blame] | 102 | import cgitb |
| 103 | cgitb.enable() |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 104 | |
| 105 | print "Content-Type: text/plain;charset=utf-8" |
| 106 | print |
| 107 | |
| 108 | print "Hello World!" |
| 109 | |
| 110 | You need to write this code into a file with a ``.py`` or ``.cgi`` extension, |
| 111 | this depends on your web server configuration. Depending on your web server |
| 112 | configuration, this file may also need to be in a ``cgi-bin`` folder, for |
| 113 | security reasons. |
| 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 |
| 118 | risk exposing some confident data to the user. Don't use it when the script is |
| 119 | ready for production use. Still, you should *always* catch exceptions, and |
| 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 |
| 128 | check whether if works as-is and if not you need to talk to the administrator of |
| 129 | your web server anyway. If it is a big hoster, you can try filing a ticket |
| 130 | asking for Python support. |
| 131 | |
| 132 | If you're your own administrator or want to install it for testing purposes on |
| 133 | your own computers, you have to configure it by yourself. There is no one and |
| 134 | single way on how to configure CGI, as there are many web servers with different |
| 135 | configuration options. The currently most widely used free web server is |
| 136 | `Apache HTTPd <http://httpd.apache.org/>`_, Apache for short -- this is the one |
| 137 | that most people use, it can be easily installed on nearly every system using |
| 138 | the systems' package management. But `lighttpd <http://www.lighttpd.net>`_ has |
| 139 | been gaining attention since some time and is said to have a better performance. |
| 140 | On many systems this server can also be installed using the package management, |
| 141 | so manually compiling the web server is never needed. |
| 142 | |
| 143 | * On Apache you can take a look into the `Dynamic Content with CGI |
| 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. |
| 147 | * On lighttpd you need to use the `CGI module |
| 148 | <http://trac.lighttpd.net/trac/wiki/Docs%3AModCGI>`_ which can be configured |
| 149 | in a straightforward way. It boils down to setting ``cgi.assign`` properly. |
| 150 | |
| 151 | |
| 152 | Common problems with CGI scripts |
| 153 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 154 | |
| 155 | Trying to use CGI sometimes leads to small annoyances that one might experience |
| 156 | while trying to get these scripts to run. Sometimes it happens that a seemingly |
| 157 | correct script does not work as expected, which is caused by some small hidden |
| 158 | reason that's difficult to spot. |
| 159 | |
| 160 | Some of these reasons are: |
| 161 | |
| 162 | * The Python script is not marked executable. When CGI scripts are not |
| 163 | executable most of the web servers will let the user download it, instead of |
| 164 | running it and sending the output to the user. For CGI scripts to run |
| 165 | properly the ``+x`` bit needs to be set. Using ``chmod a+x your_script.py`` |
| 166 | might already solve the problem. |
| 167 | * The line endings must be of Unix-type. This is important because the web |
| 168 | server checks the first line of the script (called shebang) and tries to run |
| 169 | the program specified there. It gets easily confused by Windows line endings |
| 170 | (Carriage Return & Line Feed, also called CRLF), so you have to convert the |
| 171 | file to Unix line endings (only Line Feed, LF). This can be done |
| 172 | automatically by uploading the file via FTP in text mode instead of binary |
| 173 | mode, but the preferred way is just telling your editor to save the files with |
| 174 | Unix line endings. Most proper editors support this. |
| 175 | * Your web server must be able to read the file, you need to make sure the |
| 176 | permissions are fine. Often the server runs as user and group ``www-data``, |
| 177 | so it might be worth a try to change the file ownership or making the file |
| 178 | world readable by using ``chmod a+r your_script.py``. |
| 179 | * The webserver must be able to know that the file you're trying to access is a |
| 180 | CGI script. Check the configuration of your web server, maybe there is some |
| 181 | mistake. |
| 182 | * The path to the interpreter in the shebang (``#!/usr/bin/env python``) must be |
| 183 | currect. This line calls ``/usr/bin/env`` to find Python, but it'll fail if |
| 184 | there is no ``/usr/bin/env``. If you know where your Python is installed, you |
| 185 | can also use that path. The commands ``whereis python`` and ``type -p |
| 186 | python`` might also help to find where it is installed. Once this is known, |
| 187 | the shebang line can be changed accordingly: ``#!/usr/bin/python``. |
| 188 | * The file must not contain a BOM (Byte Order Mark). The BOM is meant for |
| 189 | determining the byte order of UTF-16 encodings, but some editors write this |
| 190 | also into UTF-8 files. The BOM interferes with the shebang line, so be sure |
| 191 | to tell your editor not to write the BOM. |
| 192 | * :ref:`mod-python` might be making problems. mod_python is able to handle CGI |
| 193 | scripts by itself, but it can also be a source for problems. Be sure you |
| 194 | disable it. |
| 195 | |
| 196 | |
| 197 | .. _mod-python: |
| 198 | |
| 199 | mod_python |
| 200 | ---------- |
| 201 | |
| 202 | People coming from PHP often find it hard to grasp how to use Python in the web. |
| 203 | Their first thought is mostly `mod_python <http://www.modpython.org/>`_ because |
| 204 | they think that this is the equivalent to ``mod_php``. Actually it is not |
| 205 | really. It does embed the interpreter into the Apache process, thus speeding up |
| 206 | requests by not having to start a Python interpreter every request. On the |
| 207 | other hand, it is by far not "Python intermixed with HTML" as PHP often does. |
| 208 | The Python equivalent of that is a template engine. mod_python itself is much |
| 209 | more powerful and gives more access to Apache internals. It can emulate CGI, it |
| 210 | can work an a "Python Server Pages" mode similar to JSP which is "HTML |
| 211 | intermangled with Python" and it has a "Publisher" which destignates one file to |
| 212 | accept all requests and decide on what to do then. |
| 213 | |
| 214 | But mod_python has some problems. Unlike the PHP interpreter the Python |
| 215 | interpreter uses caching when executing files, so when changing a file the whole |
| 216 | web server needs to be re-started to update. Another problem ist the basic |
| 217 | concept -- Apache starts some child processes to handle the requests and |
| 218 | unfortunately every child process needs to load the whole Python interpreter |
| 219 | even if it does not use it. This makes the whole web server slower. Another |
| 220 | problem is that as mod_python is linked against a specific version of |
| 221 | ``libpython``, it is not possible to switch from an older version to a newer |
| 222 | (e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to |
| 223 | the Apache web server, so programs written for mod_python cannot easily run on |
| 224 | other web servers. |
| 225 | |
| 226 | These are the reasons why mod_python should be avoided when writing new |
| 227 | programs. In some circumstances it might be still a good idea to use mod_python |
| 228 | for deployment, but WSGI makes it possible to run WSGI programs under mod_python |
| 229 | as well. |
| 230 | |
| 231 | |
| 232 | FastCGI and SCGI |
| 233 | ---------------- |
| 234 | |
| 235 | FastCGI and SCGI try to solve the performance problem of CGI in another way. |
| 236 | Instead of embedding the interpreter into the web server, they create |
| 237 | long-running processes which run in the background. There still is some module |
| 238 | in the web server which makes it possible for the web server to "speak" with the |
| 239 | background process. As the background process is independent from the server, |
| 240 | it can be written in any language of course also in Python. The language just |
| 241 | needs to have a library which handles the communication with the web server. |
| 242 | |
| 243 | The difference between FastCGI and SCGI is very small, as SCGI is essentially |
| 244 | just a "simpler FastCGI". But as the web server support for SCGI is limited |
| 245 | most people use FastCGI instead, which works the same way. Almost everything |
| 246 | that applies to SCGI also applies to FastCGI as well, so we'll only write about |
| 247 | the latter. |
| 248 | |
| 249 | These days, FastCGI is never used directly. Just like ``mod_python`` it is only |
| 250 | used for the deployment of WSGI applications. |
| 251 | |
| 252 | .. seealso:: |
| 253 | |
| 254 | * `FastCGI, SCGI, and Apache: Background and Future |
| 255 | <http://www.vmunix.com/mark/blog/archives/2006/01/02/fastcgi-scgi-and-apache-background-and-future/>`_ |
| 256 | is a discussion on why the concept of FastCGI and SCGI is better that that |
| 257 | of mod_python. |
| 258 | |
| 259 | |
| 260 | Setting up FastCGI |
| 261 | ^^^^^^^^^^^^^^^^^^ |
| 262 | |
| 263 | Depending on the web server you need to have a special module. |
| 264 | |
| 265 | * Apache has both `mod_fastcgi <http://www.fastcgi.com/>`_ and `mod_fcgid |
| 266 | <http://fastcgi.coremail.cn/>`_. ``mod_fastcgi`` is the original one, but it |
| 267 | has some licensing issues that's why it is sometimes considered non-free. |
| 268 | ``mod_fcgid`` is a smaller, compatible alternative. One of these modules needs |
| 269 | to be loaded by Apache. |
| 270 | * lighttpd ships its own `FastCGI module |
| 271 | <http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI>`_ as well as an `SCGI |
| 272 | module <http://trac.lighttpd.net/trac/wiki/Docs%3AModSCGI>`_. |
Georg Brandl | a4314c2 | 2009-10-11 20:16:16 +0000 | [diff] [blame] | 273 | * nginx also supports `FastCGI <http://wiki.nginx.org/NginxSimplePythonFCGI>`_. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 274 | |
| 275 | Once you have installed and configured the module, you can test it with the |
| 276 | following WSGI-application:: |
| 277 | |
| 278 | #!/usr/bin/env python |
| 279 | # -*- coding: UTF-8 -*- |
| 280 | |
| 281 | from cgi import escape |
Benjamin Peterson | a7b55a3 | 2009-02-20 03:31:23 +0000 | [diff] [blame] | 282 | import sys, os |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 283 | from flup.server.fcgi import WSGIServer |
| 284 | |
| 285 | def app(environ, start_response): |
| 286 | start_response('200 OK', [('Content-Type', 'text/html')]) |
| 287 | |
| 288 | yield '<h1>FastCGI Environment</h1>' |
| 289 | yield '<table>' |
| 290 | for k, v in sorted(environ.items()): |
| 291 | yield '<tr><th>%s</th><td>%s</td></tr>' % (escape(k), escape(v)) |
| 292 | yield '</table>' |
| 293 | |
| 294 | WSGIServer(app).run() |
| 295 | |
| 296 | This is a simple WSGI application, but you need to install `flup |
| 297 | <http://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level |
| 298 | FastCGI access. |
| 299 | |
| 300 | .. seealso:: |
| 301 | |
| 302 | There is some documentation on `setting up Django with FastCGI |
| 303 | <http://www.djangoproject.com/documentation/fastcgi/>`_, most of which can be |
| 304 | reused for other WSGI-compliant frameworks and libraries. Only the |
| 305 | ``manage.py`` part has to be changed, the example used here can be used |
| 306 | instead. Django does more or less the exact same thing. |
| 307 | |
| 308 | |
| 309 | mod_wsgi |
| 310 | -------- |
| 311 | |
| 312 | `mod_wsgi <http://www.modwsgi.org/>`_ is an attempt to get rid of the low level |
| 313 | gateways. As FastCGI, SCGI, mod_python are mostly used to deploy WSGI |
| 314 | applications anyway, mod_wsgi was started to directly embed WSGI aplications |
| 315 | into the Apache web server. The benefit from this approach is that WSGI |
| 316 | applications can be deployed much easier as is is specially designed to host |
| 317 | WSGI applications -- unlike the other low level methods which have glue code to |
| 318 | host WSGI applications (like flup which was mentioned before). The downside is |
| 319 | that mod_wsgi is limited to the Apache web server, other servers would need |
| 320 | their own implementations of mod_wsgi. |
| 321 | |
| 322 | It supports two modes: the embedded mode in which it integrates with the Apache |
| 323 | process and the daemon mode which is more FastCGI-like. Contrary to FastCGI, |
| 324 | mod_wsgi handles the worker-processes by itself which makes administration |
| 325 | easier. |
| 326 | |
| 327 | |
| 328 | .. _WSGI: |
| 329 | |
| 330 | Step back: WSGI |
| 331 | =============== |
| 332 | |
| 333 | WSGI was already mentioned several times so it has to be something important. |
| 334 | In fact it really is, so now it's time to explain. |
| 335 | |
| 336 | The *Web Server Gateway Interface*, :pep:`333` or WSGI for short is currently |
| 337 | the best possible way to Python web programming. While it is great for |
| 338 | programmers writing frameworks, the normal person does not need to get in direct |
| 339 | contact with it. But when choosing a framework for web development it is a good |
| 340 | idea to take one which supports WSGI. |
| 341 | |
| 342 | The big profit from WSGI is the unification. When your program is compatible |
| 343 | with WSGI -- that means that your framework has support for WSGI, your program |
| 344 | can be deployed on every web server interface for which there are WSGI wrappers. |
| 345 | So you do not need to care about whether the user uses mod_python or FastCGI -- |
| 346 | with WSGI it just works on any gateway interface. The Python standard library |
| 347 | contains its own WSGI server :mod:`wsgiref`, which is a small web server that |
| 348 | can be used for testing. |
| 349 | |
| 350 | A really great WSGI feature are the middlewares. Middlewares are layers around |
| 351 | your program which can add various functionality to it. There is a `number of |
| 352 | middlewares <http://wsgi.org/wsgi/Middleware_and_Utilities>`_ already available. |
| 353 | For example, instead of writing your own session management (to identify a user |
| 354 | in subsequent requests, as HTTP does not maintain state, so it does now know |
| 355 | that the requests belong to the same user) you can just take one middleware, |
| 356 | plug it in and you can rely an already existing functionality. The same thing |
| 357 | is compression -- say you want to compress your HTML using gzip, to save your |
| 358 | server's bandwidth. So you only need to plug-in a middleware and you're done. |
| 359 | Authentication is also a problem easily solved using a middleware. |
| 360 | |
| 361 | So, generally -- although WSGI may seem complex, the initial phase of learning |
| 362 | can be very rewarding as WSGI does already have solutions to many problems that |
| 363 | might arise while writing web sites. |
| 364 | |
| 365 | |
| 366 | WSGI Servers |
| 367 | ------------ |
| 368 | |
| 369 | The code that is used to connect to various low level gateways like CGI or |
| 370 | mod_python is called *WSGI server*. One of these servers is ``flup`` which was |
| 371 | already mentioned and supports FastCGI, SCGI as well as `AJP |
| 372 | <http://en.wikipedia.org/wiki/Apache_JServ_Protocol>`_. Some of these servers |
| 373 | are written in Python as ``flup`` is, but there also exist others which are |
| 374 | written in C and can be used as drop-in replacements. |
| 375 | |
| 376 | There are quite a lot of servers already available, so a Python web application |
| 377 | can be deployed nearly everywhere. This is one big advantage that Python has |
| 378 | compared with other web techniques. |
| 379 | |
| 380 | .. seealso:: |
| 381 | |
| 382 | A good overview of all WSGI-related code can be found in the `WSGI wiki |
| 383 | <http://wsgi.org/wsgi>`_, which contains an extensive list of `WSGI servers |
| 384 | <http://wsgi.org/wsgi/Servers>`_, which can be used by *every* application |
| 385 | supporting WSGI. |
| 386 | |
| 387 | You might be interested in some WSGI-supporting modules already contained in |
| 388 | the standard library, namely: |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 389 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 390 | * :mod:`wsgiref` -- some tiny utilities and servers for WSGI |
| 391 | |
| 392 | |
| 393 | Case study: MoinMoin |
| 394 | -------------------- |
| 395 | |
| 396 | What does WSGI give the web application developer? Let's take a look on one |
| 397 | long existing web application written in Python without using WSGI. |
| 398 | |
| 399 | One of the most widely used wiki software is `MoinMoin <http://moinmo.in/>`_. |
| 400 | It was created in 2000, so it predates WSGI by about three years. While it now |
| 401 | includes support for WSGI, older versions needed separate code to run on CGI, |
| 402 | mod_python, FastCGI and standalone. Now, this all is possible by using WSGI and |
| 403 | the already-written gateways. For running with on FastCGI ``flup`` can be used, |
| 404 | for running a standalone server :mod:`wsgiref` is the way to go. |
| 405 | |
| 406 | |
| 407 | Model-view-controller |
| 408 | ===================== |
| 409 | |
| 410 | The term *MVC* is often heard in statements like "framework *foo* supports MVC". |
| 411 | While MVC is not really something technical but rather organisational, many web |
| 412 | frameworks use this model to help the developer to bring structure into his |
| 413 | program. Bigger web applications can have lots of code so it is a good idea to |
| 414 | have structure in the program right from the beginnings. That way, even users |
| 415 | of other frameworks (or even languages, as MVC is nothing Python-specific) can |
| 416 | understand the existing code easier, as they are already familiar with the |
| 417 | structure. |
| 418 | |
| 419 | MVC stands for three components: |
| 420 | |
| 421 | * The *model*. This is the data that is meant to modify. In Python frameworks |
| 422 | this component is often represented by the classes used by the |
| 423 | object-relational mapper. So, all declarations go here. |
| 424 | * The *view*. This component's job is to display the data of the model to the |
| 425 | user. Typically this component is represented by the templates. |
| 426 | * The *controller*. This is the layer between the user and the model. The |
| 427 | controller reacts on user actions (like opening some specific URL) and tells |
Mark Dickinson | 3e4caeb | 2009-02-21 20:27:01 +0000 | [diff] [blame] | 428 | the model to modify the data if necessary. |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 429 | |
| 430 | While one might think that MVC is a complex design pattern, in fact it is not. |
| 431 | It is used in Python because it has turned out to be useful for creating clean, |
| 432 | maintainable web sites. |
| 433 | |
| 434 | .. note:: |
| 435 | |
| 436 | While not all Python frameworks explicitly support MVC, it is often trivial |
Mark Dickinson | 3e4caeb | 2009-02-21 20:27:01 +0000 | [diff] [blame] | 437 | 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] | 438 | (the model) from the user interaction logic (the controller) and the |
Mark Dickinson | 3e4caeb | 2009-02-21 20:27:01 +0000 | [diff] [blame] | 439 | templates (the view). That's why it is important not to write unnecessary |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 440 | Python code in the templates -- it is against MVC and creates more chaos. |
| 441 | |
| 442 | .. seealso:: |
| 443 | |
| 444 | The english Wikipedia has an article about the `Model-View-Controller pattern |
| 445 | <http://en.wikipedia.org/wiki/Model-view-controller>`_, which includes a long |
| 446 | list of web frameworks for different programming languages. |
| 447 | |
| 448 | |
| 449 | Ingredients for web sites |
| 450 | ========================= |
| 451 | |
| 452 | Web sites are complex constructs, so tools were created to help the web site |
| 453 | developer to make his work maintainable. None of these tools are in any way |
| 454 | Python specific, they also exist for other programming languages as well. Of |
| 455 | course, developers are not forced to use these tools and often there is no |
| 456 | "best" tool, but it is worth informing yourself before choosing something |
| 457 | because of the big number of helpers that the developer can use. |
| 458 | |
| 459 | |
| 460 | .. seealso:: |
| 461 | |
| 462 | People have written far more components that can be combined than these |
| 463 | presented here. The Python wiki has a page about these components, called |
| 464 | `Web Components <http://wiki.python.org/moin/WebComponents>`_. |
| 465 | |
| 466 | |
| 467 | Templates |
| 468 | --------- |
| 469 | |
| 470 | Mixing of HTML and Python code is possible with some libraries. While |
| 471 | convenient at first, it leads to horribly unmaintainable code. That's why |
| 472 | templates exist. Templates are, in the simplest case, just HTML files with |
| 473 | placeholders. The HTML is sent to the user's browser after filling out the |
| 474 | placeholders. |
| 475 | |
| 476 | Python already includes such simple templates:: |
| 477 | |
| 478 | # a simple template |
| 479 | template = "<html><body><h1>Hello %s!</h1></body></html>" |
| 480 | print template % "Reader" |
| 481 | |
| 482 | The Python standard library also includes some more advanced templates usable |
| 483 | through :class:`string.Template`, but in HTML templates it is needed to use |
| 484 | conditional and looping contructs like Python's *for* and *if*. So, some |
| 485 | *template engine* is needed. |
| 486 | |
| 487 | Now, Python has a lot of template engines which can be used with or without a |
| 488 | `framework`_. Some of these are using a plain-text programming language which |
| 489 | is very easy to learn as it is quite limited while others use XML so the |
| 490 | template output is always guaranteed to be valid XML. Some `frameworks`_ ship |
| 491 | their own template engine or recommend one particular. If one is not yet sure, |
| 492 | using these is a good idea. |
| 493 | |
| 494 | .. note:: |
| 495 | |
| 496 | While Python has quite a lot of different template engines it usually does |
| 497 | not make sense to use a homebrewed template system. The time needed to |
| 498 | evaluate all templating systems is not really worth it, better invest the |
| 499 | time in looking through the most popular ones. Some frameworks have their |
| 500 | own template engine or have a recommentation for one. It's wise to use |
| 501 | these. |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 502 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 503 | Popular template engines include: |
| 504 | |
| 505 | * Mako |
| 506 | * Genshi |
| 507 | * Jinja |
| 508 | |
| 509 | .. seealso:: |
| 510 | |
| 511 | Lots of different template engines divide the attention between themselves |
| 512 | because it's easy to create them in Python. The page `Templating |
| 513 | <http://wiki.python.org/moin/Templating>`_ in the wiki lists a big, |
| 514 | ever-growing number of these. |
| 515 | |
| 516 | |
| 517 | Data persistence |
| 518 | ---------------- |
| 519 | |
| 520 | *Data persistence*, while sounding very complicated is just about storing data. |
| 521 | This data might be the text of blog entries, the postings of a bulletin board or |
| 522 | the text of a wiki page. As always, there are different ways to store |
| 523 | informations on a web server. |
| 524 | |
| 525 | Often relational database engines like `MySQL <http://www.mysql.com/>`_ or |
Georg Brandl | a4314c2 | 2009-10-11 20:16:16 +0000 | [diff] [blame] | 526 | `PostgreSQL <http://www.postgresql.org/>`_ are used due to their good |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 527 | performance handling very large databases consisting of up to millions of |
| 528 | entries. These are *queried* using a language called `SQL |
| 529 | <http://en.wikipedia.org/wiki/SQL>`_. Python programmers in general do not like |
| 530 | SQL too much, they prefer to work with objects. It is possible to save Python |
| 531 | objects into a database using a technology called `ORM |
| 532 | <http://en.wikipedia.org/wiki/Object-relational_mapping>`_. ORM translates all |
| 533 | object-oriented access into SQL code under the hood, the user does not need to |
| 534 | think about it. Most `frameworks`_ use ORMs and it works quite well. |
| 535 | |
| 536 | A second possibility is using files that are saved on the hard disk (sometimes |
| 537 | called flatfiles). This is very easy, but is not too fast. There is even a |
| 538 | small database engine called `SQLite <http://www.sqlite.org/>`_ which is bundled |
| 539 | with Python in the :mod:`sqlite` module and uses only one file. This database |
| 540 | can be used to store objects via an ORM and has no other dependencies. For |
| 541 | smaller sites SQLite is just enough. But it is not the only way in which data |
| 542 | can be saved into the file systems. Sometimes normal, plain text files are |
| 543 | enough. |
| 544 | |
| 545 | The third and least used possibility are so-called object oriented databases. |
| 546 | These databases store the *actual objects* instead of the relations that |
| 547 | OR-mapping creates between rows in a database. This has the advantage that |
| 548 | nearly all objects can be saven in a straightforward way, unlike in relational |
| 549 | databases where some objects are very hard to represent with ORMs. |
| 550 | |
| 551 | `Frameworks`_ often give the users hints on which method to choose, it is |
| 552 | usually a good idea to stick to these unless there are some special requirements |
| 553 | which require to use the one method and not the other. |
| 554 | |
| 555 | .. seealso:: |
| 556 | |
| 557 | * `Persistence Tools <http://wiki.python.org/moin/PersistenceTools>`_ lists |
| 558 | possibilities on how to save data in the file system, some of these modules |
| 559 | are part of the standard library |
| 560 | * `Database Programming <http://wiki.python.org/moin/DatabaseProgramming>`_ |
| 561 | helps on choosing a method on how to save the data |
| 562 | * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper for |
| 563 | Python and `Elixir <http://elixir.ematia.de/>`_ which makes it easier to |
| 564 | use |
| 565 | * `SQLObject <http://www.sqlobject.org/>`_, another popular OR-Mapper |
| 566 | * `ZODB <https://launchpad.net/zodb>`_ and `Durus |
| 567 | <http://www.mems-exchange.org/software/durus/>`_, two object oriented |
| 568 | databases |
| 569 | |
| 570 | |
| 571 | .. _framework: |
| 572 | |
| 573 | Frameworks |
| 574 | ========== |
| 575 | |
| 576 | As web sites can easily become quite large, there are so-called frameworks which |
| 577 | were created to help the developer with making these sites. Although the most |
| 578 | well-known framework is Ruby on Rails, Python does also have its own frameworks |
| 579 | which are partly inspired by Rails or which were existing a long time before |
| 580 | Rails. |
| 581 | |
| 582 | Two possible approaches to web frameworks exist: the minimalistic approach and |
| 583 | the all-inclusive approach (somtimes called *full-stack*). Frameworks which are |
| 584 | all-inclusive give you everything you need to start working, like a template |
| 585 | engine, some way to save and access data in databases and many features more. |
| 586 | Most users are best off using these as they are widely used by lots of other |
| 587 | users and well documented in form of books and tutorials. Other web frameworks |
| 588 | go the minimalistic approach trying to be as flexible as possible leaving the |
| 589 | user the freedom to choose what's best for him. |
| 590 | |
| 591 | The majority of users is best off with all-inclusive framewors. They bring |
| 592 | everything along so a user can just jump in and start to code. While they do |
| 593 | have some limitations they can fullfill 80% of what one will ever want to |
| 594 | perfectly. They consist of various components which are designed to work |
| 595 | together as good as possible. |
| 596 | |
| 597 | The multitude of web frameworks written in Python demonstrates that it is really |
| 598 | easy to write one. One of the most well-known web applications written in |
| 599 | Python is `Zope <http://www.zope.org/>`_ which can be regarded as some kind of |
| 600 | big framework. But Zope was not the only framework, there were some others |
| 601 | which are by now nearly forgotten. These do not need to be mentioned anymore, |
| 602 | because most people that used them moved on to newer ones. |
| 603 | |
| 604 | |
| 605 | Some notable frameworks |
| 606 | ----------------------- |
| 607 | |
| 608 | There is an incredible number of frameworks, so there is no way to describe them |
Mark Dickinson | 3e4caeb | 2009-02-21 20:27:01 +0000 | [diff] [blame] | 609 | all. It is not even necessary, as most of these frameworks are nothing special |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 610 | and everything that can be done with these can also be done with one of the |
| 611 | popular ones. |
| 612 | |
| 613 | |
| 614 | Django |
| 615 | ^^^^^^ |
| 616 | |
| 617 | `Django <http://www.djangoproject.com/>`_ is a framework consisting of several |
| 618 | tightly coupled elements which were written from scratch and work together very |
| 619 | well. It includes an ORM which is quite powerful while being simple to use and |
| 620 | has a great online administration interface which makes it possible to edit the |
| 621 | data in the database with a browser. The template engine is text-based and is |
| 622 | designed to be usable for page designers who cannot write Python. It supports |
| 623 | so-called template inheritance and filters (which work like Unix pipes). Django |
| 624 | has many handy features bundled, like creation of RSS feeds or generic views |
| 625 | which make it possible to write web sites nearly without any Python code. |
| 626 | |
| 627 | It has a big, international community which has created many sites using Django. |
| 628 | There are also quite a lot of add-on projects which extend Django's normal |
| 629 | functionality. This is partly due to Django's well written `online |
Georg Brandl | a4314c2 | 2009-10-11 20:16:16 +0000 | [diff] [blame] | 630 | documentation <http://docs.djangoproject.com/>`_ and the `Django book |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 631 | <http://www.djangobook.com/>`_. |
| 632 | |
| 633 | |
| 634 | .. note:: |
| 635 | |
| 636 | Although Django is an MVC-style framework, it calls the components |
| 637 | differently, which is described in the `Django FAQ |
| 638 | <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>`_. |
| 639 | |
| 640 | |
| 641 | TurboGears |
| 642 | ^^^^^^^^^^ |
| 643 | |
| 644 | The other popular web framework in Python is `TurboGears |
| 645 | <http://www.turbogears.org/>`_. It takes the approach of using already existing |
| 646 | components and combining them with glue code to create a seamless experience. |
| 647 | TurboGears gives the user more flexibility on which components to choose, the |
| 648 | ORM can be switched between some easy to use but limited and complex but very |
| 649 | powerful. Same goes for the template engine. One strong point about TurboGears |
| 650 | is that the components that it consists of can be used easily in other projects |
| 651 | without depending on TurboGears, for example the underlying web server CherryPy. |
| 652 | |
| 653 | The documentation can be found in the `TurboGears wiki |
| 654 | <http://docs.turbogears.org/>`_, where links to screencasts can be found. |
| 655 | TurboGears has also an active user community which can respond to most related |
| 656 | questions. There is also a `TurboGears book <http://turbogearsbook.com/>`_ |
| 657 | published, which is a good starting point. |
| 658 | |
| 659 | The plan for the next major version of TurboGears, version 2.0 is to switch to a |
| 660 | more flexible base provided by another very flexible web framework called |
| 661 | `Pylons <http://pylonshq.com/>`_. |
| 662 | |
| 663 | |
| 664 | Other notable frameworks |
| 665 | ^^^^^^^^^^^^^^^^^^^^^^^^ |
| 666 | |
| 667 | These two are of course not the only frameworks that are available, there are |
| 668 | also some less-popular frameworks worth mentioning. |
| 669 | |
| 670 | One of these is the already mentioned Zope, which has been around for quite a |
| 671 | long time. With Zope 2.x having been known as rather un-pythonic, the newer |
| 672 | Zope 3.x tries to change that and therefore gets more acceptance from Python |
| 673 | programmers. These efforts already showed results, there is a project which |
| 674 | connects Zope with WSGI called `Repoze <http://repoze.org/>`_ and another |
| 675 | project called `Grok <http://grok.zope.org/>`_ which makes it possible for |
| 676 | "normal" Python programmers use the very mature Zope components. |
| 677 | |
| 678 | Another framework that's already been mentioned is `Pylons`_. Pylons is much |
| 679 | like TurboGears with ab even stronger emphasis on flexibility, which is bought |
| 680 | 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] | 681 | exchanged, which makes it necessary to use the documentation of every single |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 682 | component, because there are so many Pylons combinations possible that can |
| 683 | satisfy every requirement. Pylons builds upon `Paste |
| 684 | <http://pythonpaste.org/>`_, an extensive set of tools which are handy for WSGI. |
| 685 | |
| 686 | And that's still not everything. The most up-to-date information can always be |
| 687 | found in the Python wiki. |
| 688 | |
| 689 | .. seealso:: |
Georg Brandl | c62ef8b | 2009-01-03 20:55:06 +0000 | [diff] [blame] | 690 | |
Georg Brandl | 0f3629d | 2008-09-07 17:00:17 +0000 | [diff] [blame] | 691 | The Python wiki contains an extensive list of `web frameworks |
| 692 | <http://wiki.python.org/moin/WebFrameworks>`_. |
| 693 | |
| 694 | Most frameworks also have their own mailing lists and IRC channels, look out |
| 695 | for these on the projects' websites. There is also a general "Python in the |
| 696 | Web" IRC channel on freenode called `#python.web |
| 697 | <http://wiki.python.org/moin/PoundPythonWeb>`_. |