Search code examples
pythonwebfetchtornadosynchronous

Making synchronous requests using Tornado. RuntimeError: Cannot run the event loop while another loop is running


I'm trying to make synchronous requests using Tornado.
Tried to make API calls.

main.py

import tornado.web
import tornado.httpserver
import tornado.options
import tornado.ioloop
from tornado.web import url

from handlers import IndexHandler

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers=[
            url(r"/", IndexHandler),
        ]
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

and my handlers.py is...

import tornado.web
import tornado.httpclient

import urllib
import json
import datetime
import time

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        query = self.get_argument('q')
        client = tornado.httpclient.HTTPClient()
        response = client.fetch("https://pokeapi.co/api/v2/pokemon/" + urllib.urlencode(("query")))
        print(response)
        if response == "Not Found":
            self.write("Invalid Input")
        response_data = json.loads(response.body)
        pikachu_name = response_data['name']
        pikachu_order = response_data['order']
        self.write("""
            Pickachu Name: %s <br>
            Pickachu Order: %d <br>
            """ %(pikachu_name, pikachu_order))

Now the issue I'm facing is

[E 200407 02:18:37 web:1792] Uncaught exception GET /?q=pikachu (::1)
    HTTPServerRequest(protocol='http', host='localhost:8000', method='GET', uri='/?q=pikachu', version='HTTP/1.1', remote_ip='::1')
    Traceback (most recent call last):
      File "C:\Python\Python37\lib\site-packages\tornado\web.py", line 1701, in _execute
        result = method(*self.path_args, **self.path_kwargs)
      File "C:\Users\Bagga\Documents\tornado\Tweet Rate\handlers.py", line 12, in get
        client = tornado.httpclient.HTTPClient()
      File "C:\Python\Python37\lib\site-packages\tornado\httpclient.py", line 107, in __init__
        self._async_client = self._io_loop.run_sync(make_client)
      File "C:\Python\Python37\lib\site-packages\tornado\ioloop.py", line 526, in run_sync
        self.start()
      File "C:\Python\Python37\lib\site-packages\tornado\platform\asyncio.py", line 149, in start
        self.asyncio_loop.run_forever()
      File "C:\Python\Python37\lib\asyncio\base_events.py", line 529, in run_forever
        'Cannot run the event loop while another loop is running')
    RuntimeError: Cannot run the event loop while another loop is running
[E 200407 02:18:37 web:2250] 500 GET /?q=pikachu (::1) 55.85ms

What is the issue and how can I solve it?
The main error I can see here is,
RuntimeError: Cannot run the event loop while another loop is running
I feel that the this is due to the IOLoop and HTTPClient, but can't understand as to what is the issue?


Solution

  • I quote the documentation of HTTPClient

    Changed in version 5.0: Due to limitations in asyncio, it is no longer possible to use the synchronous HTTPClient while an IOLoop is running. Use AsyncHTTPClient instead.

    Please use AsyncHTTPClient instead.