pythonpython-2.7tornadoclass-methodmotorengine

Python/Tornado - call to classmethod


Given this simple code where I declare a class and a functions inside it. In the main I try to call the function but the call is not made. I don't get any error but if I put a print in order to know if the call has happened nothing occurs.

models

class Balance(Document):
    gross_balance = FloatField(required=True, min_value=0, default=0)

    @classmethod
    def createBalance(cls, gross_balance):
        result = yield Balance.objects.create(gross_balance = gross_balance)
        result.save()
    @classmethod
    def sayHi(cls):
        print "Hi there"

main

from models import Balance

class CreateBalanceHandler(tornado.web.RequestHandler):

@tornado.gen.coroutine
def post(self):
    gross_balance = self.get_argument('gross_balance')
    Balance.createBalance(gross_balance)
    Balance.sayHi()
    self.redirect('/query/{}'.format(gross_balance))

What am I doing wrong? The sayHi function show its print but there's no reaction with createBalance.


Solution

  • Decorate createBalance with gen.coroutine to run it on ioloop. To wait until balance is created invoke it like yield Balance.createBalance() in RequestHandler

    models

    class Balance(Document):
        gross_balance = FloatField(required=True, min_value=0, default=0)
    
        # classmethod must be the most outter decorator (as well as staticmethod)
    
        @classmethod
        @tornado.gen.coroutine
        def createBalance(cls, gross_balance):
            result = yield Balance.objects.create(gross_balance = gross_balance)
            # AFAIR save returns future and also should be yielded
            # yield. result.save()
            result.save()
    
        @classmethod
        def sayHi(cls):
            print "Hi there"
    

    main

    from models import Balance
    
    class CreateBalanceHandler(tornado.web.RequestHandler):
    
        @tornado.gen.coroutine
        def post(self):
            gross_balance = self.get_argument('gross_balance')
            yield Balance.createBalance(gross_balance)
            Balance.sayHi()
            self.redirect('/query/{}'.format(gross_balance))
    

    Note: As I mentioned in snippet's comment, in motorengine the Document.save returns Future and probably you want to yield it as well, to wait until it has finished.