WebStack

docs/integrating.html

401:ca2a40e20036
2005-07-16 paulb [project @ 2005-07-16 20:32:56 by paulb] Enhanced the PYTHONPATH handling to respect the existing definition.
     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">     2 <html xmlns="http://www.w3.org/1999/xhtml">     3 <head>     4   <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type" />     5   <title>Integrating with Other Systems</title>     6   <meta name="generator"     7  content="amaya 8.1a, see http://www.w3.org/Amaya/" />     8   <link href="styles.css" rel="stylesheet" type="text/css" />     9 </head>    10 <body>    11 <h1>Integrating with Other Systems</h1>    12 <p>Most Web applications are not self-contained - instead of    13 providing&nbsp;information which is&nbsp;written into the application    14 code itself,&nbsp;they may often access data from other places or even    15 communicate with other systems. Since applications may be very    16 different&nbsp;in the way that they access external systems or the way    17 in which they obtain external information, WebStack does not mandate    18 rigid mechanisms for hooking into such systems or loading such    19 information. Instead, it is recommended that applications import    20 packages and modules which provide the functionality necessary to carry    21 out such integration.</p>    22 <h2>Examples of Packages</h2>    23 <p>Examples of packages and modules that might be used for integration    24 purposes include the following:</p>    25 <ul>    26   <li>Database access packages, including object-relational mappers.</li>    27   <li>Communications libraries - for connecting to Web services or    28 other remote services, for example.</li>    29   <li>Templating or reporting systems. (Note that templating systems    30 are also very useful when generating <a href="responses.html">responses</a>.)</li>    31 </ul>    32 <h2> Using External Packages</h2>    33 <p>In the simplest of cases, the use of external packages is as    34 straightforward as importing a Python module (or package) and then    35 using that module's contents. This can often be done in the <a    36  href="resources.html">resource</a> code; for example:</p>    37 <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>    38 <p>In the above example, here is what happens:</p>    39 <table style="text-align: left; width: 80%;" align="center" border="1"    40  cellpadding="5" cellspacing="0">    41   <tbody>    42     <tr>    43       <th>What we do</th>    44       <th>Where it happens and how often</th>    45     </tr>    46     <tr>    47       <td align="undefined" valign="undefined"> Import <code>urllib</code>    48 to gain access to functionality which we can then use to access a    49 remote service.</td>    50       <td align="undefined" valign="undefined">This happens once - when    51 the above code is itself imported into Python.</td>    52     </tr>    53     <tr>    54       <td align="undefined" valign="undefined">Use the&nbsp;<code>urlopen</code>    55 function of <code>urllib</code> to actually access a remote service.</td>    56       <td align="undefined" valign="undefined">This happens in the    57 resource code each time the resource decides to access the service.</td>    58     </tr>    59   </tbody>    60 </table>    61 <p>In this case, the functionality is relatively easy to acquire and    62 does not require any initialisation. But what if we were connecting to    63 a database? There might be a need to specially initialise the database    64 module - only once, though - and then repeatedly use it. Consider this    65 highly artificial example:</p>    66 <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.]    67 </pre>    68 <p>In the above example, here is what happens:</p>    69 <table style="text-align: left; width: 80%;" align="center" border="1"    70  cellpadding="5" cellspacing="0">    71   <tbody>    72     <tr>    73       <th>What we do</th>    74       <th>Where it happens and how often</th>    75     </tr>    76     <tr>    77       <td align="undefined" valign="undefined">Import the <code>mydb</code>    78 module to gain access to database access functionality.</td>    79       <td align="undefined" valign="undefined">This happens once - when    80 the above code is itself imported into Python.</td>    81     </tr>    82     <tr>    83       <td align="undefined" valign="undefined">Initialise a database    84 connection using the <code>connect</code> function from the <code>mydb</code>    85 module.</td>    86       <td align="undefined" valign="undefined">This also happens only    87 once - when the above code is itself imported into Python.</td>    88     </tr>    89     <tr>    90       <td align="undefined" valign="undefined">Use the <code>query</code>    91 method on the connection object to access a database.</td>    92       <td align="undefined" valign="undefined">This happens in the    93 resource code each time the resource decides to access the database.</td>    94     </tr>    95   </tbody>    96 </table>    97 <p>The choice of initialising the connection may seem arbitrary - why    98 not just obtain a connection in the resource? Usually, such decisions    99 are made on the basis of efficiency and on constraints outside the   100 control of the application - some database systems limit the number of   101 connections, for example, and if a large number of resources suddenly   102 became active, some of them would fail to obtain connections if the   103 connection initialisation code were in the&nbsp;<code>respond</code>   104 method of the resource.</p>   105 <h2>Configuring Packages Globally</h2>   106 <p>Of course, the above resource might not be the only resource to use   107 database connections. It might then be tempting to initialise a   108 connection for each module whose resource needs (or, since as normal   109 Python classes we can put many resources in a single module, whose   110 resources need) to access a database. But it would surely be&nbsp;more   111 convenient to define a single, central place to hold such global   112 resources.</p>   113 <p>One approach is to define a module which can be accessed by all   114 modules, and thus by all resources. Let us create such a module in the   115 file <code>Properties.py</code> which will reside alongside <code>MyApplication.py</code>   116 (or whatever the application module is called). Inside the&nbsp;<code>Properties</code>   117 module we can write the following code:</p>   118 <pre>import mydb<br /><br />connection = mydb.connect("me", "myPassword")</pre>   119 <p>Now, in each module containing resources which need to access the   120 database, all we need to do now is to import the <code>Properties</code>   121 module and to use the connection as defined in that module:</p>   122 <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>   123 <p>This is a very simple approach that is technically outclassed by the   124 mechanisms available in some frameworks. Currently, WebStack does not   125 provide access to those more sophisticated mechanisms, however.</p>   126 </body>   127 </html>