[Twisted-Python] Basic problem with deferreds

mayvimmer at fibertel.com.ar mayvimmer at fibertel.com.ar
Mon Aug 22 23:52:56 EDT 2011


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!





More information about the Twisted-Python mailing list