1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/docs/integrating.html Mon Apr 25 22:04:02 2005 +0000
1.3 @@ -0,0 +1,127 @@
1.4 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
1.5 +<html xmlns="http://www.w3.org/1999/xhtml">
1.6 +<head>
1.7 + <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" />
1.8 + <title>Integrating with Other Systems</title>
1.9 + <meta name="generator"
1.10 + content="amaya 8.1a, see http://www.w3.org/Amaya/" />
1.11 + <link href="styles.css" rel="stylesheet" type="text/css" />
1.12 +</head>
1.13 +<body>
1.14 +<h1>Integrating with Other Systems</h1>
1.15 +<p>Most Web applications are not self-contained - instead of
1.16 +providing information which is written into the application
1.17 +code itself, they may often access data from other places or even
1.18 +communicate with other systems. Since applications may be very
1.19 +different in the way that they access external systems or the way
1.20 +in which they obtain external information, WebStack does not mandate
1.21 +rigid mechanisms for hooking into such systems or loading such
1.22 +information. Instead, it is recommended that applications import
1.23 +packages and modules which provide the functionality necessary to carry
1.24 +out such integration.</p>
1.25 +<h2>Examples of Packages</h2>
1.26 +<p>Examples of packages and modules that might be used for integration
1.27 +purposes include the following:</p>
1.28 +<ul>
1.29 + <li>Database access packages, including object-relational mappers.</li>
1.30 + <li>Communications libraries - for connecting to Web services or
1.31 +other remote services, for example.</li>
1.32 + <li>Templating or reporting systems. (Note that templating systems
1.33 +are also very useful when generating <a href="responses.html">responses</a>.)</li>
1.34 +</ul>
1.35 +<h2> Using External Packages</h2>
1.36 +<p>In the simplest of cases, the use of external packages is as
1.37 +straightforward as importing a Python module (or package) and then
1.38 +using that module's contents. This can often be done in the <a
1.39 + href="resources.html">resource</a> code; for example:</p>
1.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>
1.41 +<p>In the above example, here is what happens:</p>
1.42 +<table style="text-align: left; width: 80%;" align="center" border="1"
1.43 + cellpadding="5" cellspacing="0">
1.44 + <tbody>
1.45 + <tr>
1.46 + <th>What we do</th>
1.47 + <th>Where it happens and how often</th>
1.48 + </tr>
1.49 + <tr>
1.50 + <td align="undefined" valign="undefined"> Import <code>urllib</code>
1.51 +to gain access to functionality which we can then use to access a
1.52 +remote service.</td>
1.53 + <td align="undefined" valign="undefined">This happens once - when
1.54 +the above code is itself imported into Python.</td>
1.55 + </tr>
1.56 + <tr>
1.57 + <td align="undefined" valign="undefined">Use the <code>urlopen</code>
1.58 +function of <code>urllib</code> to actually access a remote service.</td>
1.59 + <td align="undefined" valign="undefined">This happens in the
1.60 +resource code each time the resource decides to access the service.</td>
1.61 + </tr>
1.62 + </tbody>
1.63 +</table>
1.64 +<p>In this case, the functionality is relatively easy to acquire and
1.65 +does not require any initialisation. But what if we were connecting to
1.66 +a database? There might be a need to specially initialise the database
1.67 +module - only once, though - and then repeatedly use it. Consider this
1.68 +highly artificial example:</p>
1.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.]
1.70 +</pre>
1.71 +<p>In the above example, here is what happens:</p>
1.72 +<table style="text-align: left; width: 80%;" align="center" border="1"
1.73 + cellpadding="5" cellspacing="0">
1.74 + <tbody>
1.75 + <tr>
1.76 + <th>What we do</th>
1.77 + <th>Where it happens and how often</th>
1.78 + </tr>
1.79 + <tr>
1.80 + <td align="undefined" valign="undefined">Import the <code>mydb</code>
1.81 +module to gain access to database access functionality.</td>
1.82 + <td align="undefined" valign="undefined">This happens once - when
1.83 +the above code is itself imported into Python.</td>
1.84 + </tr>
1.85 + <tr>
1.86 + <td align="undefined" valign="undefined">Initialise a database
1.87 +connection using the <code>connect</code> function from the <code>mydb</code>
1.88 +module.</td>
1.89 + <td align="undefined" valign="undefined">This also happens only
1.90 +once - when the above code is itself imported into Python.</td>
1.91 + </tr>
1.92 + <tr>
1.93 + <td align="undefined" valign="undefined">Use the <code>query</code>
1.94 +method on the connection object to access a database.</td>
1.95 + <td align="undefined" valign="undefined">This happens in the
1.96 +resource code each time the resource decides to access the database.</td>
1.97 + </tr>
1.98 + </tbody>
1.99 +</table>
1.100 +<p>The choice of initialising the connection may seem arbitrary - why
1.101 +not just obtain a connection in the resource? Usually, such decisions
1.102 +are made on the basis of efficiency and on constraints outside the
1.103 +control of the application - some database systems limit the number of
1.104 +connections, for example, and if a large number of resources suddenly
1.105 +became active, some of them would fail to obtain connections if the
1.106 +connection initialisation code were in the <code>respond</code>
1.107 +method of the resource.</p>
1.108 +<h2>Configuring Packages Globally</h2>
1.109 +<p>Of course, the above resource might not be the only resource to use
1.110 +database connections. It might then be tempting to initialise a
1.111 +connection for each module whose resource needs (or, since as normal
1.112 +Python classes we can put many resources in a single module, whose
1.113 +resources need) to access a database. But it would surely be more
1.114 +convenient to define a single, central place to hold such global
1.115 +resources.</p>
1.116 +<p>One approach is to define a module which can be accessed by all
1.117 +modules, and thus by all resources. Let us create such a module in the
1.118 +file <code>Properties.py</code> which will reside alongside <code>MyApplication.py</code>
1.119 +(or whatever the application module is called). Inside the <code>Properties</code>
1.120 +module we can write the following code:</p>
1.121 +<pre>import mydb<br /><br />connection = mydb.connect("me", "myPassword")</pre>
1.122 +<p>Now, in each module containing resources which need to access the
1.123 +database, all we need to do now is to import the <code>Properties</code>
1.124 +module and to use the connection as defined in that module:</p>
1.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>
1.126 +<p>This is a very simple approach that is technically outclassed by the
1.127 +mechanisms available in some frameworks. Currently, WebStack does not
1.128 +provide access to those more sophisticated mechanisms, however.</p>
1.129 +</body>
1.130 +</html>