Judah Endymion
Judah Endymion

Reputation: 67

Calling a different endpoint from the same running web service in Tornado Python

I have two endpoints in the same web service and one should call the second one. But because the first one is not yet finished, the second one is not called. Below is the demonstration of what I need to achieve.

import tornado.ioloop
import tornado.web
import tornado.escape
import time
import requests
import itertools

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

class SampleApi1(tornado.web.RequestHandler):
    def post(self):
        print("1")
        response = requests.post("http://localhost:5000/test2/")
        self.write(response)

class SampleApi2(tornado.web.RequestHandler):
    def post(self):
        print("2")
        self.write({"key": "value"})

def make_app():
    return tornado.web.Application([(r"/test1/", SampleApi1),
                                    (r"/test2/", SampleApi2)])

if __name__ == "__main__":
    app = make_app()
    app.listen(5000)
    print("Listening on port 5000")
    tornado.ioloop.IOLoop.current().start()

SampleApi1 calls SampleApi2 but SampleApi2 is not being called since SampleApi1 is not yet done. I've read gen.coroutines but it didn't work. I don't need to call SampleApi2 in parallel, I just need to call it from SampleApi1. Thank you in advance!

Upvotes: 0

Views: 773

Answers (1)

Ben Darnell
Ben Darnell

Reputation: 22154

Tornado is an asynchronous framework, but the requests library is synchronous and blocking (see the tornado user's guide for more on these concepts). You shouldn't use requests in Tornado applications because it blocks the main thread. Instead, use Tornado's own AsyncHTTPClient (or another async http client like aiohttp):

async def post(self):
    print("1")
    client = tornado.httpclient.AsyncHTTPClient()
    response = await client.fetch("http://localhost:5000/test2", method="POST", body=b"")
    self.write(response)

Upvotes: 1

Related Questions