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 12 <p>Most Web applications are not self-contained - instead of providing 13 information which is written into the application code itself, they may often 14 access data from other places or even communicate with other systems. Since 15 applications may be very different in the way that they access external systems 16 or the way in which they obtain external information, WebStack does not mandate 17 a single mechanism for hooking into such systems or loading such information. 18 Instead, it is recommended that applications import packages and modules which 19 provide the functionality necessary to carry out such integration, using the 20 appropriate conveniences (such as <a href="selectors.html">selector 21 resources</a>) to manage that functionality where appropriate.</p> 22 23 <h2>Examples of Packages</h2> 24 25 <p>Examples of packages and modules that might be used for integration purposes 26 include the following:</p> 27 28 <ul> 29 <li>Database access packages, including object-relational mappers.</li> 30 <li>Communications libraries - for connecting to Web services or other remote 31 services, for example.</li> 32 <li>Templating or reporting systems. (Note that templating systems are also 33 very useful when generating <a href="responses.html">responses</a>.)</li> 34 </ul> 35 36 <h2>Using External Packages in General</h2> 37 38 <p>In the simplest of cases, the use of external packages is as straightforward 39 as importing a Python module (or package) and then using that module's 40 contents. This can often be done in the <a href="resources.html">resource</a> 41 code; for example:</p> 42 43 <pre> 44 import urllib 45 46 class MyResource: 47 def respond(self, trans): 48 [Examine the transaction, decide what the user wants to do.] 49 50 f = urllib.urlopen("http://www.boddie.org.uk/rss/feed.xml") 51 52 [Produce some kind of response which tells the user what happened.] 53 </pre> 54 55 <p>In the above example, here is what happens:</p> 56 57 <table style="text-align: left; width: 80%;" align="center" border="1" 58 cellpadding="5" cellspacing="0"> 59 <tbody> 60 <tr> 61 <th>What we do</th> 62 <th>Where it happens and how often</th> 63 </tr> 64 <tr> 65 <td>Import <code>urllib</code> to gain access to functionality which we 66 can then use to access a remote service.</td> 67 <td>This happens once - when the above code is itself imported into 68 Python.</td> 69 </tr> 70 <tr> 71 <td>Use the <code>urlopen</code> function of <code>urllib</code> to 72 actually access a remote service.</td> 73 <td>This happens in the resource code each time the resource decides to 74 access the service.</td> 75 </tr> 76 </tbody> 77 </table> 78 79 <h2>Using Database Connections</h2> 80 81 <p>In the above case, the functionality is relatively easy to acquire and does not 82 require any initialisation. But what if we were connecting to a database? There 83 might be a need to specially initialise the database module - only once, though 84 - and then repeatedly use it. Moreover, we may want to ensure that any 85 transactions created as our resources run are terminated when the resources 86 have themselves completed their work. At this point, it is worth considering 87 the <code>StoreSelector</code> class, as described in the <a 88 href="selectors.html">"Selectors - Components for Dispatching to 89 Resources"</a> document. Consider this example:</p> 90 91 <pre> 92 from WebStack.Resources.Selectors import StoreSelector 93 94 class MyResource: 95 def respond(self, trans): 96 [Examine the transaction, decide what the user wants to do.] 97 98 connection = trans.get_attributes()["store"] 99 cursor = connection.cursor() 100 try: 101 cursor.execute("select url from feeds where owner=?", ["boddie.org.uk"]) 102 results = cursor.fetchall() 103 finally: 104 cursor.close() 105 106 [Produce some kind of response which tells the user what happened.] 107 108 def get_site_map(connection): 109 return StoreSelector(MyResource(), connection) 110 </pre> 111 112 <p>The initialisation would be done elsewhere, perhaps in the same module:</p> 113 114 <pre> 115 import mydb 116 117 connection = mydb.connect("me", "myPassword") 118 try: 119 site = get_site_map(connection) 120 deploy(site) 121 finally: 122 connection.close() 123 </pre> 124 125 <p>In the above example, here is what happens:</p> 126 127 <table style="text-align: left; width: 80%;" align="center" border="1" 128 cellpadding="5" cellspacing="0"> 129 <tbody> 130 <tr> 131 <th>What we do</th> 132 <th>Where it happens and how often</th> 133 </tr> 134 <tr> 135 <td>Import the <code>mydb</code> module to gain access to database access functionality.</td> 136 <td>This happens once - when the above code is itself imported into Python.</td> 137 </tr> 138 <tr> 139 <td>Initialise a database connection using the <code>connect</code> function from the <code>mydb</code> module.</td> 140 <td>This also happens only once - when the above code is itself imported into Python.</td> 141 </tr> 142 <tr> 143 <td>Wrap the application in a <code>StoreSelector</code> which manages 144 the database connection.</td> 145 <td>This happens in the <code>get_site_map</code> function which 146 prepares the application before deployment.</td> 147 </tr> 148 <tr> 149 <td>Make the connection available in a transaction object.</td> 150 <td>This happens <strong>automatically</strong> for every incoming transaction or request to access the 151 application - it is managed by the <code>StoreSelector</code> object.</td> 152 </tr> 153 <tr> 154 <td>Obtain the connection from the attributes on the transaction object; 155 use the <code>cursor</code> method on the connection object to access 156 the database; use the methods on the cursor object.</td> 157 <td>This happens in the resource code each time the resource decides to 158 access the database.</td> 159 </tr> 160 <tr> 161 <td>Terminate the active transaction on the connection object.</td> 162 <td>This happens <strong>automatically</strong> for every completed transaction or request to access the 163 application - it is managed by the <code>StoreSelector</code> object.</td> 164 </tr> 165 <tr> 166 <td>Close the database connection using the <code>close</code> method on 167 the connection object.</td> 168 <td>This also happens only once - when the application is 169 terminating.</td> 170 </tr> 171 </tbody> 172 </table> 173 174 <p>The choice of initialising the connection may seem arbitrary - why not just 175 obtain a connection in the resource? Usually, such decisions are made on the 176 basis of efficiency and on constraints outside the control of the application - 177 some database systems limit the number of connections, for example, and if a 178 large number of resources suddenly became active, some of them would fail to 179 obtain connections if the connection initialisation code were in the 180 <code>respond</code> method of the resource. Moreover, by using the 181 <code>StoreSelector</code>, a certain amount of "boilerplate" code can be 182 hidden away and not written within each resource.</p> 183 184 </body> 185 </html>