1.1 --- a/docs/anatomy.html Mon Apr 25 22:03:10 2005 +0000
1.2 +++ b/docs/anatomy.html Mon Apr 25 22:04:02 2005 +0000
1.3 @@ -38,7 +38,7 @@
1.4 <td align="center" valign="undefined">Most new code will be
1.5 written in the application.</td>
1.6 <td align="center" valign="undefined">Applications are
1.7 -described in <a href="resources.html">this part of the documentation</a>.</td>
1.8 +described in <a href="resources.html">"Applications and Resources"</a>.</td>
1.9 </tr>
1.10 <tr>
1.11 <th
1.12 @@ -48,9 +48,8 @@
1.13 "glues" the application to the environment.</span></td>
1.14 <td align="center" valign="undefined">Mostly copying an existing
1.15 adapter or writing a short module.</td>
1.16 - <td align="center" valign="undefined">Adapters are explained in
1.17 -the <a href="deploying.html">deployment
1.18 -documentation</a>. </td>
1.19 + <td align="center" valign="undefined">Adapters are explained in <a
1.20 + href="deploying.html">"Deploying a WebStack Application"</a>. </td>
1.21 </tr>
1.22 <tr>
1.23 <th
1.24 @@ -62,8 +61,8 @@
1.25 if any at all.</td>
1.26 <td align="center" valign="undefined">Server environments are
1.27 covered
1.28 -in the <a href="deploying.html">deployment
1.29 -documentation</a>. </td>
1.30 +in <a href="deploying.html">"Deploying a WebStack Application"</a>.
1.31 + </td>
1.32 </tr>
1.33 </tbody>
1.34 </table>
2.1 --- a/docs/design.html Mon Apr 25 22:03:10 2005 +0000
2.2 +++ b/docs/design.html Mon Apr 25 22:04:02 2005 +0000
2.3 @@ -10,14 +10,55 @@
2.4 <body>
2.5 <h1>Application Design Considerations</h1>
2.6 <p>When writing an application, we
2.7 -must consider a number of factors which
2.8 -have an impact on the code (and other things) that we will need to
2.9 -provide as
2.10 -part of the finished product or service.</p>
2.11 +must try and cover the three activities mentioned in our overview of
2.12 +what a simple application looks like:</p>
2.13 +<ol>
2.14 + <li>Examine the transaction, decide what the user wants to do.</li>
2.15 + <li>Perform some kind of action with the information supplied.</li>
2.16 + <li>Produce some kind of response which tells the user what happened.</li>
2.17 +</ol>
2.18 +<p>We briefly covered the third activity in the <code>MyApplication</code>
2.19 +example, but for a real, properly-behaved application, we need to visit
2.20 +each activity in detail.</p>
2.21 +<h2>Examine the Transaction</h2>
2.22 +<p>In WebStack, the transaction is an object which is passed into a
2.23 +resource when a user makes contact with an application. This
2.24 +transaction object effectively tells us what it is the user wants to
2.25 +do; it does so through a number of different pieces of information
2.26 +including the request method, headers, parameters, cookies and sessions.</p>
2.27 +<div class="WebStack">
2.28 +<h3>WebStack API - The Transaction Object</h3>
2.29 +<p>The transaction object appears as the first parameter in a
2.30 +resource's <code>respond</code> method:</p>
2.31 +<pre>class SomeResource:<br /> def respond(self, trans):<br /> [Here is where the code for the resource is written.]</pre>
2.32 +<p>For full information about transaction objects, see the API
2.33 +documentation for the <a
2.34 + href="../apidocs/public/WebStack.Generic.Transaction-class.html"><code>WebStack.Generic.Transaction</code></a>
2.35 +class.</p>
2.36 +</div>
2.37 +<p>Within this activity, certain topics are of interest:</p>
2.38 <ul>
2.39 <li><a href="paths.html">URLs and Paths</a></li>
2.40 <li><a href="methods.html">Request Methods</a></li>
2.41 <li><a href="parameters.html">Request Parameters and Uploads</a></li>
2.42 +</ul>
2.43 +<h2>Perform Actions</h2>
2.44 +<p>Of all activities summarised above, this is the most vague because
2.45 +the kinds of actions performed by applications will vary substantially
2.46 +depending on what the application is supposed to do. Indeed, it is
2.47 +within this activity that most applications will probably be integrated
2.48 +with other systems - they may access databases or Web services, for
2.49 +example.</p>
2.50 +<p>WebStack does not mandate any particular style of integration with
2.51 +other systems. It is generally recommended that developers use
2.52 +whichever Python modules or packages they prefer and just to import
2.53 +these into their applications. See <a href="integrating.html">"Integrating
2.54 +with Other Systems"</a> for advice on this subject.</p>
2.55 +<h2>Produce a Response</h2>
2.56 +<p>This activity was briefly covered in the <code>MyApplication</code>
2.57 +example, but for "real world" applications the following topics must be
2.58 +understood in more detail:</p>
2.59 +<ul>
2.60 <li><a href="responses.html">Responses and Presentation</a></li>
2.61 <li><a href="state.html">Cookies, Sessions and Persistent
2.62 Information</a></li>
3.1 --- a/docs/index.html Mon Apr 25 22:03:10 2005 +0000
3.2 +++ b/docs/index.html Mon Apr 25 22:04:02 2005 +0000
3.3 @@ -8,7 +8,7 @@
3.4 </head>
3.5 <body>
3.6 <h1>Creating Web Applications with WebStack</h1>
3.7 -<p>This set of documents describes the process of making a Web
3.8 +<p>This introductory guide describes the process of making a Web
3.9 application
3.10 using the WebStack framework.</p>
3.11 <h2>Setting Up</h2>
3.12 @@ -27,11 +27,25 @@
3.13 sure
3.14 that the <code>WebStack-0.9</code> directory sits on your
3.15 <code>PYTHONPATH</code>.</p>
3.16 +<h2>Generating the API Documentation</h2>
3.17 +<p>In order to view the API documentation in conjunction with this
3.18 +guide, it is necessary to generate some Web pages from the Python
3.19 +source code. For this, the <a href="http://epydoc.sourceforge.net/">epydoc</a>
3.20 +application must be available on your system. Then, change into
3.21 +the <code>WebStack-0.9</code> directory and run the <code>apidocs.sh</code>
3.22 +tool script as follows:</p>
3.23 +<pre>cd WebStack-0.9<br />./tools/apidocs.sh</pre>
3.24 +<p>Some warnings may be generated by the script, but the result should
3.25 +be a new <code>apidocs</code> directory within the <code>WebStack-0.9</code>
3.26 +directory. Of course, it is always possible to view documentation
3.27 +within Python by importing modules (such as <code>WebStack.Generic</code>)
3.28 +and using Python's built-in <code>help</code> function.</p>
3.29 <h2>About WebStack Applications</h2>
3.30 <ul>
3.31 <li><a href="anatomy.html">Anatomy of a WebStack Application</a></li>
3.32 <li><a href="securing.html">Securing a WebStack Application</a></li>
3.33 <li><a href="deploying.html">Deploying a WebStack Application</a></li>
3.34 + <li><a href="integrating.html">Integrating with Other Systems</a></li>
3.35 </ul>
3.36 </body>
3.37 </html>
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/docs/integrating.html Mon Apr 25 22:04:02 2005 +0000
4.3 @@ -0,0 +1,127 @@
4.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4.5 +<html xmlns="http://www.w3.org/1999/xhtml">
4.6 +<head>
4.7 + <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" />
4.8 + <title>Integrating with Other Systems</title>
4.9 + <meta name="generator"
4.10 + content="amaya 8.1a, see http://www.w3.org/Amaya/" />
4.11 + <link href="styles.css" rel="stylesheet" type="text/css" />
4.12 +</head>
4.13 +<body>
4.14 +<h1>Integrating with Other Systems</h1>
4.15 +<p>Most Web applications are not self-contained - instead of
4.16 +providing information which is written into the application
4.17 +code itself, they may often access data from other places or even
4.18 +communicate with other systems. Since applications may be very
4.19 +different in the way that they access external systems or the way
4.20 +in which they obtain external information, WebStack does not mandate
4.21 +rigid mechanisms for hooking into such systems or loading such
4.22 +information. Instead, it is recommended that applications import
4.23 +packages and modules which provide the functionality necessary to carry
4.24 +out such integration.</p>
4.25 +<h2>Examples of Packages</h2>
4.26 +<p>Examples of packages and modules that might be used for integration
4.27 +purposes include the following:</p>
4.28 +<ul>
4.29 + <li>Database access packages, including object-relational mappers.</li>
4.30 + <li>Communications libraries - for connecting to Web services or
4.31 +other remote services, for example.</li>
4.32 + <li>Templating or reporting systems. (Note that templating systems
4.33 +are also very useful when generating <a href="responses.html">responses</a>.)</li>
4.34 +</ul>
4.35 +<h2> Using External Packages</h2>
4.36 +<p>In the simplest of cases, the use of external packages is as
4.37 +straightforward as importing a Python module (or package) and then
4.38 +using that module's contents. This can often be done in the <a
4.39 + href="resources.html">resource</a> code; for example:</p>
4.40 +<pre>import urllib<br /><br />class MyResource:<br /> def respond(self, trans):<br /> [Examine the transaction, decide what the user wants to do.]<br /><br /> f = urllib.urlopen("http://www.boddie.org.uk/rss/feed.xml")<br /><br /> [Produce some kind of response which tells the user what happened.]</pre>
4.41 +<p>In the above example, here is what happens:</p>
4.42 +<table style="text-align: left; width: 80%;" align="center" border="1"
4.43 + cellpadding="5" cellspacing="0">
4.44 + <tbody>
4.45 + <tr>
4.46 + <th>What we do</th>
4.47 + <th>Where it happens and how often</th>
4.48 + </tr>
4.49 + <tr>
4.50 + <td align="undefined" valign="undefined"> Import <code>urllib</code>
4.51 +to gain access to functionality which we can then use to access a
4.52 +remote service.</td>
4.53 + <td align="undefined" valign="undefined">This happens once - when
4.54 +the above code is itself imported into Python.</td>
4.55 + </tr>
4.56 + <tr>
4.57 + <td align="undefined" valign="undefined">Use the <code>urlopen</code>
4.58 +function of <code>urllib</code> to actually access a remote service.</td>
4.59 + <td align="undefined" valign="undefined">This happens in the
4.60 +resource code each time the resource decides to access the service.</td>
4.61 + </tr>
4.62 + </tbody>
4.63 +</table>
4.64 +<p>In this case, the functionality is relatively easy to acquire and
4.65 +does not require any initialisation. But what if we were connecting to
4.66 +a database? There might be a need to specially initialise the database
4.67 +module - only once, though - and then repeatedly use it. Consider this
4.68 +highly artificial example:</p>
4.69 +<pre>import mydb<br /><br />connection = mydb.connect("me", "myPassword")<br /><br />class MyResource:<br /> def respond(self, trans):<br /> [Examine the transaction, decide what the user wants to do.]<br /><br /> results = connection.query("feed", owner="boddie.org.uk")<br /><br /> [Produce some kind of response which tells the user what happened.]
4.70 +</pre>
4.71 +<p>In the above example, here is what happens:</p>
4.72 +<table style="text-align: left; width: 80%;" align="center" border="1"
4.73 + cellpadding="5" cellspacing="0">
4.74 + <tbody>
4.75 + <tr>
4.76 + <th>What we do</th>
4.77 + <th>Where it happens and how often</th>
4.78 + </tr>
4.79 + <tr>
4.80 + <td align="undefined" valign="undefined">Import the <code>mydb</code>
4.81 +module to gain access to database access functionality.</td>
4.82 + <td align="undefined" valign="undefined">This happens once - when
4.83 +the above code is itself imported into Python.</td>
4.84 + </tr>
4.85 + <tr>
4.86 + <td align="undefined" valign="undefined">Initialise a database
4.87 +connection using the <code>connect</code> function from the <code>mydb</code>
4.88 +module.</td>
4.89 + <td align="undefined" valign="undefined">This also happens only
4.90 +once - when the above code is itself imported into Python.</td>
4.91 + </tr>
4.92 + <tr>
4.93 + <td align="undefined" valign="undefined">Use the <code>query</code>
4.94 +method on the connection object to access a database.</td>
4.95 + <td align="undefined" valign="undefined">This happens in the
4.96 +resource code each time the resource decides to access the database.</td>
4.97 + </tr>
4.98 + </tbody>
4.99 +</table>
4.100 +<p>The choice of initialising the connection may seem arbitrary - why
4.101 +not just obtain a connection in the resource? Usually, such decisions
4.102 +are made on the basis of efficiency and on constraints outside the
4.103 +control of the application - some database systems limit the number of
4.104 +connections, for example, and if a large number of resources suddenly
4.105 +became active, some of them would fail to obtain connections if the
4.106 +connection initialisation code were in the <code>respond</code>
4.107 +method of the resource.</p>
4.108 +<h2>Configuring Packages Globally</h2>
4.109 +<p>Of course, the above resource might not be the only resource to use
4.110 +database connections. It might then be tempting to initialise a
4.111 +connection for each module whose resource needs (or, since as normal
4.112 +Python classes we can put many resources in a single module, whose
4.113 +resources need) to access a database. But it would surely be more
4.114 +convenient to define a single, central place to hold such global
4.115 +resources.</p>
4.116 +<p>One approach is to define a module which can be accessed by all
4.117 +modules, and thus by all resources. Let us create such a module in the
4.118 +file <code>Properties.py</code> which will reside alongside <code>MyApplication.py</code>
4.119 +(or whatever the application module is called). Inside the <code>Properties</code>
4.120 +module we can write the following code:</p>
4.121 +<pre>import mydb<br /><br />connection = mydb.connect("me", "myPassword")</pre>
4.122 +<p>Now, in each module containing resources which need to access the
4.123 +database, all we need to do now is to import the <code>Properties</code>
4.124 +module and to use the connection as defined in that module:</p>
4.125 +<pre>import Properties<br /><br />class MyResource:<br /> def respond(self, trans):<br /> [Examine the transaction, decide what the user wants to do.]<br /><br /> results = Properties.connection.query("feed", owner="boddie.org.uk")<br /><br /> [Produce some kind of response which tells the user what happened.]</pre>
4.126 +<p>This is a very simple approach that is technically outclassed by the
4.127 +mechanisms available in some frameworks. Currently, WebStack does not
4.128 +provide access to those more sophisticated mechanisms, however.</p>
4.129 +</body>
4.130 +</html>
5.1 --- a/docs/responses.html Mon Apr 25 22:03:10 2005 +0000
5.2 +++ b/docs/responses.html Mon Apr 25 22:04:02 2005 +0000
5.3 @@ -1,84 +1,86 @@
5.4 -<?xml version="1.0" encoding="iso-8859-1"?>
5.5 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5.6 - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5.7 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5.8 <html xmlns="http://www.w3.org/1999/xhtml">
5.9 <head>
5.10 <title>Responses and Presentation</title>
5.11 - <meta name="generator" content="amaya 8.1a, see http://www.w3.org/Amaya/" />
5.12 + <meta name="generator"
5.13 + content="amaya 8.1a, see http://www.w3.org/Amaya/" />
5.14 <link href="styles.css" rel="stylesheet" type="text/css" />
5.15 </head>
5.16 -
5.17 <body>
5.18 <h1>Responses and Presentation</h1>
5.19 -
5.20 -<p>After performing some kind of processing on input information, an
5.21 -application will then want to produce some kind of response to indicate what
5.22 +<p>After performing some kind of
5.23 +processing on input information, an
5.24 +application will then want to produce some kind of response to indicate
5.25 +what
5.26 went on. Here are some examples of responses:</p>
5.27 <ul>
5.28 - <li>Returning the contents of a requested file.</li>
5.29 - <li>Showing a message telling the user that the requested operation
5.30 - succeeded or failed.</li>
5.31 - <li>Presenting a view onto the application with the results of the recent
5.32 - activity shown in a Web page.</li>
5.33 + <li>Returning the contents of a
5.34 +requested file.</li>
5.35 + <li>Showing a message telling
5.36 +the user that the requested operation succeeded or failed.</li>
5.37 + <li>Presenting a view onto the
5.38 +application with the results of the recent activity shown in a Web page.</li>
5.39 </ul>
5.40 -
5.41 <h2>Generating Responses</h2>
5.42 -
5.43 -<p>The procedure involved in generating a response usually involves the
5.44 +<p>The procedure involved in
5.45 +generating a response usually involves the
5.46 following steps:</p>
5.47 <ol>
5.48 - <li>Setting a response code to signal whether the application performed the
5.49 - requested operation successfully.</li>
5.50 - <li>Setting a content type and a <a>character encoding</a>.</li>
5.51 - <li>Producing content and sending it to the user.</li>
5.52 + <li>Setting a response code to
5.53 +signal whether the application performed the requested operation
5.54 +successfully.</li>
5.55 + <li>Setting a content type and a
5.56 + <a>character encoding</a>.</li>
5.57 + <li>Producing content and
5.58 +sending it to the user.</li>
5.59 </ol>
5.60 -
5.61 -<p>The kind of code involved may well resemble the following:</p>
5.62 -<pre>from WebStack.Generic import ContentType
5.63 -
5.64 -class MyResource:
5.65 - def respond(self, trans):
5.66 - [Perform the requested operations.]
5.67 -
5.68 - if [the operation was successful]:
5.69 - trans.set_response_code(200)
5.70 - trans.set_content_type(ContentType("text/html", encoding="utf-8"))
5.71 - out = trans.get_response_stream()
5.72 - out.write([some data either as a plain string suitably encoded or as Unicode])
5.73 - else:
5.74 - trans.set_response_code(500) # or some other code
5.75 - trans.set_content_type(ContentType("text/html", encoding="utf-8"))
5.76 - out = trans.get_response_stream()
5.77 - out.write([some other data either as a plain string suitably encoded or as Unicode])</pre>
5.78 -
5.79 -<p>As discussed in <a href="encodings.html">"Character Encodings"</a>, care
5.80 -must be taken generating the response so that it meets any expectations that
5.81 +<p>The kind of code involved may
5.82 +well resemble the following:</p>
5.83 +<pre>from WebStack.Generic import ContentType<br /><br />class MyResource:<br /> def respond(self, trans):<br /> [Perform the requested operations.]<br /><br /> if [the operation was successful]:<br /> trans.set_response_code(200)<br /> trans.set_content_type(ContentType("text/html", encoding="utf-8"))<br /> out = trans.get_response_stream()<br /> out.write([some data either as a plain string suitably encoded or as Unicode])<br /> else:<br /> trans.set_response_code(500) # or some other code<br /> trans.set_content_type(ContentType("text/html", encoding="utf-8"))<br /> out = trans.get_response_stream()<br /> out.write([some other data either as a plain string suitably encoded or as Unicode])</pre>
5.84 +<p>As discussed in <a href="encodings.html">"Character Encodings"</a>,
5.85 +care
5.86 +must be taken generating the response so that it meets any expectations
5.87 +that
5.88 browsers and other Web clients may have.</p>
5.89 -
5.90 <div class="WebStack">
5.91 -<h3>WebStack API - Response-Related Methods</h3>
5.92 -
5.93 -<p>Transaction objects have various methods that can be used in generating
5.94 +<h3>WebStack API -
5.95 +Response-Related Methods</h3>
5.96 +<p>Transaction objects have
5.97 +various methods that can be used in generating
5.98 responses:</p>
5.99 <dl>
5.100 <dt><code>set_response_code</code></dt>
5.101 - <dd>This accepts an integer value denoting the response condition as
5.102 - described in the HTTP specification. If this method is not used,
5.103 - WebStack sets a <code>200</code> status condition on the response,
5.104 - meaning that the request was processed successfully.</dd>
5.105 + <dd>This accepts an integer
5.106 +value denoting the response condition as described in the HTTP
5.107 +specification. If this method is not used, WebStack sets a <code>200</code>
5.108 +status condition on the response, meaning that the request was
5.109 +processed successfully.</dd>
5.110 <dt><code>set_content_type</code></dt>
5.111 - <dd>This accepts a content type object (typically
5.112 - <code>WebStack.Generic.ContentType</code>) which specifies both the
5.113 - media type and the character encoding (if relevant) of the data sent to
5.114 - the user. The media type describes the format of the data (eg.
5.115 - <code>text/html</code> - a Web page), whereas the character encoding
5.116 - describes how any character information on the page is encoded - see <a
5.117 - href="encodings.html">"Character Encodings"</a> for more
5.118 - information.</dd>
5.119 + <dd>This accepts a content type
5.120 +object (typically <code>WebStack.Generic.ContentType</code>)
5.121 +which specifies both the media type and the character encoding (if
5.122 +relevant) of the data sent to the user. The media type describes the
5.123 +format of the data (eg. <code>text/html</code>
5.124 +- a Web page), whereas the character encoding describes how any
5.125 +character information on the page is encoded - see <a
5.126 + href="encodings.html">"Character Encodings"</a>
5.127 +for more information.</dd>
5.128 <dt><code>get_response_stream</code></dt>
5.129 - <dd>This returns the output stream through which data may be sent to the
5.130 - user.</dd>
5.131 + <dd>This returns the output
5.132 +stream through which data may be sent to the user.</dd>
5.133 </dl>
5.134 </div>
5.135 +<h2>Integrating with Content Generators</h2>
5.136 +<p>Just as applications might need to integrate with other systems in
5.137 +order to fetch information or to perform operations on behalf of the
5.138 +user, the generation of response content can also be made a lot easier
5.139 +by using external libraries. In the above example code, the process of
5.140 +obtaining and formatting the actual data to be written out has been
5.141 +left unspecified, but for anything more complicated than "hello world"
5.142 +it is usually advisable to consider using templating systems which
5.143 +combine raw data and templates to produce formatted output that can be
5.144 +displayed as a Web page (amongst other things).</p>
5.145 +<p>See <a href="integrating.html">"Integration with Other Systems"</a>
5.146 +for more information on the principles of using such external libraries.</p>
5.147 </body>
5.148 </html>