Integrating with Other Systems

Most Web applications are not self-contained - instead of providing information which is written into the application code itself, they may often access data from other places or even communicate with other systems. Since applications may be very different in the way that they access external systems or the way in which they obtain external information, WebStack does not mandate rigid mechanisms for hooking into such systems or loading such information. Instead, it is recommended that applications import packages and modules which provide the functionality necessary to carry out such integration.

Examples of Packages

Examples of packages and modules that might be used for integration purposes include the following:

Using External Packages

In the simplest of cases, the use of external packages is as straightforward as importing a Python module (or package) and then using that module's contents. This can often be done in the resource code; for example:

import urllib

class MyResource:
def respond(self, trans):
[Examine the transaction, decide what the user wants to do.]

f = urllib.urlopen("http://www.boddie.org.uk/rss/feed.xml")

[Produce some kind of response which tells the user what happened.]

In the above example, here is what happens:

What we do Where it happens and how often
Import urllib to gain access to functionality which we can then use to access a remote service. This happens once - when the above code is itself imported into Python.
Use the urlopen function of urllib to actually access a remote service. This happens in the resource code each time the resource decides to access the service.

In this case, the functionality is relatively easy to acquire and does not require any initialisation. But what if we were connecting to a database? There might be a need to specially initialise the database module - only once, though - and then repeatedly use it. Consider this highly artificial example:

import mydb

connection = mydb.connect("me", "myPassword")

class MyResource:
def respond(self, trans):
[Examine the transaction, decide what the user wants to do.]

results = connection.query("feed", owner="boddie.org.uk")

[Produce some kind of response which tells the user what happened.]

In the above example, here is what happens:

What we do Where it happens and how often
Import the mydb module to gain access to database access functionality. This happens once - when the above code is itself imported into Python.
Initialise a database connection using the connect function from the mydb module. This also happens only once - when the above code is itself imported into Python.
Use the query method on the connection object to access a database. This happens in the resource code each time the resource decides to access the database.

The choice of initialising the connection may seem arbitrary - why not just obtain a connection in the resource? Usually, such decisions are made on the basis of efficiency and on constraints outside the control of the application - some database systems limit the number of connections, for example, and if a large number of resources suddenly became active, some of them would fail to obtain connections if the connection initialisation code were in the respond method of the resource.

Configuring Packages Globally

Of course, the above resource might not be the only resource to use database connections. It might then be tempting to initialise a connection for each module whose resource needs (or, since as normal Python classes we can put many resources in a single module, whose resources need) to access a database. But it would surely be more convenient to define a single, central place to hold such global resources.

One approach is to define a module which can be accessed by all modules, and thus by all resources. Let us create such a module in the file Properties.py which will reside alongside MyApplication.py (or whatever the application module is called). Inside the Properties module we can write the following code:

import mydb

connection = mydb.connect("me", "myPassword")

Now, in each module containing resources which need to access the database, all we need to do now is to import the Properties module and to use the connection as defined in that module:

import Properties

class MyResource:
def respond(self, trans):
[Examine the transaction, decide what the user wants to do.]

results = Properties.connection.query("feed", owner="boddie.org.uk")

[Produce some kind of response which tells the user what happened.]

This is a very simple approach that is technically outclassed by the mechanisms available in some frameworks. Currently, WebStack does not provide access to those more sophisticated mechanisms, however.