I have some asynchronous functions using tornado gen.coroutine
that I normally use as part of a tornado-based web application. However, I want to call some of them from a plain old python script to do some administration tasks. How do I do this?
from tornado import gen
import some_internal_stuff
@gen.coroutine
def myfunc(x):
y = yield some_internal_stuff.another_async_func(x)
raise gen.Return(y)
if __name__ == "__main__":
# What do I put here to call myfunc(1) and get the async return value?
pass
Update:
A more concrete example:
from tornado import gen
@gen.coroutine
def another_async_func(x):
print "aaf"
raise gen.Return(x + 1)
@gen.coroutine
def myfunc(x):
print "myfunc"
y = yield another_async_func(x)
print "back"
raise gen.Return(y)
def callback(y):
print "Callback called with %d" % y
if __name__ == "__main__":
myfunc(1, callback=callback)
Running this outputs:
myfunc
aaf
There's a built-in method run_sync
in IOLoop
to run a single call and then stop the loop, so it's pretty trivial to just add an event loop to a plain python script provided you have tornado in the PYTHONPATH.
With the concrete example:
from tornado import gen, ioloop
@gen.coroutine
def another_async_func(x):
print "aaf"
raise gen.Return(x + 1)
@gen.coroutine
def myfunc(x):
print "myfunc"
y = yield another_async_func(x)
print "back"
raise gen.Return(y)
@gen.coroutine
def main():
y = yield myfunc(1)
print "Callback called with %d" % y
if __name__ == "__main__":
ioloop.IOLoop.instance().run_sync(main)
This outputs:
myfunc
aaf
back
Callback called with 2
Note that run_sync
doesn't nest well; if you call run_sync
in a function called by run_sync
on the same IOLoop
the completion of the inner call will stop the IOLoop
and no further yield
s after the inner call will return.