Python futures : How do I get the json from a future object in Tornado?

4.4k Views Asked by At

This is a post handler :

handler.py

from imports import logic

@gen.coroutine
def post(self):
    data = self.request.body.decode('utf-8')
    params = json.loads(data)
    model_id= params['model_id']
    logic.begin(model_id)

The logic object is imported from imports.py where it is instantiated from an imported class Logic

imports.py :

import Models
import Logic

class Persist(object):
    def getModel(self, model_id):
        model = Models.findByModelId(model_id)
        return model


persist = Persist()
logic = Logic(persist)

logic.py

class Logic(object):
    def __init__(self, persist):
        self._persist = persist

    def begin(self, model_id):
         model = self._persist.get_model(model_id)
         print ("Model from persist : ")
         print (model)

the get_model method uses Models which makes a DB query and returns the future object :

model.py:

from motorengine.document import Document

class Models(Document):
    name = StringField(required=True)

def findByModelId(model_id):
    return Models.objects.filter(_id=ObjectId(model_id)).find_all()

This prints a future object in console :

<tornado.concurrent.Future object at 0x7fbb147047b8>

How can I convert it to json ?

1

There are 1 best solutions below

0
A. Jesse Jiryu Davis On

To resolve a Future into an actual value, yield it inside a coroutine:

@gen.coroutine
def begin(self, model_id):
     model = yield self._persist.get_model(model_id)
     print ("Model from persist : ")
     print (model)

Any function that calls a coroutine must be a coroutine, and it must yield the return value of the coroutine to get its return value:

@gen.coroutine
def post(self):
    data = self.request.body.decode('utf-8')
    params = json.loads(data)
    model_id = params['model_id']
    model = yield logic.begin(model_id)
    print(model)

More advanced coding patterns don't need to follow these rules, but to begin with, follow these basic rules.

For more information about calling coroutines from coroutines, see Refactoring Tornado Coroutines.