Oha Noch
Oha Noch

Reputation: 404

Python Tornado respond to GET request

I am misunderstanding something very basic probably. I am new to tornado and web servers in general. I used some tutorials and a lot of googling to get started but I still find myself stuck at the basics.

The Situation

I am using python 3.6.9 on an Ubuntu 18.04 server with tornado 6.0.4. I have a tornado server that accepts GET requests via a tornado.web.RequestHandler class get () function and does some computation on it. This all works properly.
I need the tornado server to return the results (a numpy array) to the client that sent the request.
To my knowledge everything I am doing is synchronous as I did not add any async code myself.

My code in a nutshell:

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        base_data = self.get_argument("base_data")
        compute_data(base_data)
        #Here I want to return the data back to the client

application = tornado.web.Application(handlers=[ (r"/calculator", MainHandler)])

if __name__ == "__main__":
    http_server=tornado.httpserver.HTTPServer(application)
    http_server.listen(__PORT__)
    tornado.ioloop.IOLoop.instance().start()

The problem

I do not have info about the client.
I do not have any idea and cannot find any tutorial explaining how to respond back to a client from a GET request.

What I tried

I tried simply returning the np.array at the end of my get() function but I got:
TypeError: object numpy.ndarray can't be used in 'await' expression
I thought what I need to do is make a POST request back to the client, but I do not (that I know of) have the IP and port of the client.
I also found randomly maybe I should use tornado.ioloop.IOLoop.current().spawn_callback(data) but that wasn't right I guess because it asked me for a callable function.

What I want to happen

I want to send back the computed data to the client that requested it.

Thanks in advance for any help available. I know I am probably misunderstanding the very basics of what tornado is meant to do or how it works, but I can't find any place addressing this question specifically.

Upvotes: 0

Views: 1679

Answers (2)

Milovan Tomašević
Milovan Tomašević

Reputation: 8673

See official documentation:

Many methods in RequestHandler are designed to be overridden in subclasses and be used throughout the application. It is common to define a BaseHandler class that overrides methods such as write_error and get_current_user and then subclass your own BaseHandler instead of RequestHandler for all your specific handlers.

So in your example it is also possible to write a write_response method that could make it easier to write responses in MainHandler as well as in other handlers.

See a simple example:

from tornado.web import RequestHandler
from http import HTTPStatus
import json


class BaseHandler(RequestHandler):
    def write_response(self, status_code, result=None, message=None):
        self.set_status(status_code)
        if result:
            self.finish(json.dumps(result))
        elif message:
            self.finish(json.dumps({
                "message": message
            }))
        elif status_code:
            self.set_status(status_code)
            self.finish()

class MainHandler(BaseHandler):
    def get(self):
        self.write_response(status_code=HTTPStatus.OK, message='Hello calculator!')

If the data you return to the client is in the form below, then use write_response with the result argument

data = ['foo', {'bar': ('baz', None, 1.0, 2)}]
self.write_response(status_code=HTTPStatus.OK, result=data)

# and so you will send to the client:
["foo", {"bar": ["baz", null, 1.0, 2]}]

# or
your_numpy_list = your_numpy_object.tolist()
self.write_response(status_code=HTTPStatus.OK, result=your_numpy_list)

Upvotes: 1

Oha Noch
Oha Noch

Reputation: 404

So I was missing the most basic thing. Apparently in Tornado self.write({"data_name":data}) in the get() function will return the data.

Now I am still running into an issue of not being able to return byte data (my circumstances have changed and now I need to turn the numpy array into a wav file and send the wav file over) and I am getting a different error that Object of type 'bytes' is not JSON serializable but if I wont be able to figure it out I will open a new question for it.

Upvotes: 0

Related Questions