WebStack

docs/integrating.html

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