The following is a simple Flask sample code that can be run, from which the sample code analyzes what the flask source is doing.
The Flask sample code is as follows:
fromFlaskImportFlaskapp= Flask (__name__) @app. Route ('/')defHello_world ():return 'Hello world!'@app. Route ('/user/<name>')defUser (name):return ''%nameif __name__=='__main__': App.run (Debug=true)
First Call app = Flask (__name__) to build a Flask instance. The Flask class is defined in the app.py file
""" The Flask object implements a WSGI application and acts as the central object. It is passed the name of the module or package of the application. Once It is created it would act as a central registry for the view functions, the URL rules, template configuration and Much more. The name of the package was used to resolve resources from inside the package or the folder The module was contained in Depending on if the package parameter resolves to an actual Python package (a folder with an:file: ' __init__.py ' File inside) or a standard module (just a '. py ' file).
Next analyze the work done by the App.route function
App.route is an adorner for Python. The specific function code is as follows:
def route (self, rule, * *options) :def decorator (f) := Options.pop (' endpoint', None) * *options )return F return decorator
The main point here is to associate the app instance with the corresponding view function by calling the Add_url_rule function.
defAdd_url_rule (self, rule, endpoint=none, View_func=none, * *options):ifEndpoint isNone:endpoint=_endpoint_from_view_func (view_func) options['Endpoint'] =Endpoint Methods= Options.pop ('Methods', None)#If the methods is not given and the View_func object knows its #methods We can use the that instead. If neither exists, we go with #a tuple of only ' GET ' as default. ifMethods isNone:methods= GetAttr (View_func,'Methods', None)or('GET',) ifisinstance (Methods, string_types):RaiseTypeError ('allowed methods has to be iterables of strings,' 'For example: @app. Route (..., methods=["POST"])') Methods= Set (Item.upper () forIteminchmethods)#Methods that should is addedRequired_methods = Set (GetAttr (View_func,'Required_methods', ())) #starting with Flask 0.8 The View_func object can disable and #force-enable the automatic options handling.Provide_automatic_options =getattr (View_func,'provide_automatic_options', None)ifProvide_automatic_options isNone:if 'OPTIONS' not inchmethods:provide_automatic_options=True Required_methods.add ('OPTIONS') Else: Provide_automatic_options=False#ADD the required methods now.Methods |=Required_methods Rule= self.url_rule_class (rule, methods=methods, * *options) Rule.provide_automatic_options=provide_automatic_options self.url_map.add (rule)ifView_func is notNone:old_func=Self.view_functions.get (Endpoint)ifOld_func is notNone andOld_func! =View_func:RaiseAssertionerror ('View function Mapping is overwriting an' 'existing endpoint function:%s'%endpoint) Self.view_functions[endpoint]= View_func
if the endpoint function is not specified , _ENDPOINT_FROM_VIEW_FUNC is specified as endpoint by function name. Next gets the specified methods. Url_rule_class (rule, methods=methods, **options) generates an instance of rule. Then url_map.add (rule) associates the rule with the flask instance. An instance of the map object is defined in the previous flask instance.
The source code for the Add function is as follows:
def Add (Self, rulefactory): for inch rulefactory.get_rules (self): rule.bind (self) self._rules.append (rule) Self._rules_by_ Endpoint.setdefault (Rule.endpoint, []). Append (rule) = True
This links the map to rule. where Rule.bind () call compile () to the expression in rule is an escape with '/static/<path:filename> ' as an example.
defcompile (self):ifSelf.map.host_matching:domain_rule= Self.hostor "' Else: Domain_rule= Self.subdomainor "'Self._trace=[] self._converters={} self._weights=[] Regex_parts= [] def_build_regex (rule): forconverter, arguments, variableinchparse_rule (rule):ifConverter isNone:regex_parts.append (re.escape (variable)) self._trace.append (False, Variab Le)) forPartinchVariable.split ('/'): ifpart:self._weights.append (0,-Len (part))) Else: ifArguments:c_args, C_kwargs=Parse_converter_args (arguments)Else: C_args=() C_kwargs={} convobj=self.get_converter (variable, converter, C_args, C_kwargs) Regex_parts.appe nd ('(? p<%s>%s)'%(variable, convobj.regex)) self._converters[variable]=convobj Self._trace.append ((True, variable)) Self._weights.append ((1, Convobj.weight)) Self.arguments.add (str (variable)) _build_regex (Domain_rule) regex_parts.append ('\\|') Self._trace.append (False,'|')) _build_regex (Self.is_leaf andSelf.ruleorSelf.rule.rstrip ('/')) if notself.is_leaf:self._trace.append (False,'/')) ifself.build_only:returnRegex= R'^%s%s$'%(U"'. Join (Regex_parts), ( notSelf.is_leafor notSelf.strict_slashes) and '( ? <!/) (? p<__suffix__>/?)' or "') Self._regex= Re.compile (regex, re. UNICODE)
The _build_regex function parses '/static/<path:filename> '. Retrieving the converter through path
Default_converters = { 'default': Unicodeconverter,'string': Unicodeconverter,' any': Anyconverter,'Path': Pathconverter,'int': Integerconverter,'float': Floatconverter,'UUID': Uuidconverter,}
The Pathconverter class is defined in the routing file. obtained through the path dictionary. The main acquisition here is the regex = ' [^/].*? ' This property. Then Regex_parts.append (' (? p<%s>%s) '% (variable, convobj.regex)) will ' filename ' and ' [^/].*? ' Fills the corresponding character. This generates the corresponding
URL Regular Expression
Python Learning Note-flask Learning (i)