Introduction and usage examples of Tarnado

Source: Internet
Author: User
Tags assert

Directory

    • Tarnado

    • Tarnado Source Installation

    • Tarnado Test procedure

    • Analysis of Application class

I. Tarnado INTRODUCTION

Recently in the study of Python, inadvertently contact the Tarnado, feel tarnado still fine so tarnado exactly what? Tarnado is a non-blocking Web server framework developed by Python that is very different from many mainstream web frameworks (and of course other web frameworks I really don't know), epoll and non-blocking ways so that he can connect thousands of times per second, Ideal for Web services with real-time. The following address is the official explanation of Tarnado

Two. Tarnado Source Installation

Go to the address above to download tornado-1.2.1.tar.gz

After decompression, locate this path in the CMD command box and install it as follows:

Note: After I test, this code can not be executed on the python3.5, on the 2.7 above, so it is recommended to install on the python2.7 to test and learn.

Three. Test procedures

After the installation is complete, open pycharm, create a new py file, write the following test code, after execution, enter the http://127.0.0.1:8888 in the browser will display Hello, world word, it is the installation success.

1 Import tornado.ioloop 2 import tornado.web 3  4 class MainHandler (Tornado.web.RequestHandler): 5     def get (self): 6         self.write ("Hello, World") 7  8 application = tornado.web.Application ([9     (R "/", MainHandler), ten]) if __name__ = = "__main__":     application.listen (8888)     tornado.ioloop.IOLoop.instance (). Start ()
Test Code

Four. Parsing of the application class

The following is finally going to be application, but before parsing, let's say a little bit about the execution flow of the test code.

1 #!/usr/bin/env Python 2 #-*-Coding:utf-8-*-3 # Zhou 4 # 2017/6/27 5  6 # import two Modules 7 import tornado.ioloop 8 Import Tornado.web 9 10 # 1. Load the class RequestHandler into memory 11 # 2. The class RequestHandler is passed as a parameter in the MainHandler 12 # 3. Load the class MainHandler into memory 13 # More than three steps will essentially not take any action, just load the class into memory for subsequent calls to Class MainHandler (Tornado.web.RequestHandler): 15     def get (self): +         self.write ("Hello, World") 17 18 19 # Plex This step begins to really create object 20 # 1. Class application creates an object, The name is Application21 # 2. R "/" This is the regular expression type/, which is the Url22 # 3 we entered in the browser. Pass the class MainHandler as a parameter to the application 23 # 4. This is just a variable []24 application = tornado.web.Application ([+     ] (r "/", MainHandler), [+]) if __name__ = = "__main__ ":     # # # # # # # # # # # # # # # # # # # # # # # # # # # # application Listen     Tornado.ioloop.IOLoop.instance (). Start ()
Introduction to the test procedure execution Process

The next step is to dissect the following line of code

Application =
A collection of request handlers that made up a Web application. Combine many requests processors to implement Web applications

1. Initialization process of application

 1 def __init__ (self, Handlers=none, default_host= "", Transforms=none, 2 Wsgi=false, **settings): 3 If TR Ansforms is None:4 self.transforms = [] 5 if Settings.get ("gzip"): 6 Self.transforms.append (G zipcontentencoding) 7 self.transforms.append (chunkedtransferencoding) 8 Else:9 self.transforms = Tran Sforms10 self.handlers = []11 self.named_handlers = {}12 Self.default_host = default_host13 self.settings = Settings14 Self.ui_modules = {}15 Self.ui_methods = {}16 Self._wsgi = wsgi17 self._load_ui_modules (setti Ngs.get ("Ui_modules", {})) Self._load_ui_methods (Settings.get ("Ui_methods", {})) if Self.settings.get ("Static_ Path "): Path = self.settings[" Static_path "]21 handlers = list (handlers or []) Static_url_prefi                        x = Settings.get ("Static_url_prefix", "/static/"), handlers = [25 (RE.EScape (Static_url_prefix) + R "(. *)", staticfilehandler,26 Dict (Path=path)), 27 (r "/(Favicon\.ico)", StaticFileHandler, Dict (Path=path)), (r "/(Robots\.txt)", StaticFileHandler , Dict (Path=path)), + Handlers30 if Handlers:self.add_handlers (". *$", handlers) # Aut         Omatically Reload Modified Modules33 if Self.settings.get ("Debug") and not wsgi:34 import autoreload35 Autoreload.start ()
Initialize Code

Code One

<1>. is to encapsulate the tranforms variable for the object application,

<2>. If the user does not specify the variable, the system defaults to the server and the client in the process of transmission between a certain compression, and to do a piece of transmission

################################################## #if transforms is None:    self.transforms = []if settings.get (" Gzip "):        self.transforms.append (gzipcontentencoding)    self.transforms.append (chunkedtransferencoding) else:    self.transforms = transforms################################################## #这里面主要包含了三个类:    Gzipcontentencoding (Outputtransform)        # gzip content encoding chunkedtransferencoding (outputtransform)    # chunked transfer Encoding Outputtransform ()                           # is the parent class of the above two classes        explained: A transform modifies the result of an HTTP request (e.g., GZIP encoding) 
   is primarily used to convert the results of an HTTP request, which can be gzip compression

Code two

<1>. is to encapsulate a series of variables for the object application, the two variables ui_modules and ui_methods are not understood for the time being and will be supplemented later.

Self.handlers = []self.named_handlers = {}self.default_host = Default_hostself.settings = Settingsself.ui_modules = {} Self.ui_methods = {}self._wsgi = Wsgi

Code Three

<1>. The main thing is the method of the module that encapsulates the UI for the object application, and the difference between the UI module and the method above, I think it should be the module and method that I define and the system default.

Self._load_ui_modules (Settings.get ("Ui_modules", {})) Self._load_ui_methods (Settings.get ("Ui_methods", {}))

He mainly calls two methods, where the first method is simply described (_load_ui_modules)

  Because the second method is the same as the modules.

1 def _load_ui_modules (self, modules): 2     if Type (modules) is types. Moduletype:3         Self._load_ui_modules (Dict ((N, getattr (modules, N)) 4 for                                    N in dir (modules)) 5     Elif Isinstance (modules, list): 6 for         m in Modules:self._load_ui_modules (m) 7     Else:8         assert isinstance (modules , Dict) 9         for name, CLS in Modules.iteritems ():             try:11                 if Issubclass (CLS, uimodule):                     self.ui_ Modules[name] = Cls13             except typeerror:14                 Pass
_load_ui_modules Source Code

For the above source code parsing

# Wrap the incoming module modules all into a dictionary in the form of ui_modules variable def _load_ui_modules (self, modules): # Types is a. py file, he is mainly to define some simple functions, similar to the built-in functions can be used directly to use the types inside the description of the Moduletype is: Moduletype = Type (SYS) is the type of sys <type ' Module ' ># here is actually to judge the outgoing modules is not a module type, if it is to turn it into a dictionary form recursive judgment if Type (modules) is types. Moduletype:        self._load_ui_modules (Dict ((N, getattr (modules, N))                                   for N in dir (modules)) #判断modules是不是一个列表, If it is a list, the elements inside the list are re-entered into the method to invoke                             elif isinstance (modules, list): for M in Modules:self._load_ui_modules (m) else:# Here is an assertion mechanism, which means that modules must be a dictionary form assert isinstance (modules, dict) # because modules is a dictionary, assigning keys and values to name and CLS, respectively, Then determine the value of each key The CLS is not a subclass of Uimodule, and if it is # Add this value to a variable in the previous package self.ui_modules[name] = clsfor name, cls in Modules.iteritems (): Try:if Issubclass (CLS, uimodule):                    self.ui_modules[name] = clsexcept Typeerror:pass

Code Four

<1>. It defines a series of variables, the most important of which is handler, which leads to a class StaticFileHandler and this class inherits RequestHandler because there is no object in this class created here. So here is no longer to dig into the real call time to pay attention to.

   But from the conditional statement, we can see that when the setting does not contain static, it does not create these variables, which is to be noted.

# defines a series of variables such as Handlers,path,static_url_prefix   # When the settings contains the Static_path key, the variables will be defined         if Self.settings.get ("Static_path"):    Path = self.settings["Static_path"]    handlers = list (handlers or [])    Static_url_prefix = Settings.get ("Static_url_prefix",                                     "/static/")    handlers = [        (Re.escape (static_url_ Prefix) + R "(. *)", StaticFileHandler,         dict (Path=path)),        (r "/(Favicon\.ico)", StaticFileHandler, Dict (path =path)),        (r "/(Robots\.txt)", StaticFileHandler, Dict (Path=path)),    ] + handlers

Code Five

<1>. Adds the given processor to the system's list of processors. (This may actually be inaccurate, as we can see from code four that if the given URL contains Static_path, the given processor will change anyway)

If Handlers:self.add_handlers (". *$", handlers)

Code Six

Analysis of Add_handles function

def add_handlers (self, Host_pattern, host_handlers): # Add the given processor to the system's processor list, note that the host mode is processed sequentially,    Until the first one is matched this means that all processors of the given host must be added to the processor "" "appends the given handlers to our handler list.     Note that host patterns was processed sequentially in the order they were added, and only the first matching pattern is  Used. This means, all handlers for a given host must is added in a single add_handlers call. "" # if the given host mode is not ending with "$", add $ to the end if not Host_pattern.endswith ("$"): Host_pattern + = "$" handlers = []# the handlers with T  He wildcard Host_pattern is a special# case-they ' re added in the constructor but should has lower# precedence than the More-precise handlers added later.# If A wildcard handler group exists, it should always being last# in the list, so insert New groups just before it.# with wildcards is a special case, they have been added in the constructor method, but their priority is lower than some important processors, so should be added after # so if a processor group with wildcards exists, You should put them on the last side of a list, or they'll stick in front of him. # This is what this code means, if his pattern is '. *$ ', which means that he does not have wildcards, so put him in front of the last one, otherwise the wildcard will be added directly to the back if self.Handlers and Self.handlers[-1][0].pattern = = '. *$ ': Self.handlers.insert ( -1, (Re.compile (Host_pattern), handlers)) E Lse:self.handlers.append ((Re.compile (Host_pattern), handlers) # This is an analysis of our incoming host_handlers, the first adoption number to pattern, The second one gives handler if there are three, assign to Kwargs if there is no third kwargs=={}for spec in host_handlers:if type (spec) is type (()): Assert Len (Spec) in (2,                3) pattern = spec[0] Handler = spec[1]if len (spec) = = 3:kwargs = Spec[2]else: Kwargs = {}# After the assignment is complete, encapsulate these parameters into class Urlspec spec = Urlspec (pattern, Handler, Kwargs) # class Urlspec After creating the object spec, it will be re-given self.named _handlers add a Handlers key value pair, if the key value itself exists, will be written in the past log warning message handlers.append (spec) if Spec.name:if spec.name in Self.named_hand Lers:logging.warning ("Multiple handlers named%s; Replacing previous value ", Spec.name) self.named_handlers[spec.name] = Spec

  

Code Seven

Analysis of Class Urlspec

A spec object was created in code six, with the class Urlspec created

Class Urlspec (object): # The function of this class is mainly to make a specific mapping between the URL and handlers, the main embodiment should be the preceding variable name_handlers# the preceding assignment statement: self.named_handlers [Spec.name] = Spec "" "Specifies mappings between URLs and handlers." ""        def __init__ (self, pattern, handler_class, kwargs={}, Name=none): "" "Creates a urlspec.  Parameters: # passed in host mode pattern:regular expression to be matched.                    Any groups in the regex would be passed in to the handler ' s get/post/etc methods as arguments.        # This is not particularly understood, but it means that RequestHandler subclasses will be called Handler_class:requesthandler subclass to be invoked.                    Kwargs (optional): A Dictionary of additional arguments to being passed to the handler ' s constructor.  # This handler name is an extra parameter name (optional): a name for this handler. Used by Application.reverse_url. "" " If not Pattern.endswith (' $ '): pattern + = ' $ ' Self.regex = Re.compile (pattern) Self.handler_class = handle R_class Self.kwargs = kwArgs Self.name = Name Self._path, Self._group_count = Self._find_groups () 

Code Eight

Method Self._find_groups ()

This method is interesting, the following will take an example to explain

def _find_groups (self): # is to return a tuple to a specific URL, the following is an example, the contents of the parentheses will be converted to%s, the following 2 represents the number of parentheses brackets "" "Returns a tuple (reverse string,    Group count) for a URL. For Example:given the URL pattern/([0-9]{4})/([a-z-]+]/, this method would return ('/%s/%s/', 2). "" # get the pattern string form, remove the starting ^ and end of the $ symbol pattern = self.regex.patternif Pattern.startswith (' ^ '): pattern = pattern[1:]if Patt Ern.endswith (' $ '): pattern = pattern[:-1]# If the value of regex.groups should normally be equal to count, unless a particularly complex URL is returned, two Noneif Self.regex.group s! = Pattern.count (' ('): # The pattern is too complicated-simplistic matching,# so we can ' t-support reversing It.re  Turn (None, none) # This is the specific code that translates the URL into the Narimoto group, which is implemented by converting all the contents of the parentheses into%spieces = []for fragment in Pattern.split (' ('): if ') ' in Fragment:paren_loc = Fragment.index (') ') if Paren_loc >= 0:pieces.append ('%s ' + FRAGMENT[PA  Ren_loc + 1:]) Else:pieces.append (fragment) # Re-stitch the Picese into characters and return back to return (". Join (Pieces), self.regex.groups)
Import Repattern = "/abcd123 ([0-9]{4})/lwjeg ([a-z-]+)/" regex = re.compile (pattern) pieces = []print (Pattern.split (' (') ) for fragment in Pattern.split (' ('): if ') ' in fragment:# find ') ' Position paren_loc = Fragment.index (') ') ' If Paren_loc >= 0:# ') ' After all the content is spliced up pieces.append ('%s ' + Fragment[paren_loc + 1:]) Else:        pieces.append (fragment) print (pieces) Result: ['/ Abcd123 ', ' [0-9]{4}]/lwjeg ', ' [a-z-]+]/' ['/abcd123 ', '%s/lwjeg ', '%s/']

Code Nine

# Automatic to reload the changed module, this call is implemented by the Autorelaad module    # automatically reload modified modulesif self.settings.get ("Debug") and not Wsgi:import autoreload    Autoreload.start ()

So far

   application = Tornado.web.Application ([   
(r "/", MainHandler) ,
])

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.