[Twisted-Python] deferreds, and .rpy resources

Mario Ruggier mario at ruggier.org
Fri Jan 24 05:14:56 EST 2003

Thanks a lot Daniel, that was very helpful. The code you sent works
almost verbatim on a test table in postgres. I have also tried mapped
the same solution to adbapi. Tthe rpy code for both versions is below.
To switch between the 2 just toggle commenting the resource defns.
In the adbapi version, I have some questions:

1.  First of all, would this be the correct way to do this with adbapi?
2. If I stop the reactor at the end of databaseResult_adbapi, twistdweb
returns the http request with correct content, but crashes  
(consistently on
each request).
3. If i just import the reactor privately inside the render() method  
never call stop() on it), everything seems to work fine. But is this the
way it should be done?

Thanks again, mario

>> Hi, sorry for the newbie questions but I do not understand how I
>> can combine the resource interface with deferred callbacks.  Or,
>> specifically, can anyone point me to a simple example of a .rpy
>> that does a simple database call, and returns the result to the
>> http response?
>> Many thanks,
>> Mario
> I'm no expert, but you can do something like this (UNTESTED):


> Of course, you could also use twisted.enterprise.adbapi, but I've  
> experienced a lot of memory leaks occurring when going that route, so  
> I just use deferToThread instead.
> There is probably a better way to code this, but I'm not far enough  
> along in my Python/Twisted experience to provide it.
> L. Daniel Burr

# common twisted imports
from twisted.web import resource
from twisted.web.server import NOT_DONE_YET

dbname = 'db'
dbuser = 'user'
dbpass = 'pw'

### dbapi

def databaseResult(result, httpRequest):

def errBack(err, httpRequest):
     httpRequest.write('error: ' + str(err) )

def databaseOperation():
     from pyPgSQL import PgSQL
     con = PgSQL.connect(database=dbname,user=dbuser,password=dbpass)
     cur = con.cursor()
     cur.execute("SELECT foo_id,name,weight FROM foo")
     databaseResult = cur.fetchall()
     return databaseResult #[0][0]

class MyResource(resource.Resource):
     def render(self, request):
         from twisted.internet import threads
         d = threads.deferToThread(databaseOperation)
         d.addCallback(databaseResult, request)
         d.addErrback(errBack, request)
         return NOT_DONE_YET

### adpapi

from twisted.internet import reactor
from twisted.enterprise import row

class FooRow(row.RowObject):
   rowColumns = [
           ('foo_id', 'int'),
           ('name', 'varchar'),
           ('weight', 'int'),
   rowKeyColumns = [('foo_id', 'int4')]
   rowTableName = 'foo'
   #rowFactoryMethod = ['testFactoryMethod']

def databaseResult_adbapi(result, httpRequest):
     if result:
         for foo in result:
             httpRequest.write('foo: '+str(foo.__dict__)+'<br/>')

def errBack_adbapi(err, httpRequest):
     httpRequest.write('error: '+str(err) )

class MyResource_adbapi(resource.Resource):
     def render(self, request):
         #from twisted.internet import reactor
         from twisted.enterprise import adbapi, reflector
         from twisted.enterprise.sqlreflector import SQLReflector
         dbpool =  
         r = SQLReflector(dbpool,[FooRow])
         d = r.loadObjectsFrom('foo',whereClause=[('foo_id',  
reflector.LESSTHAN, 5)])
         d.addCallback(databaseResult_adbapi, request)
         d.addErrback(errBack_adbapi, request)
         return NOT_DONE_YET


#resource = MyResource()
resource = MyResource_adbapi()


More information about the Twisted-Python mailing list