Search code examples
tornado

Convert Tornado html return to json data


I have a simple tornado app that return Hello World for get requests, but if the method is POST/PUT/DELETE... it is returning HTML response like this:

<html>
<title>405: Method Not Allowed</title>

<body>405: Method Not Allowed</body>

</html> 

I want the response like that:

{ "error":"Method not allowed }

So, my question is there a way to return a json response instead of html. Below is the code that I wrote so far (I've added set header but it is just returning the same html data above but in json format(I want to return specific json data) so, is there a way to do that?

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
      self.set_header('Content-Type', 'application/json')

    def get(self):
        self.write("Hello, world")

class SecondHandler(tornado.web.RequestHandler):
    def get(self, two):
        self.write("Hello, worldddd")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
        (r"/", SecondHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Thank you


Solution

  • The method to override for this is RequestHandler.write_error.

    def write_error(self, status_code, **kwargs):
        if status_code == 405:
            self.finish({"error": "Method not allowed"})
        else:
            super().write_error(status_code, **kwargs)
    

    But I'd encourage you to make your client code able to look at the status code regardless of whether there is a response body in json format or not. It's more trouble than its worth to track down all possible 404 paths (etc) to issue json-formatted responses for all errors.