[PYTHON] Tornado-Let's create a Web API that easily returns JSON with JSON

On the front mouth

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.

environment

Web Server: nginx Language: Python 2.7.10 OS: CentOS release 6.7 (Final)

Insur

First, install tornado and Tornado-JSON with pip.

pip install tornado
pip install Tornado-JSON

I was able to install it without any problems.

demos part 1 hellowold

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.

tornado-json-helloworld-compressed.png

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[a-zA-Z0-9_\-]+)/?$

$ 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.

demos part 2 rest_api

This is a demo showing URLconf.

When I look at the helloworld implementation, I notice that I can't find URLconf (ʻurlpatternsinDjango`). 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 ofTornado-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).

Actually make something and publish

There is no such thing. (I'm exhausted .. Maybe I'll do it later if I feel like it?

Impressions I tried

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.

reference

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

Tornado-Let's create a Web API that easily returns JSON with JSON
Create a web API that can deliver images with Django
Create a web app that can be easily visualized with Plotly Dash
Create a web application that recognizes numbers with a neural network
Create an API that returns data from a model using turicreate
Create REST API that returns the current time with Python3 + Falcon
[LINE Messaging API] Create a BOT that connects with someone with Python
Create a web service with Docker + Flask
Create a page that loads infinitely with python
You can easily create a GUI with Python
Create a Python console application easily with Click
I tried to create a class that can easily serialize Json in Python
I want to create an API that returns a model with a recursive relationship in the Django REST Framework
Why not create a stylish table easily with Python?
Create a chatbot that supports free input with Word2Vec
Create a discord bot that notifies unilaterally with python (use only requests and json)
Create a PythonBox that outputs with Random after PEPPER Input
I made a LINE BOT that returns parrots with Go
Create a bot that only returns the result of morphological analysis with MeCab on Discord
Create an API with Django
Let's create a script that registers with Ideone.com in Python.
Create a life game that is manually updated with tkinter
A script that makes it easy to create rich menus with the LINE Messaging API
Create a defaultdict that returns a defaultdict to create a world where KeyErrror does not occur (+ JSON parsing example)
Web API with Python + Falcon
Build a speed of light web API server with Falcon
Create a heatmap with pyqtgraph
Create playlists of bright songs only with Spotify Web API
(For beginners) Try creating a simple web API with Django
Create a directory with python
Easily cProfile with a decorator
Create a social integration API for smartphone apps with Django
Create a program that can generate your favorite images with Selenium
Web App Development Practice: Create a Shift Creation Page with Django! (Shift creation page)
Create a TalkBot easily using Discord.py and A3RT's Talk API (pya3rt).
Create a poster with matplotlib to visualize multiplication tables that remember multiplication
Try to create a Qiita article with REST API [Environmental preparation]
Create a REST API to operate dynamodb with the Django REST Framework
How to create a serverless machine learning API with AWS Lambda
Create Awaitable with Python / C API
[AWS] Create API with API Gateway + Lambda
A function that returns a random name
Create a virtual environment with Python!
Build a web application with Django
Create API using hug with mod_wsgi
Create a CRUD API using FastAPI
Create a poisson stepper with numpy.random
Easily draw a map with matplotlib.basemap
Create a file uploader with Django
Create a BOT that can call images registered with Discord like pictograms
A story that visualizes the present of Qiita with Qiita API + Elasticsearch + Kibana
Create a Twitter BOT service with GAE / P + Tweepy + RIOT API! (Part 1)
Create a Twitter BOT service with GAE / P + Tweepy + RIOT API! (Part 2)
The LXC Web Panel that can operate LXC with a browser was wonderful
I made a plug-in "EZPrinter" that easily outputs map PDF with QGIS.
Web App Development Practice: Create a Shift Creation Page with Django! (Introduction)
Hit a method of a class instance with the Python Bottle Web API
Create a "Congratulations 2.0" app that collects congratulatory voices with automatic phone answering with Twilio API x Python (Flask) x Heroku
(Note) A web application that uses TensorFlow to infer recommended song names [Create an execution environment with docker-compose]
Create a typed web app with Python's web framework "Fast API" and TypeScript / OpenAPI-Technology stack for machine learning web apps
Create a Python function decorator with Class