pythonmongodbasynchronoustornadotornado-motor

Use async with tornado and motor


Newbie to Python 3.5 and the new async and await features

The following code only returns a future object. How do I get the actual book item from database and write it to json? And what is the best practice for using async await along with motor-tornado?

async def get(self, book_id=None):
    if book_id:
        book = await self.get_book(book_id)
        self.write(json_util.dumps(book.result()))
    else:
        self.write("Need a book id")

async def get_book(self, book_id):
    book = self.db.books.find_one({"_id":ObjectId(book_id)})
    return book

Solution

  • No need for "result()". Since your "get" method is a native coroutine (it's defined with "async def"), then using it with "await" means that a result is already returned to you:

    async def get(self, book_id=None):
        if book_id:
            # Correct: "await" resolves the Future.
            book = await self.get_book(book_id)
            # No resolve(): "book" is already resolved to a dict.
            self.write(json_util.dumps(book))
        else:
            self.write("Need a book id")
    

    However you must also "await" the future in "get_book" in order to resolve it before returning:

    async def get_book(self, book_id):
        book = await self.db.books.find_one({"_id":ObjectId(book_id)})
        return book