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 information which is written into the application 14 code itself, they may often access data from other places or even 15 communicate with other systems. Since applications may be very 16 different 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 <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 <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 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 <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>