Python development [Tornado]: introduction and use, pythontornado
Tornado framework
Introduction:
Tornado is an open-source version of our Web server in FriendFeed and Its commonly used tools [1]. Tornado differs significantly from the current mainstream Web Server framework (including most Python frameworks): It is a non-blocking server and is fast. Tornado can process thousands of connections per second based on its non-blocking method and epoll application. Therefore, Tornado is an ideal framework for real-time Web services. Tornado is a Python web framework with an Asynchronous Network Library, initially developed on FriendFeed (a social service. By using non-blocking network I/O, Tornado can expand to thousands of open connections, making it an ideal choice for long polling, WebSockets, and other applications that require persistent connection to each user.
Installation:
C:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.9\sbin>pip3 install tornadoCollecting tornado Downloading tornado-4.5.1-cp36-cp36m-win_amd64.whl (422kB) 100% |████████████████████████████████| 430kB 16kB/sInstalling collected packages: tornadoSuccessfully installed tornado-4.5.1
You can install pip3 install tornado on Python3.6 successfully.
Simple Example:
import tornado.ioloopimport tornado.webclass MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world")def make_app(): return tornado.web.Application([ (r"/", MainHandler), ])if __name__ == "__main__": app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start()
After running the command, enter http: // 127.0.0.1: 8888 in the browser to access the file. Hello world is displayed. This example does not use any asynchronous feature of Tornado, but looks like a simple chat room.
Simple Web Services
1. Application Example:
Tornado is a framework for compiling responses to HTTP requests. As a programmer, your job is to write handler that responds to HTTP requests with specific conditions. The following is a basic example of a full-featured Tornado application:
Import tornado. httpserverimport tornado. ioloopimport tornado. optionsimport tornado. webfrom tornado. options import define, optionsdefine ("port", default = 8000, help = "run on the given port", type = int) # python hello. py -- port = 8000 specifies the running port. The default value is 8000. The input type is intclass IndexHandler (tornado. web. requestHandler): # processing class def get (self): # get request greeting = self. get_argument ('greeting ', 'Hello') # receives the greeting parameter. The default value is Hello se. Lf. write (greeting + ', friendly user! ') # Returned data if _ name _ = "_ main _": # This is a statement that really makes Tornado run. First, we use the options module of Tornado to parse the command line # And then we create an instance of the Tornado Application class. Handlers is the most important parameter passed to the Application class _ init _ method. # It tells Tornado which class should be used to respond to the request. Tornado. options. parse_command_line () app = tornado. web. application (handlers = [(r "/", IndexHandler)]) # The code from here will be used repeatedly: Once the Application object is created, we can pass it to the HTTPServer object of Tornado, # Then we can use the port we specified in the command line to listen (retrieve it through the options object .) # Finally, after the program is ready to receive HTTP requests, we will create a Tornado IOLoop instance. Http_server = tornado. httpserver. HTTPServer (app) http_server.listen (options. port) tornado. ioloop. IOLoop. instance (). start ()
Run the program directly or specify the Port:
$ python hello.py --port=8000
Access the corresponding port service through a browser and pass in the greeting parameter to obtain different results:
$ curl http://localhost:8000/Hello, friendly user!$ curl http://localhost:8000/?greeting=SalutationsSalutations, friendly user!
① Parameter handlers:
Let's take a look at this line in the hello. py example:
app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
Parameters hereHandlersIt is very important and deserves further research. It should be a list of tuples. The first element of each tuple is a regular expression for matching, and the second element isRequestHanlderClass. InHello. pyOnly one regular expression-RequestHanlderYes, but you can specify any number as needed.
② Use a regular expression to specify the path:
Tornado uses a regular expression in the tuples to match the path of the HTTP request. (This path is the part after the host name in the URL, excluding query strings and fragments .) Tornado regards these regular expressions as including the beginning and end of a row (that is, strings "/" are viewed as "^/$ ").
If a regular expression contains a capture group (that is, the part of the regular expression is enclosed in parentheses), the matched content will be uploaded as a parameter of the corresponding HTTP request.RequestHandlerObject. We will see its usage in the next example.
2. More complex examples:
Import textwrapimport tornado. httpserverimport tornado. ioloopimport tornado. optionsimport tornado. webfrom tornado. options import define, optionsdefine ("port", default = 8000, help = "run on the given port", type = int) class ReverseHandler (tornado. web. requestHandler): def get (self, input): self. write (input [:-1]) class WrapHandler (tornado. web. requestHandler): def post (self): text = self. get_argument ('text') width = self. get_argument ('width', 40) self. write (textwrap. fill (text, int (width) if _ name _ = "_ main _": tornado. options. parse_command_line () app = tornado. web. application (handlers = [(r "/reverse/(\ w +)", ReverseHandler), # use regular expression matching to access URLs and call different function classes (r "/wrap ", wrapHandler)]) http_server = tornado. httpserver. HTTPServer (app) http_server.listen (options. port) tornado. ioloop. IOLoop. instance (). start ()
The Startup Program is a basic Web Server framework for string operations. So far, you can use it to do two things. First,/reverse/string
OfGETThe request will return the reverse form of the specified string in the URL path.
$ curl http://localhost:8000/reverse/stresseddesserts$ curl http://localhost:8000/reverse/slipuppupils
Second,/wrap
OfPOSTRequest from parameterTextTo obtain the specified text, and return according to the parametersWidthSpecifies the text to be decorated in width. The following request specifies a string without width, so its output width is specifiedGet_argumentThe default value is 40 characters.
$ http://localhost:8000/wrap -d text=Lorem+ipsum+dolor+sit+amet,+consectetuer+adipiscing+elit.Lorem ipsum dolor sit amet, consectetueradipiscing elit.
More
So far, we have learnedRequestHandlerObject basics: how to obtain information from an incoming HTTP RequestGet_argumentAnd passedGetAndPostParameters) and write the HTTP Response (UseWriteMethod ). In addition, there are many things to learn. We will explain them in the following chapters. At the same time, there are someRequestHandlerAnd Tornado how to use it only need to remember.
1. HTTP method:
Examples discussed so far, eachRequestHandlerClass only defines the behavior of an HTTP method. However, it is possible and useful to define multiple methods in the same processing function. It is a good method to bind concepts-related functions to the same class. For example, you may write a processing function to process objects with a specific ID in the database.GETMethod, also usePOSTMethod. ImaginationGETMethod to return the information of this Part, andPOSTMethod To change the parts of this ID in the database:
# matched with (r"/widget/(\d+)", WidgetHandler)class WidgetHandler(tornado.web.RequestHandler): def get(self, widget_id): widget = retrieve_from_db(widget_id) self.write(widget.serialize()) def post(self, widget_id): widget = retrieve_from_db(widget_id) widget['foo'] = self.get_argument('foo') save_to_db(widget)
So far, we have only usedGETAndPOSTMethod, but Tornado supports any valid HTTP Request (GET,POST,PUT,DELETE,HEAD,OPTIONS). You can easily define the behavior of any of the above methods.RequestHandlerClass. The following is another example.HEADThe request only provides information based on whether frob exists.GETMethod returns the entire object:
# matched with (r"/frob/(\d+)", FrobHandler)class FrobHandler(tornado.web.RequestHandler): def head(self, frob_id): frob = retrieve_from_db(frob_id) if frob is not None: self.set_status(200) else: self.set_status(404) def get(self, frob_id): frob = retrieve_from_db(frob_id) self.write(frob.serialize())
2. HTTP status code:
From the code above, you can useRequestHandlerClassSet_status ()Explicitly set the HTTP status code. However, you need to remember that Tornado automatically sets the HTTP status code in some cases. The following is an outline of common situations:
404 Not FoundTornado will return a 404 (Not Found) response code when the HTTP Request Path cannot match any Mode corresponding to the RequestHandler class. 400 Bad Request if you call a get_argument function without a default value and no parameter with a given name is found, Tornado will automatically return a 400 (Bad Request) response code. 405 Method Not Allowed if the incoming request uses an HTTP Method Not defined in RequestHandler (for example, a POST request, but only the get Method is defined in the processing function ), tornado returns the 405 (Methos Not Allowed) response code. 500 Internal Server Error when the program encounters an Error that cannot exit, Tornado returns the 500 (Internal Server Error) response code. Any exceptions that are not captured in your code will also cause a 500 response code. 200 OK if the response is successful and no other return code is set, Tornado returns a 200 (OK) response code by default.
When any of the preceding errors occurs, Tornado sends a short clip containing the status code and error message to the client by default. If you want to replace the default error response with your own method, you can rewrite it.Write_errorMethod in yourRequestHandlerClass. For example, in the code listing 1-3, the version of the regular error message is added to the hello. py example.
import tornado.httpserverimport tornado.ioloopimport tornado.optionsimport tornado.webfrom tornado.options import define, optionsdefine("port", default=8000, help="run on the given port", type=int)class IndexHandler(tornado.web.RequestHandler): def get(self): greeting = self.get_argument('greeting', 'Hello') self.write(greeting + ', friendly user!') def write_error(self, status_code, **kwargs): self.write("Gosh darnit, user! You caused a %d error." % status_code)if __name__ == "__main__": tornado.options.parse_command_line() app = tornado.web.Application(handlers=[(r"/", IndexHandler)]) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()
When we tryPOSTRequest, the following response is returned. In general, we should get the default error response from Tornado, but because we OverwriteWrite_error, We will get something different:
$ curl -d foo=bar http://localhost:8000/Gosh darnit, user! You caused a 405 error.