From: Ken L. <ke...@to...> - 2001-10-24 14:46:56
|
Thanks for your comments, Clark. I'd argue for putting Application.getDbConnection() in the core as follows: - putting it in SitePage makes it inaccessible to code that doesn't subclass SitePage. For example, I keep WebKit session data in a postgresql database, and the code to implement that is unrelated to SitePage. The pool is logically part of the application, not the Page servlet. - cleaning up DB connections at exit time is more awkward when subclassing SitePage. I guess you can do it with atexit, but it's messy, and some people won't bother. - it took me a little fiddling around to figure out the best way to do pooling connections, and I imagine others will waste time reinventing the same thing. Providing an application-wide connection pool with proper cleanup at exit fills a very common developer need, and is appropriate for the core. > From: "Clark C . Evans" <cc...@cl...> > To: Ken Lalonde <ke...@to...> > Subject: Re: [Webware-discuss] A few patches > > Ken Lalonde wrote: > | * WebKit/Application.py: > | New method: getDbConnection() > > This is interesting, but I'm not sure that it should > be added to the core of WebKit since it is certainly > easy enough to add in one's SitePage.py > > Your other changes sound good. |
From: Jeff J. <je...@bo...> - 2001-10-24 19:06:35
|
> * WebKit/Application.py: > New method: getDbConnection(), which returns > a (pooled) database connection. > Requires 3 new Application.config settings, e.g.: > 'DbModule': 'PgSQL', # your fav DB-API v2.0 module > 'DbConnect':'::mydb:me', # DB connection string > 'DbConnections': 5, # concurrent connections > Connections in the pool are closed at application > shutdown, in the interest of database hygiene. > I prefer this method over Cans, because it's simpler, > it centralizes the DB stuff in one place, and it's the sort > of natural functionality WebKit should support out of the box. We connect to multiple databases. Can this be modified so that each database is given a data source name (DSN) and so getDbConnection takes the DSN as an argument? The config could look something like: 'dataSources': { 'billing': { 'DbModule': 'PgSQL', 'DbConnect': '::billing:me', 'DbConnections': 5, }, 'inventory': { 'DbModule': 'PgSQL', 'DbConnect': '::inventory:me', 'DbConnections': 5, }, }, And used like: dbB =3D app.getDbConnection('billing') dbI =3D app.getDbConnection('inventory') -Jeff |
From: Clark C . E. <cc...@cl...> - 2001-10-24 19:35:23
|
To meet my requirements (I dynamically create databases) the connection information can't be hard-coded. So if the function "getConnectInfo()" could be added, where this function returns the tuple (module,connect,no_conn) the default implementation of getConnectInfo() can read from the configuration file as Jeff has below. How then could I override the getConnectInfo? Clark On Wed, Oct 24, 2001 at 02:55:50PM -0400, Jeff Johnson wrote: | We connect to multiple databases. Can this be modified so that each | database is given a data source name (DSN) and so getDbConnection takes | the DSN as an argument? The config could look something like: | | 'dataSources': { | 'billing': { | 'DbModule': 'PgSQL', | 'DbConnect': '::billing:me', | 'DbConnections': 5, | }, | 'inventory': { | 'DbModule': 'PgSQL', | 'DbConnect': '::inventory:me', | 'DbConnections': 5, | }, | }, | | And used like: | dbB = app.getDbConnection('billing') | dbI = app.getDbConnection('inventory') | | | -Jeff | | | | | | _______________________________________________ | Webware-discuss mailing list | Web...@li... | https://lists.sourceforge.net/lists/listinfo/webware-discuss |
From: Ian B. <ia...@co...> - 2001-10-24 19:48:08
|
From all the various implementation issues, it seems like there's no one way that works for everyone -- or at least no elegant one way. Someone brought up the idea of a PoolKit, which could potentially have PoolKit.DB, or PoolKit.MultiDB, or whatever else. This sounds like a good idea to me. If there aren't the right hooks in Application to do what you need now, I think it would be better to add those hooks than to directly add the DB stuff. Just my $0.02 Ian |
From: Aaron H. <aa...@me...> - 2001-10-24 20:12:58
|
I agree with Ian, Webware is an ideal platform for Intranet work - and that lends itself to unique data access methods. Generic object pools and lots of hooks. DBPool is very easy to work with and diag + I can use the same data access modules in a Python GUI as I do in webware. I think that the big drawback of the current method is to close or reduce the number of connections. I have a problem where database connections are related to sessions. It would be much easier for me to write code that executes when a session opens and closes. Now I am working on a taskKit task that has to scan all of the sessions and can take actions based on what it finds. Thanks, -Aaron Ian Wrote: > From all the various implementation issues, it seems like there's no > one way that works for everyone -- or at least no elegant one way. > If there aren't the right hooks in Application to do what you need > now, I think it would be better to add those hooks than to directly > add the DB stuff. > > Just my $0.02 > > Ian |
From: Ken L. <ke...@to...> - 2001-10-24 19:33:45
|
I like Jeff's idea re multiple data sources. Here's a patch to WebKit/Application.py to do that: *** o/Application.py Tue Oct 23 17:49:44 2001 --- ./Application.py Wed Oct 24 15:26:26 2001 *************** *** 101,106 **** --- 101,107 ---- self._serverSideInfoCacheByPath = {} self._cacheDictLock = Lock() self._instanceCacheSize = self._server.setting('MaxServerThreads') + self._dbPools = {} self._canDirs = [] self.initializeCans() *************** *** 237,242 **** --- 238,245 ---- del self._factoryList del self._server del self._servletCacheByPath + for p in self._dbPools.values(): + p.shutDown() print "Application has been succesfully shutdown." *************** *** 1186,1191 **** --- 1189,1206 ---- return ssPath, urlPath, extraURLPath + def getDbConnection(self, dsn='default'): + if not self._dbPools.has_key(dsn): + from MiscUtils.DBPool import DBPool + source = self.setting('dataSources')[dsn] + self._dbPools[dsn] = DBPool( + # our DB-API v2.0 module: + __import__(source['DbModule']), + # number of concurrent connections: + source['DbConnections'], + # DB module connection string: + source['DbConnect']) + return self._dbPools[dsn].getConnection() # may block ## Deprecated ## |
From: Clark C . E. <cc...@cl...> - 2001-10-24 19:42:01
|
Nice. Ok. I manually modified Ken's patch to add getDbConnInfo(). This way I can provide for dynamically generated connection information via... self.application.getDbConnInfo = myDbConnInfo Clark *** o/Application.py Tue Oct 23 17:49:44 2001 --- ./Application.py Wed Oct 24 15:26:26 2001 *************** *** 101,106 **** --- 101,107 ---- self._serverSideInfoCacheByPath = {} self._cacheDictLock = Lock() self._instanceCacheSize = self._server.setting('MaxServerThreads') + self._dbPools = {} self._canDirs = [] self.initializeCans() *************** *** 237,242 **** --- 238,245 ---- del self._factoryList del self._server del self._servletCacheByPath + for p in self._dbPools.values(): + p.shutDown() print "Application has been succesfully shutdown." *************** *** 1186,1191 **** --- 1189,1206 ---- return ssPath, urlPath, extraURLPath + def getDbConnInfo(self,dsn): + return self.setting('dataSources')[dsn] + + def getDbConnection(self, dsn='default'): + if not self._dbPools.has_key(dsn): + from MiscUtils.DBPool import DBPool + source = self.getDbConnInfo(dsn) + self._dbPools[dsn] = DBPool( + # our DB-API v2.0 module: + __import__(source['DbModule']), + # number of concurrent connections: + source['DbConnections'], + # DB module connection string: + source['DbConnect']) + return self._dbPools[dsn].getConnection() # may block ## Deprecated ## _______________________________________________ Webware-discuss mailing list Web...@li... https://lists.sourceforge.net/lists/listinfo/webware-discuss ----- End forwarded message ----- |
From: Ben P. <be...@th...> - 2001-10-24 18:43:34
|
Second that. We've implemented centralized database access via the Application object as well, and were planning on adding pooling support, but now I'll most likely be switching our system over to Ken's patch. We require central database access for a content scheduling system, which manages content for the servlets. -----Original Message----- From: web...@li... [mailto:web...@li...]On Behalf Of Ken Lalonde Sent: Wednesday, October 24, 2001 10:47 AM To: cc...@cl... Cc: web...@li... Subject: Re: [Webware-discuss] A few patches Thanks for your comments, Clark. I'd argue for putting Application.getDbConnection() in the core as follows: - putting it in SitePage makes it inaccessible to code that doesn't subclass SitePage. For example, I keep WebKit session data in a postgresql database, and the code to implement that is unrelated to SitePage. The pool is logically part of the application, not the Page servlet. - cleaning up DB connections at exit time is more awkward when subclassing SitePage. I guess you can do it with atexit, but it's messy, and some people won't bother. - it took me a little fiddling around to figure out the best way to do pooling connections, and I imagine others will waste time reinventing the same thing. Providing an application-wide connection pool with proper cleanup at exit fills a very common developer need, and is appropriate for the core. > From: "Clark C . Evans" <cc...@cl...> > To: Ken Lalonde <ke...@to...> > Subject: Re: [Webware-discuss] A few patches > > Ken Lalonde wrote: > | * WebKit/Application.py: > | New method: getDbConnection() > > This is interesting, but I'm not sure that it should > be added to the core of WebKit since it is certainly > easy enough to add in one's SitePage.py > > Your other changes sound good. _______________________________________________ Webware-discuss mailing list Web...@li... https://lists.sourceforge.net/lists/listinfo/webware-discuss |
From: Tom S. <tom...@we...> - 2001-10-24 19:10:33
|
Ben Parker wrote: > > Second that. We've implemented centralized database access via the > Application object as well, and were planning on adding pooling support, but > now I'll most likely be switching our system over to Ken's patch. We > require central database access for a content scheduling system, which > manages content for the servlets. Interesting. Do you use TaskKit or do you implement the scheduling yourself.. -- Tom Schwaller tsc...@gn... http://www.python.de |
From: Ben P. <be...@th...> - 2001-10-25 07:30:41
|
The content scheduling is a bit different from TaskKit. Think of it more like scheduling a television show to run on a particular channel for a particular time. The schedule requires both start and end times and provides a dictionary of arguments which define the content for display in a specific location within the site. Rather than the scheduler kicking off tasks to change display, the display mechanism asks the schedule for it's own content. This way the work associated with switching content happens organically. However, I would like to interface with TaskKit to kick off Admin-initiated changes which maintain the schedule. Right now, the content schedule is persistently stored in the db and cached at runtime. We rely on prefined times for the schedule to pick up the latest admin changes from the db. It'd be nice to employ TaskKit to make these changes on the fly. -----Original Message----- From: et...@we... [mailto:et...@we...]On Behalf Of Tom Schwaller Sent: Wednesday, October 24, 2001 3:29 PM To: Ben Parker Cc: web...@li... Subject: Re: [Webware-discuss] A few patches Ben Parker wrote: > > Second that. We've implemented centralized database access via the > Application object as well, and were planning on adding pooling support, but > now I'll most likely be switching our system over to Ken's patch. We > require central database access for a content scheduling system, which > manages content for the servlets. Interesting. Do you use TaskKit or do you implement the scheduling yourself.. -- Tom Schwaller tsc...@gn... http://www.python.de |
From: Tom S. <tom...@we...> - 2001-10-25 09:07:48
|
Ben Parker wrote: > > The content scheduling is a bit different from TaskKit. Think of it more > like scheduling a television show to run on a particular channel for a > particular time. The schedule requires both start and end times and > provides a dictionary of arguments which define the content for display in a > specific location within the site. Rather than the scheduler kicking off > tasks to change display, the display mechanism asks the schedule for it's > own content. This way the work associated with switching content happens > organically. ok, I understand. Thanks for the explanation.. > However, I would like to interface with TaskKit to kick off Admin-initiated > changes which maintain the schedule. Right now, the content schedule is > persistently stored in the db and cached at runtime. We rely on prefined > times for the schedule to pick up the latest admin changes from the db. > It'd be nice to employ TaskKit to make these changes on the fly. That reminds that Webware still needs something like PHPNuke, PostNuke, Slashcode, Midgard,... to give people a point and click content mangement system they can deploy out of the box and contribute Modules for (Mail, Calender, Rating System, Syndication with other sites, Shop, Workflow, ...). We have all pieces for a killer application (Webware, CheetahTemplates, FunFormKit, TaskKit, CanKit,..), but have not done it yet... I'm shure the Webware user community will explode with such a ContentKit. One could use the PostNuke (or PHPNuke) Database structure as a starting point and do the implementation the right way with Python/Webware. There's a reason I use PHPNuke at www.python.de. You can start in 5 Minutes with such a thing. Of course I want so switch, but do not have the time to implement everything myself right now... -- Tom Schwaller tsc...@gn... http://www.python.de |
From: Geoff T. <gta...@na...> - 2001-10-24 20:24:05
|
That brings up the larger question of "where do I put resources that are global to the application?" I usually just put stuff like that into regular Python modules. Then whenever I need it, I just import the module (at which time it gets initialized) and use it. Sometimes I put in some helper methods into SitePage to make it more convenient to use within servlets. But the compelling reason to put this directly into Application is so that it can shutdown cleanly. I haven't needed that up till now. So perhaps there needs to be a more general way to register stuff into Application so that it initializes when the app starts up, is available throughout the whole application, AND shuts down cleanly when the appserver is stopped. But I still agree with Clark that specific stuff like this doesn't really belong directly in Application; rather, there needs to be a plug-in mechanism so that it's easy to add stuff like this into Application via a configuration setting. Like perhaps in Application.config, there could be a list of Python files with mixins that automatically get applied to Application. Or a way to substitute your own derived version of Application instead of the original Application. At 02:43 PM 10/24/01 -0400, Ben Parker wrote: >Second that. We've implemented centralized database access via the >Application object as well, and were planning on adding pooling support, but >now I'll most likely be switching our system over to Ken's patch. We >require central database access for a content scheduling system, which >manages content for the servlets. > >-----Original Message----- >From: web...@li... >[mailto:web...@li...]On Behalf Of Ken >Lalonde >Sent: Wednesday, October 24, 2001 10:47 AM >To: cc...@cl... >Cc: web...@li... >Subject: Re: [Webware-discuss] A few patches > > >Thanks for your comments, Clark. > >I'd argue for putting Application.getDbConnection() in the core >as follows: >- putting it in SitePage makes it inaccessible > to code that doesn't subclass SitePage. > For example, I keep WebKit session data in a postgresql database, > and the code to implement that is unrelated to SitePage. > The pool is logically part of the application, not the Page servlet. >- cleaning up DB connections at exit time is more awkward > when subclassing SitePage. I guess you can do it with atexit, > but it's messy, and some people won't bother. >- it took me a little fiddling around to figure out the best way > to do pooling connections, and I imagine others will > waste time reinventing the same thing. > Providing an application-wide connection pool with proper > cleanup at exit fills a very common developer need, > and is appropriate for the core. > > > From: "Clark C . Evans" <cc...@cl...> > > To: Ken Lalonde <ke...@to...> > > Subject: Re: [Webware-discuss] A few patches > > > > Ken Lalonde wrote: > > | * WebKit/Application.py: > > | New method: getDbConnection() > > > > This is interesting, but I'm not sure that it should > > be added to the core of WebKit since it is certainly > > easy enough to add in one's SitePage.py > > > > Your other changes sound good. -- - Geoff Talvola gtalvola@NameConnector.com |
From: Ben P. <be...@th...> - 2001-10-25 07:10:42
|
I'm very interested in any work on adding mixin classes to Application or subclassing Application. In addition to database pooling, there are many examples of runtime caches that can be maintained by the application. We subclass Application to add in additional caching services for pieces of servlet output and a content scheduling system. I've extended AppServer to allow specification of Application classes based on the configuration file. The methodology is borrowed from WebKit's ServletFactory, we read in the class name from the config file and look for it in the main WebKit path. It's a bit of a hack. I'd like to switch this so it searches the python path or something. Here's the change to AppServer.createApplication() and the new method, AppServer.applicationClassName(): def createApplication(self): ''' Creates and returns an application object. Invoked by __init__. Reads the configurable ApplicationClassName setting ''' appClass = self.applicationClassName() return appClass(server=self) def applicationClassName(self): name = self.setting('ApplicationClassName') print 'Appserver creating Application class: ' + name path = self.serverSidePath(name + '.py') g = globals() execfile(path, g) assert g.has_key(name), 'AppServer: Cannot find %s in file %s.' % (name,path) appClass = g[name] assert type(appClass) is ClassType, 'AppServer: %s is not a ClassType.' % appClass assert issubclass(appClass, Application), 'AppServer: %s is not a subclass of Application.' % appClass return appClass Note that OneShotAppServer.createApplication() must be changed, as well. This is based on 0.5.1rc3 source. Cheers, Ben -----Original Message----- From: web...@li... [mailto:web...@li...]On Behalf Of Geoff Talvola Sent: Wednesday, October 24, 2001 4:23 PM To: Ben Parker; web...@li... Subject: RE: [Webware-discuss] A few patches That brings up the larger question of "where do I put resources that are global to the application?" I usually just put stuff like that into regular Python modules. Then whenever I need it, I just import the module (at which time it gets initialized) and use it. Sometimes I put in some helper methods into SitePage to make it more convenient to use within servlets. But the compelling reason to put this directly into Application is so that it can shutdown cleanly. I haven't needed that up till now. So perhaps there needs to be a more general way to register stuff into Application so that it initializes when the app starts up, is available throughout the whole application, AND shuts down cleanly when the appserver is stopped. But I still agree with Clark that specific stuff like this doesn't really belong directly in Application; rather, there needs to be a plug-in mechanism so that it's easy to add stuff like this into Application via a configuration setting. Like perhaps in Application.config, there could be a list of Python files with mixins that automatically get applied to Application. Or a way to substitute your own derived version of Application instead of the original Application. At 02:43 PM 10/24/01 -0400, Ben Parker wrote: >Second that. We've implemented centralized database access via the >Application object as well, and were planning on adding pooling support, but >now I'll most likely be switching our system over to Ken's patch. We >require central database access for a content scheduling system, which >manages content for the servlets. > >-----Original Message----- >From: web...@li... >[mailto:web...@li...]On Behalf Of Ken >Lalonde >Sent: Wednesday, October 24, 2001 10:47 AM >To: cc...@cl... >Cc: web...@li... >Subject: Re: [Webware-discuss] A few patches > > >Thanks for your comments, Clark. > >I'd argue for putting Application.getDbConnection() in the core >as follows: >- putting it in SitePage makes it inaccessible > to code that doesn't subclass SitePage. > For example, I keep WebKit session data in a postgresql database, > and the code to implement that is unrelated to SitePage. > The pool is logically part of the application, not the Page servlet. >- cleaning up DB connections at exit time is more awkward > when subclassing SitePage. I guess you can do it with atexit, > but it's messy, and some people won't bother. >- it took me a little fiddling around to figure out the best way > to do pooling connections, and I imagine others will > waste time reinventing the same thing. > Providing an application-wide connection pool with proper > cleanup at exit fills a very common developer need, > and is appropriate for the core. > > > From: "Clark C . Evans" <cc...@cl...> > > To: Ken Lalonde <ke...@to...> > > Subject: Re: [Webware-discuss] A few patches > > > > Ken Lalonde wrote: > > | * WebKit/Application.py: > > | New method: getDbConnection() > > > > This is interesting, but I'm not sure that it should > > be added to the core of WebKit since it is certainly > > easy enough to add in one's SitePage.py > > > > Your other changes sound good. -- - Geoff Talvola gtalvola@NameConnector.com _______________________________________________ Webware-discuss mailing list Web...@li... https://lists.sourceforge.net/lists/listinfo/webware-discuss |
From: Chuck E. <Chu...@ya...> - 2001-10-25 07:20:27
|
At 03:09 AM 10/25/2001 -0400, Ben Parker wrote: >Note that OneShotAppServer.createApplication() must be changed, as well. >This is based on 0.5.1rc3 source. Without having spent much time digesting your suggestion, I'd just like to throw this out there: Our current CVS and our 0.6a1 release are so much better than 0.5.1rc3 that I strongly encourage you to work with them instead. Of course, 0.6 will be released soon, thereby eliminating the need for this message (for the time being). -Chuck |
From: Geoff T. <gta...@na...> - 2001-10-24 20:54:35
|
At 04:22 PM 10/24/01 -0400, Geoff Talvola wrote: >That brings up the larger question of "where do I put resources that are >global to the application?" > >I usually just put stuff like that into regular Python modules. Then >whenever I need it, I just import the module (at which time it gets >initialized) and use it. Sometimes I put in some helper methods into >SitePage to make it more convenient to use within servlets. > >But the compelling reason to put this directly into Application is so that >it can shutdown cleanly. I haven't needed that up till now. > >So perhaps there needs to be a more general way to register stuff into >Application so that it initializes when the app starts up, is available >throughout the whole application, AND shuts down cleanly when the >appserver is stopped. > >But I still agree with Clark that specific stuff like this doesn't really >belong directly in Application; rather, there needs to be a plug-in >mechanism so that it's easy to add stuff like this into Application via a >configuration setting. Like perhaps in Application.config, there could be >a list of Python files with mixins that automatically get applied to >Application. Or a way to substitute your own derived version of >Application instead of the original Application. (following up on my own message) And as others have suggested, a Kit is the place to put this db code. If the Kit's job is to simply augment Application with new methods, then it may be as simple as a DbMixin.py module that defines a DbMixin class with the new methods, a Properties.py file like the other Kits, and an __init__.py like this (completely untested): # This function gets called by the app server during initialization def InstallInWebKit(appServer): # See if DbKit was enabled if appServer.setting('EnableDbKit', 0): # Mix in our DbMixin class into Application from WebKit.Application import Application from DbMixin import DbMixin from MiscUtils.MixIn import MixIn MixIn(Application, DbMixin) -- - Geoff Talvola gtalvola@NameConnector.com |
From: Chuck E. <Chu...@ya...> - 2001-10-24 20:54:47
|
At 04:22 PM 10/24/2001 -0400, Geoff Talvola wrote: >But the compelling reason to put this directly into Application is so that >it can shutdown cleanly. I haven't needed that up till now. > >So perhaps there needs to be a more general way to register stuff into >Application so that it initializes when the app starts up, is available >throughout the whole application, AND shuts down cleanly when the >appserver is stopped. > >But I still agree with Clark that specific stuff like this doesn't really >belong directly in Application; rather, there needs to be a plug-in >mechanism so that it's easy to add stuff like this into Application via a >configuration setting. Like perhaps in Application.config, there could be >a list of Python files with mixins that automatically get applied to >Application. Or a way to substitute your own derived version of >Application instead of the original Application. I agree with this line of thought regarding modularity and ease of extension. How about the idea of an "applet" which is an instance that can be attached to an application via either configuration or run time code (often found in your initializeContext() function)? class Applet: def __init__(self): self._app = None def app(self): return self._app def name(self): return self.__class__.__name__ def wasInstalled(self, app): self._app = app def shutDown(self): pass app.addApplet(MyApplet()) The application would maintain a list of these and send them all shutDown() when it shutdown. Application.applet('foo') would return an applet by name, possibly returning a list in the case of name collisions. As the application developer you would decide if such name collisions would/could happen and either deal with it, or not. Basically, this approach allows you to attach arbitrary instances to the application for whatever purposes you desire and hook into application level events like shutDown(). I'm not sure if there would be any other events in the future. I'd also like to provide a file system structure for applications where it would be easy to drop in a custom subclass of Application for your project. Inheritance and composition are both valid ways to extend a class and WebKit should make both easy for Application. If Applet is well received and remains fairly simple, we could sneak it into the 0.6 release. If it's not well received or blows up in complexity (as these things often do), then we'd wait for 0.7. Let the e-mails begin... -Chuck |
From: Tom S. <tom...@we...> - 2001-10-24 18:57:40
|
Ken Lalonde wrote: > > Thanks for your comments, Clark. > > I'd argue for putting Application.getDbConnection() in the core > as follows: > - putting it in SitePage makes it inaccessible > to code that doesn't subclass SitePage. > For example, I keep WebKit session data in a postgresql database, > and the code to implement that is unrelated to SitePage. > The pool is logically part of the application, not the Page servlet. > - cleaning up DB connections at exit time is more awkward > when subclassing SitePage. I guess you can do it with atexit, > but it's messy, and some people won't bother. > - it took me a little fiddling around to figure out the best way > to do pooling connections, and I imagine others will > waste time reinventing the same thing. > Providing an application-wide connection pool with proper > cleanup at exit fills a very common developer need, > and is appropriate for the core. I personally agree to put this into the core, since it is probably the first thing people will use when developing dynamic web applications with Webware. I was never really happy with the situation to implement this kind of stuff myself. The other possibility would be a small DBKit, which does the same thing and makes available some more convenience routines (some of them published on this mailinglist some time ago). I used this kind of approach a long time ago and switched to the "Derive from SitePage" approach later, but a cleaner solution would be nice. Maybe even a PoolKit, which makes pooling avaliable in a much general sense (like Poolman in the Java world, http://www.codestudio.com) -- Tom Schwaller tsc...@gn... http://www.python.de |