[Twisted-Python] Basic problem with deferreds

Hi guys, I'm new to twisted world and I'm facing what seems to be an easy problem but I cannot grasp it. I thought I have already undestood the deferred concept but obviously I still have a concept error I cannot pass: I have a method with the following parameters: 1- an userid, 2- a security code, 3- a list of tuples composed by an object id and an object quantity. I need to check in a database if the user exists and he's active, if the security code exists and belongs to the user and for each object if it exists and then insert the submitted quantity in the database. What I try to do is to check both user and security code just once and then loop the objects to verify them and insert. If user or sec_code are invalid, this should fail right away, otherwise perform the action and add the results to a list. No matter how I place the methods or how I call them when evaluating the user or the security code, I always get a Deferred object and I need the actual result so that the method continue to be executed or not, evaluating each object in the list. I thought that using the "callback" method this will fire the callbacks and give me the result, but I cannot find where I need to execute it. Here is my code: class ExampleObject(object): def get_userid(self, username): r1 = defer.Deferred() def cb(rs): if len(rs)==0: resp = u'The user is not in the database' else: resp = rs[0]['id'] r1.callback(resp) r1 = self.conn_pool.runQuery('select id from users where ' 'username=?', (sql_safe(username),)).addCallback(cb) return r1 def get_sec_code(self, sec_code): r2 = defer.Deferred() def cb(rs): if len(rs)==0: resp = u'The security code is invalid' else: resp = rs[0]['userid'] r2.callback(resp) r2 = self.conn_pool.runQuery('select user_id from sec_codes where ' 'sec_code=?', (sql_safe(sec_code),)).addCallback(cb) return r2 def grant_objs(self, username, sec_code, objects): errmsg = None def grant_obj(pobj, puser, psec_code): d = defer.Deferred() def cb(rs): if len(rs)==0: d.callback(False) else: d.callback(True) def cb2(rs): if rs: self.conn_pool.runOperation('insert into inventory '\ '(user_id, obj_id, quantity, dateadded) values '\ '(?,?,?,?)', (pobj, pitem[0], pitemp[1], datetime.datetime.now())).callback(True) else: d.callback('Object with id %d does not exist' % (pobj[0])) self.conn_pool.runQuery("select id, ? as quantity from objects where " "id=?", (sql_safe(pobj[0]), sql_safe(pobj[1]))).\ addCallback(cb).addCallback(cb2) defs = [] def cb(value): return value for i in enumerate(items): if i[0]==0: # # I need the result right now, however I always get a Deferred object. # u_ = self.get_userid(username).addCallback(cb) t_ = self.get_sec_code(sec_code).addCallback(cb) if not isinstance(u_, int): errmsg = u_ elif not isinstance(t_, int): errmsg = t_ elif u_!=t_: errmsg = u'Your security code does not belong to the user' if errmsg is not None: defs.append(errmsg) break res = grant_obj(i[1], u_, t_) defs.append(res) return defs TIA for any pointers you can give me!

On 23 August 2011 04:52, <mayvimmer@fibertel.com.ar> wrote: <snip>
You want the reactor to callback the deferred when the SQL query has finished rather than you triggering the callback method. Your get_userid function returns a deferred so if you want something to happen after that you must attach it as a callback to this deferred. You could try something like the following that will run cb with the result of get_userid and get_sec_code. d1 = get_userid() d2 = get_sec_code() d = defer.DeferredList([d1, d2]) d.addCallback(cb)

On 23 August 2011 04:52, <mayvimmer@fibertel.com.ar> wrote: <snip>
You want the reactor to callback the deferred when the SQL query has finished rather than you triggering the callback method. Your get_userid function returns a deferred so if you want something to happen after that you must attach it as a callback to this deferred. You could try something like the following that will run cb with the result of get_userid and get_sec_code. d1 = get_userid() d2 = get_sec_code() d = defer.DeferredList([d1, d2]) d.addCallback(cb)
participants (2)
-
mayvimmer@fibertel.com.ar
-
Michael Thompson