tornado is a lightweight web framework and asynchronous communication library. It seems to show its true value when adopting a communication method that maintains a connection for a long time, such as WebSocket and long polling.
This time, I didn't want to use a big web framework like Django
for a server implementation of a little app that returns a JSON-formatted response, so I tried tornado
.
You can also use JSONEncorder
to return the response, but if you use Tornado-JSON, the response format will be JSend It can be specified or validated by JSON Schema. You can also do documentation, which seems useful if you want to implement it in JSON over HTTP.
Web Server: nginx Language: Python 2.7.10 OS: CentOS release 6.7 (Final)
First, install tornado
and Tornado-JSON
with pip.
pip install tornado
pip install Tornado-JSON
I was able to install it without any problems.
After the installation is complete, clone Tornado-JSON
from GitHub and try demo.
cd Tornado-JSON/demos/helloworld
python helloworld.py
Doing the above will start the tornado application. You can see the class associated with the API URL as shown below.
Let's actually make a request. You can also use a browser, but this time I will use httpie to check from the terminal. Try the APIs displayed in the terminal from top to bottom.
/api/helloworld/?
$ http GET <path/to/host>/api/helloworld/
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 45
Content-Type: application/json; charset=UTF-8
Date: Thu, 21 Jan 2016 20:22:38 GMT
Etag: "2e708f71c76a9c77119c54d91746619abbbb28fc"
Server: nginx/1.0.15
Vary: Accept-Encoding
{
"data": "Hello world!",
"status": "success"
}
Seems to be the simplest example.
/api/freewilled/?
$ http GET <path/to/host>/api/freewilled/
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 76
Content-Type: application/json; charset=UTF-8
Date: Thu, 21 Jan 2016 20:27:55 GMT
Etag: "81d9135b038a336645a03c17f8c1f58bf890a010"
Server: nginx/1.0.15
Vary: Accept-Encoding
{
"data": "I don't need no stinkin' schema validation.",
"status": "success"
}
This is a bit confusing, but it seems to be an example without validation.
/api/postit/?
#In httpie, the numeric type is to send the raw json=not:=Note that it is specified in.=If you specify with, the numerical value becomes a character string type, and an error occurs in validation.
$ http POST <path/to/host>/api/postit/ title='post it' body='hello world' index:=0
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 65
Content-Type: application/json; charset=UTF-8
Date: Thu, 21 Jan 2016 20:30:53 GMT
Server: nginx/1.0.15
Vary: Accept-Encoding
{
"data": {
"message": "post it was posted."
},
"status": "success"
}
This is an example of the POST Method, not the GET Method. Since the API has title, body, and index as parameters, validation will fail if these are not specified. When it failed, it became as follows.
$ http POST <path/to/host>/api/postit/ title='post it' body='hello world' index=0
HTTP/1.1 400 Bad Request
Connection: keep-alive
Content-Length: 179
Content-Type: application/json; charset=UTF-8
Date: Fri, 22 Jan 2016 16:02:19 GMT
Server: nginx/1.0.15
Vary: Accept-Encoding
{
"data": "u'0' is not of type 'number'\n\nFailed validating 'type' in schema['properties']['index']:\n {'type': 'number'}\n\nOn instance['index']:\n u'0'",
"status": "fail"
}
/api/greeting/(?P<fname>[a-zA-Z0-9_\-]+)/(?P<lname>[a-zA-Z0-9_\-]+)/?$
$ http GET <path/to/host>/api/greeting/John/Smith
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 55
Content-Type: application/json; charset=UTF-8
Date: Thu, 21 Jan 2016 20:45:36 GMT
Etag: "8e58c6953fdb166e2912eca36881f55885f20073"
Server: nginx/1.0.15
Vary: Accept-Encoding
{
"data": "Greetings, John Smith!",
"status": "success"
}
This is an example of a URL that uses regular expressions. John and Smith are captured with the keys fname and lname, respectively, and can be referenced from a Python program.
/api/asynchelloworld/(?P
$ http GET <path/to/host>/api/asynchelloworld/Smith
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 78
Content-Type: application/json; charset=UTF-8
Date: Thu, 21 Jan 2016 20:48:19 GMT
Etag: "4f1db48667213b44adbacc2a85599bca86c72f19"
Server: nginx/1.0.15
Vary: Accept-Encoding
{
"data": "Hello (asynchronous) world! My name is Smith.",
"status": "success"
}
Hello, asynchronous world. So it looks like an example using an asynchronous library.
The above API implementations are on GitHub demos / helloworld / helloworld.py and demos / helloworld / helloworld /api.py. It seems that the desired processing can be implemented by referring to these.
This is a demo showing URLconf.
When I look at the helloworld implementation, I notice that I can't find URLconf (ʻurlpatternsin
Django`).
What does that mean?
In fact, ʻAPIHandler has list type class variables named
urls,
url_names, and if you override this, URLs will be generated automatically. Get the generated URLs with the
tornado_json.routes.get_routesfunction. This seems to be the URLconf method of
Tornado-JSON`.
For more information, [demos / rest_api / cars / api / \ _ \ _ init \ _ \ _. Py](https://github.com/hfaran/Tornado-JSON/blob/master/demos/rest_api/cars/api/ It is described in init.py # L20).
There is no such thing. (I'm exhausted .. Maybe I'll do it later if I feel like it?
There may be various traps, but I am happy that it is lightweight. Asynchronous processing and non-blocking IO, which seems to be the most attractive, have not been investigated in detail, but it is interesting to see what happens especially when combined with WebSocket.
As for Tornado-JSON
, it's fascinating considering that the recent requirements for web development have moved to JSON over HTTP
. However, I'm a little worried that the development is not very active and there are very few contributors, 4 people. On the other hand, tornado
is relatively active, so I feel a little relieved.
As for tornado
, it seems that a (probably the only) book was published around 2012.
https://github.com/Introduction-to-Tornado/Introduction-to-Tornado
Recommended Posts