| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862 |
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
- <title>werkzeug.routing — proxypool documentation</title>
-
- <link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
- <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
-
- <script type="text/javascript">
- var DOCUMENTATION_OPTIONS = {
- URL_ROOT: '../../',
- VERSION: '',
- COLLAPSE_INDEX: false,
- FILE_SUFFIX: '.html',
- HAS_SOURCE: true
- };
- </script>
- <script type="text/javascript" src="../../_static/jquery.js"></script>
- <script type="text/javascript" src="../../_static/underscore.js"></script>
- <script type="text/javascript" src="../../_static/doctools.js"></script>
- <link rel="index" title="Index" href="../../genindex.html" />
- <link rel="search" title="Search" href="../../search.html" />
- <link rel="top" title="proxypool documentation" href="../../index.html" />
- <link rel="up" title="Module code" href="../index.html" />
-
- <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
-
-
- <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
- </head>
- <body role="document">
-
- <div class="document">
- <div class="documentwrapper">
- <div class="bodywrapper">
- <div class="body" role="main">
-
- <h1>Source code for werkzeug.routing</h1><div class="highlight"><pre>
- <span></span><span class="c1"># -*- coding: utf-8 -*-</span>
- <span class="sd">"""</span>
- <span class="sd"> werkzeug.routing</span>
- <span class="sd"> ~~~~~~~~~~~~~~~~</span>
- <span class="sd"> When it comes to combining multiple controller or view functions (however</span>
- <span class="sd"> you want to call them) you need a dispatcher. A simple way would be</span>
- <span class="sd"> applying regular expression tests on the ``PATH_INFO`` and calling</span>
- <span class="sd"> registered callback functions that return the value then.</span>
- <span class="sd"> This module implements a much more powerful system than simple regular</span>
- <span class="sd"> expression matching because it can also convert values in the URLs and</span>
- <span class="sd"> build URLs.</span>
- <span class="sd"> Here a simple example that creates an URL map for an application with</span>
- <span class="sd"> two subdomains (www and kb) and some URL rules:</span>
- <span class="sd"> >>> m = Map([</span>
- <span class="sd"> ... # Static URLs</span>
- <span class="sd"> ... Rule('/', endpoint='static/index'),</span>
- <span class="sd"> ... Rule('/about', endpoint='static/about'),</span>
- <span class="sd"> ... Rule('/help', endpoint='static/help'),</span>
- <span class="sd"> ... # Knowledge Base</span>
- <span class="sd"> ... Subdomain('kb', [</span>
- <span class="sd"> ... Rule('/', endpoint='kb/index'),</span>
- <span class="sd"> ... Rule('/browse/', endpoint='kb/browse'),</span>
- <span class="sd"> ... Rule('/browse/<int:id>/', endpoint='kb/browse'),</span>
- <span class="sd"> ... Rule('/browse/<int:id>/<int:page>', endpoint='kb/browse')</span>
- <span class="sd"> ... ])</span>
- <span class="sd"> ... ], default_subdomain='www')</span>
- <span class="sd"> If the application doesn't use subdomains it's perfectly fine to not set</span>
- <span class="sd"> the default subdomain and not use the `Subdomain` rule factory. The endpoint</span>
- <span class="sd"> in the rules can be anything, for example import paths or unique</span>
- <span class="sd"> identifiers. The WSGI application can use those endpoints to get the</span>
- <span class="sd"> handler for that URL. It doesn't have to be a string at all but it's</span>
- <span class="sd"> recommended.</span>
- <span class="sd"> Now it's possible to create a URL adapter for one of the subdomains and</span>
- <span class="sd"> build URLs:</span>
- <span class="sd"> >>> c = m.bind('example.com')</span>
- <span class="sd"> >>> c.build("kb/browse", dict(id=42))</span>
- <span class="sd"> 'http://kb.example.com/browse/42/'</span>
- <span class="sd"> >>> c.build("kb/browse", dict())</span>
- <span class="sd"> 'http://kb.example.com/browse/'</span>
- <span class="sd"> >>> c.build("kb/browse", dict(id=42, page=3))</span>
- <span class="sd"> 'http://kb.example.com/browse/42/3'</span>
- <span class="sd"> >>> c.build("static/about")</span>
- <span class="sd"> '/about'</span>
- <span class="sd"> >>> c.build("static/index", force_external=True)</span>
- <span class="sd"> 'http://www.example.com/'</span>
- <span class="sd"> >>> c = m.bind('example.com', subdomain='kb')</span>
- <span class="sd"> >>> c.build("static/about")</span>
- <span class="sd"> 'http://www.example.com/about'</span>
- <span class="sd"> The first argument to bind is the server name *without* the subdomain.</span>
- <span class="sd"> Per default it will assume that the script is mounted on the root, but</span>
- <span class="sd"> often that's not the case so you can provide the real mount point as</span>
- <span class="sd"> second argument:</span>
- <span class="sd"> >>> c = m.bind('example.com', '/applications/example')</span>
- <span class="sd"> The third argument can be the subdomain, if not given the default</span>
- <span class="sd"> subdomain is used. For more details about binding have a look at the</span>
- <span class="sd"> documentation of the `MapAdapter`.</span>
- <span class="sd"> And here is how you can match URLs:</span>
- <span class="sd"> >>> c = m.bind('example.com')</span>
- <span class="sd"> >>> c.match("/")</span>
- <span class="sd"> ('static/index', {})</span>
- <span class="sd"> >>> c.match("/about")</span>
- <span class="sd"> ('static/about', {})</span>
- <span class="sd"> >>> c = m.bind('example.com', '/', 'kb')</span>
- <span class="sd"> >>> c.match("/")</span>
- <span class="sd"> ('kb/index', {})</span>
- <span class="sd"> >>> c.match("/browse/42/23")</span>
- <span class="sd"> ('kb/browse', {'id': 42, 'page': 23})</span>
- <span class="sd"> If matching fails you get a `NotFound` exception, if the rule thinks</span>
- <span class="sd"> it's a good idea to redirect (for example because the URL was defined</span>
- <span class="sd"> to have a slash at the end but the request was missing that slash) it</span>
- <span class="sd"> will raise a `RequestRedirect` exception. Both are subclasses of the</span>
- <span class="sd"> `HTTPException` so you can use those errors as responses in the</span>
- <span class="sd"> application.</span>
- <span class="sd"> If matching succeeded but the URL rule was incompatible to the given</span>
- <span class="sd"> method (for example there were only rules for `GET` and `HEAD` and</span>
- <span class="sd"> routing system tried to match a `POST` request) a `MethodNotAllowed`</span>
- <span class="sd"> method is raised.</span>
- <span class="sd"> :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.</span>
- <span class="sd"> :license: BSD, see LICENSE for more details.</span>
- <span class="sd">"""</span>
- <span class="kn">import</span> <span class="nn">difflib</span>
- <span class="kn">import</span> <span class="nn">re</span>
- <span class="kn">import</span> <span class="nn">uuid</span>
- <span class="kn">import</span> <span class="nn">posixpath</span>
- <span class="kn">from</span> <span class="nn">pprint</span> <span class="k">import</span> <span class="n">pformat</span>
- <span class="kn">from</span> <span class="nn">threading</span> <span class="k">import</span> <span class="n">Lock</span>
- <span class="kn">from</span> <span class="nn">werkzeug.urls</span> <span class="k">import</span> <span class="n">url_encode</span><span class="p">,</span> <span class="n">url_quote</span><span class="p">,</span> <span class="n">url_join</span>
- <span class="kn">from</span> <span class="nn">werkzeug.utils</span> <span class="k">import</span> <span class="n">redirect</span><span class="p">,</span> <span class="n">format_string</span>
- <span class="kn">from</span> <span class="nn">werkzeug.exceptions</span> <span class="k">import</span> <span class="n">HTTPException</span><span class="p">,</span> <span class="n">NotFound</span><span class="p">,</span> <span class="n">MethodNotAllowed</span><span class="p">,</span> \
- <span class="n">BadHost</span>
- <span class="kn">from</span> <span class="nn">werkzeug._internal</span> <span class="k">import</span> <span class="n">_get_environ</span><span class="p">,</span> <span class="n">_encode_idna</span>
- <span class="kn">from</span> <span class="nn">werkzeug._compat</span> <span class="k">import</span> <span class="n">itervalues</span><span class="p">,</span> <span class="n">iteritems</span><span class="p">,</span> <span class="n">to_unicode</span><span class="p">,</span> <span class="n">to_bytes</span><span class="p">,</span> \
- <span class="n">text_type</span><span class="p">,</span> <span class="n">string_types</span><span class="p">,</span> <span class="n">native_string_result</span><span class="p">,</span> \
- <span class="n">implements_to_string</span><span class="p">,</span> <span class="n">wsgi_decoding_dance</span>
- <span class="kn">from</span> <span class="nn">werkzeug.datastructures</span> <span class="k">import</span> <span class="n">ImmutableDict</span><span class="p">,</span> <span class="n">MultiDict</span>
- <span class="n">_rule_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">r'''</span>
- <span class="s1"> (?P<static>[^<]*) # static rule data</span>
- <span class="s1"> <</span>
- <span class="s1"> (?:</span>
- <span class="s1"> (?P<converter>[a-zA-Z_][a-zA-Z0-9_]*) # converter name</span>
- <span class="s1"> (?:\((?P<args>.*?)\))? # converter arguments</span>
- <span class="s1"> \: # variable delimiter</span>
- <span class="s1"> )?</span>
- <span class="s1"> (?P<variable>[a-zA-Z_][a-zA-Z0-9_]*) # variable name</span>
- <span class="s1"> ></span>
- <span class="s1">'''</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">VERBOSE</span><span class="p">)</span>
- <span class="n">_simple_rule_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">r'<([^>]+)>'</span><span class="p">)</span>
- <span class="n">_converter_args_re</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">r'''</span>
- <span class="s1"> ((?P<name>\w+)\s*=\s*)?</span>
- <span class="s1"> (?P<value></span>
- <span class="s1"> True|False|</span>
- <span class="s1"> \d+.\d+|</span>
- <span class="s1"> \d+.|</span>
- <span class="s1"> \d+|</span>
- <span class="s1"> \w+|</span>
- <span class="s1"> [urUR]?(?P<stringval>"[^"]*?"|'[^']*')</span>
- <span class="s1"> )\s*,</span>
- <span class="s1">'''</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">VERBOSE</span> <span class="o">|</span> <span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span><span class="p">)</span>
- <span class="n">_PYTHON_CONSTANTS</span> <span class="o">=</span> <span class="p">{</span>
- <span class="s1">'None'</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
- <span class="s1">'True'</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
- <span class="s1">'False'</span><span class="p">:</span> <span class="kc">False</span>
- <span class="p">}</span>
- <span class="k">def</span> <span class="nf">_pythonize</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
- <span class="k">if</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">_PYTHON_CONSTANTS</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">_PYTHON_CONSTANTS</span><span class="p">[</span><span class="n">value</span><span class="p">]</span>
- <span class="k">for</span> <span class="n">convert</span> <span class="ow">in</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">:</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">convert</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
- <span class="k">pass</span>
- <span class="k">if</span> <span class="n">value</span><span class="p">[:</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="n">value</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">:]</span> <span class="ow">and</span> <span class="n">value</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="s1">'"</span><span class="se">\'</span><span class="s1">'</span><span class="p">:</span>
- <span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
- <span class="k">return</span> <span class="n">text_type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">parse_converter_args</span><span class="p">(</span><span class="n">argstr</span><span class="p">):</span>
- <span class="n">argstr</span> <span class="o">+=</span> <span class="s1">','</span>
- <span class="n">args</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="n">kwargs</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">_converter_args_re</span><span class="o">.</span><span class="n">finditer</span><span class="p">(</span><span class="n">argstr</span><span class="p">):</span>
- <span class="n">value</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">'stringval'</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">value</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">'value'</span><span class="p">)</span>
- <span class="n">value</span> <span class="o">=</span> <span class="n">_pythonize</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="n">item</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">'name'</span><span class="p">):</span>
- <span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">name</span> <span class="o">=</span> <span class="n">item</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="s1">'name'</span><span class="p">)</span>
- <span class="n">kwargs</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
- <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">args</span><span class="p">),</span> <span class="n">kwargs</span>
- <span class="k">def</span> <span class="nf">parse_rule</span><span class="p">(</span><span class="n">rule</span><span class="p">):</span>
- <span class="sd">"""Parse a rule and return it as generator. Each iteration yields tuples</span>
- <span class="sd"> in the form ``(converter, arguments, variable)``. If the converter is</span>
- <span class="sd"> `None` it's a static url part, otherwise it's a dynamic one.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="n">pos</span> <span class="o">=</span> <span class="mi">0</span>
- <span class="n">end</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">rule</span><span class="p">)</span>
- <span class="n">do_match</span> <span class="o">=</span> <span class="n">_rule_re</span><span class="o">.</span><span class="n">match</span>
- <span class="n">used_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
- <span class="k">while</span> <span class="n">pos</span> <span class="o"><</span> <span class="n">end</span><span class="p">:</span>
- <span class="n">m</span> <span class="o">=</span> <span class="n">do_match</span><span class="p">(</span><span class="n">rule</span><span class="p">,</span> <span class="n">pos</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">m</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">break</span>
- <span class="n">data</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s1">'static'</span><span class="p">]:</span>
- <span class="k">yield</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="s1">'static'</span><span class="p">]</span>
- <span class="n">variable</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s1">'variable'</span><span class="p">]</span>
- <span class="n">converter</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s1">'converter'</span><span class="p">]</span> <span class="ow">or</span> <span class="s1">'default'</span>
- <span class="k">if</span> <span class="n">variable</span> <span class="ow">in</span> <span class="n">used_names</span><span class="p">:</span>
- <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'variable name </span><span class="si">%r</span><span class="s1"> used twice.'</span> <span class="o">%</span> <span class="n">variable</span><span class="p">)</span>
- <span class="n">used_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">variable</span><span class="p">)</span>
- <span class="k">yield</span> <span class="n">converter</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="s1">'args'</span><span class="p">]</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">,</span> <span class="n">variable</span>
- <span class="n">pos</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">end</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">pos</span> <span class="o"><</span> <span class="n">end</span><span class="p">:</span>
- <span class="n">remaining</span> <span class="o">=</span> <span class="n">rule</span><span class="p">[</span><span class="n">pos</span><span class="p">:]</span>
- <span class="k">if</span> <span class="s1">'>'</span> <span class="ow">in</span> <span class="n">remaining</span> <span class="ow">or</span> <span class="s1">'<'</span> <span class="ow">in</span> <span class="n">remaining</span><span class="p">:</span>
- <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'malformed url rule: </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span> <span class="n">rule</span><span class="p">)</span>
- <span class="k">yield</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">remaining</span>
- <span class="k">class</span> <span class="nc">RoutingException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
- <span class="sd">"""Special exceptions that require the application to redirect, notifying</span>
- <span class="sd"> about missing urls, etc.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">class</span> <span class="nc">RequestRedirect</span><span class="p">(</span><span class="n">HTTPException</span><span class="p">,</span> <span class="n">RoutingException</span><span class="p">):</span>
- <span class="sd">"""Raise if the map requests a redirect. This is for example the case if</span>
- <span class="sd"> `strict_slashes` are activated and an url that requires a trailing slash.</span>
- <span class="sd"> The attribute `new_url` contains the absolute destination url.</span>
- <span class="sd"> """</span>
- <span class="n">code</span> <span class="o">=</span> <span class="mi">301</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_url</span><span class="p">):</span>
- <span class="n">RoutingException</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new_url</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">new_url</span> <span class="o">=</span> <span class="n">new_url</span>
- <span class="k">def</span> <span class="nf">get_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">redirect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">new_url</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">code</span><span class="p">)</span>
- <span class="k">class</span> <span class="nc">RequestSlash</span><span class="p">(</span><span class="n">RoutingException</span><span class="p">):</span>
- <span class="sd">"""Internal exception."""</span>
- <span class="k">class</span> <span class="nc">RequestAliasRedirect</span><span class="p">(</span><span class="n">RoutingException</span><span class="p">):</span>
- <span class="sd">"""This rule is an alias and wants to redirect to the canonical URL."""</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">matched_values</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">matched_values</span> <span class="o">=</span> <span class="n">matched_values</span>
- <span class="k">class</span> <span class="nc">BuildError</span><span class="p">(</span><span class="n">RoutingException</span><span class="p">,</span> <span class="ne">LookupError</span><span class="p">):</span>
- <span class="sd">"""Raised if the build system cannot find a URL for an endpoint with the</span>
- <span class="sd"> values provided.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">adapter</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="ne">LookupError</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span> <span class="o">=</span> <span class="n">endpoint</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">values</span> <span class="o">=</span> <span class="n">values</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="o">=</span> <span class="n">method</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">suggested</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">closest_rule</span><span class="p">(</span><span class="n">adapter</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">closest_rule</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">adapter</span><span class="p">):</span>
- <span class="k">def</span> <span class="nf">score_rule</span><span class="p">(</span><span class="n">rule</span><span class="p">):</span>
- <span class="k">return</span> <span class="nb">sum</span><span class="p">([</span>
- <span class="mf">0.98</span> <span class="o">*</span> <span class="n">difflib</span><span class="o">.</span><span class="n">SequenceMatcher</span><span class="p">(</span>
- <span class="kc">None</span><span class="p">,</span> <span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span>
- <span class="p">)</span><span class="o">.</span><span class="n">ratio</span><span class="p">(),</span>
- <span class="mf">0.01</span> <span class="o">*</span> <span class="nb">bool</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">values</span> <span class="ow">or</span> <span class="p">())</span><span class="o">.</span><span class="n">issubset</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">arguments</span><span class="p">)),</span>
- <span class="mf">0.01</span> <span class="o">*</span> <span class="nb">bool</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">methods</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="ow">in</span> <span class="n">rule</span><span class="o">.</span><span class="n">methods</span><span class="p">)</span>
- <span class="p">])</span>
- <span class="k">if</span> <span class="n">adapter</span> <span class="ow">and</span> <span class="n">adapter</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">_rules</span><span class="p">:</span>
- <span class="k">return</span> <span class="nb">max</span><span class="p">(</span><span class="n">adapter</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">_rules</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">score_rule</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="k">return</span> <span class="kc">None</span>
- <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="n">message</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"Could not build url for endpoint </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span><span class="p">)</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span><span class="p">:</span>
- <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">" (</span><span class="si">%r</span><span class="s2">)"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span><span class="p">)</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">values</span><span class="p">:</span>
- <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">" with values </span><span class="si">%r</span><span class="s2">"</span> <span class="o">%</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">values</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
- <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"."</span><span class="p">)</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">suggested</span><span class="p">:</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">suggested</span><span class="o">.</span><span class="n">endpoint</span><span class="p">:</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">suggested</span><span class="o">.</span><span class="n">methods</span><span class="p">:</span>
- <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">" Did you mean to use methods </span><span class="si">%r</span><span class="s2">?"</span> <span class="o">%</span> <span class="nb">sorted</span><span class="p">(</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">suggested</span><span class="o">.</span><span class="n">methods</span>
- <span class="p">))</span>
- <span class="n">missing_values</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">suggested</span><span class="o">.</span><span class="n">arguments</span><span class="o">.</span><span class="n">union</span><span class="p">(</span>
- <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">suggested</span><span class="o">.</span><span class="n">defaults</span> <span class="ow">or</span> <span class="p">())</span>
- <span class="p">)</span> <span class="o">-</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">values</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
- <span class="k">if</span> <span class="n">missing_values</span><span class="p">:</span>
- <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
- <span class="s2">" Did you forget to specify values </span><span class="si">%r</span><span class="s2">?"</span> <span class="o">%</span>
- <span class="nb">sorted</span><span class="p">(</span><span class="n">missing_values</span><span class="p">)</span>
- <span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">message</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
- <span class="s2">" Did you mean </span><span class="si">%r</span><span class="s2"> instead?"</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">suggested</span><span class="o">.</span><span class="n">endpoint</span>
- <span class="p">)</span>
- <span class="k">return</span> <span class="s2">""</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
- <span class="k">class</span> <span class="nc">ValidationError</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">):</span>
- <span class="sd">"""Validation error. If a rule converter raises this exception the rule</span>
- <span class="sd"> does not match the current URL and the next URL is tried.</span>
- <span class="sd"> """</span>
- <span class="k">class</span> <span class="nc">RuleFactory</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
- <span class="sd">"""As soon as you have more complex URL setups it's a good idea to use rule</span>
- <span class="sd"> factories to avoid repetitive tasks. Some of them are builtin, others can</span>
- <span class="sd"> be added by subclassing `RuleFactory` and overriding `get_rules`.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">get_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">):</span>
- <span class="sd">"""Subclasses of `RuleFactory` have to override this method and return</span>
- <span class="sd"> an iterable of rules."""</span>
- <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">()</span>
- <span class="k">class</span> <span class="nc">Subdomain</span><span class="p">(</span><span class="n">RuleFactory</span><span class="p">):</span>
- <span class="sd">"""All URLs provided by this factory have the subdomain set to a</span>
- <span class="sd"> specific domain. For example if you want to use the subdomain for</span>
- <span class="sd"> the current language this can be a good setup::</span>
- <span class="sd"> url_map = Map([</span>
- <span class="sd"> Rule('/', endpoint='#select_language'),</span>
- <span class="sd"> Subdomain('<string(length=2):lang_code>', [</span>
- <span class="sd"> Rule('/', endpoint='index'),</span>
- <span class="sd"> Rule('/about', endpoint='about'),</span>
- <span class="sd"> Rule('/help', endpoint='help')</span>
- <span class="sd"> ])</span>
- <span class="sd"> ])</span>
- <span class="sd"> All the rules except for the ``'#select_language'`` endpoint will now</span>
- <span class="sd"> listen on a two letter long subdomain that holds the language code</span>
- <span class="sd"> for the current request.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subdomain</span><span class="p">,</span> <span class="n">rules</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="o">=</span> <span class="n">subdomain</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">rules</span> <span class="o">=</span> <span class="n">rules</span>
- <span class="k">def</span> <span class="nf">get_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">):</span>
- <span class="k">for</span> <span class="n">rulefactory</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="p">:</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">rulefactory</span><span class="o">.</span><span class="n">get_rules</span><span class="p">(</span><span class="nb">map</span><span class="p">):</span>
- <span class="n">rule</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">empty</span><span class="p">()</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">subdomain</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span>
- <span class="k">yield</span> <span class="n">rule</span>
- <span class="k">class</span> <span class="nc">Submount</span><span class="p">(</span><span class="n">RuleFactory</span><span class="p">):</span>
- <span class="sd">"""Like `Subdomain` but prefixes the URL rule with a given string::</span>
- <span class="sd"> url_map = Map([</span>
- <span class="sd"> Rule('/', endpoint='index'),</span>
- <span class="sd"> Submount('/blog', [</span>
- <span class="sd"> Rule('/', endpoint='blog/index'),</span>
- <span class="sd"> Rule('/entry/<entry_slug>', endpoint='blog/show')</span>
- <span class="sd"> ])</span>
- <span class="sd"> ])</span>
- <span class="sd"> Now the rule ``'blog/show'`` matches ``/blog/entry/<entry_slug>``.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">rules</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">rules</span> <span class="o">=</span> <span class="n">rules</span>
- <span class="k">def</span> <span class="nf">get_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">):</span>
- <span class="k">for</span> <span class="n">rulefactory</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="p">:</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">rulefactory</span><span class="o">.</span><span class="n">get_rules</span><span class="p">(</span><span class="nb">map</span><span class="p">):</span>
- <span class="n">rule</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">empty</span><span class="p">()</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">rule</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">+</span> <span class="n">rule</span><span class="o">.</span><span class="n">rule</span>
- <span class="k">yield</span> <span class="n">rule</span>
- <span class="k">class</span> <span class="nc">EndpointPrefix</span><span class="p">(</span><span class="n">RuleFactory</span><span class="p">):</span>
- <span class="sd">"""Prefixes all endpoints (which must be strings for this factory) with</span>
- <span class="sd"> another string. This can be useful for sub applications::</span>
- <span class="sd"> url_map = Map([</span>
- <span class="sd"> Rule('/', endpoint='index'),</span>
- <span class="sd"> EndpointPrefix('blog/', [Submount('/blog', [</span>
- <span class="sd"> Rule('/', endpoint='index'),</span>
- <span class="sd"> Rule('/entry/<entry_slug>', endpoint='show')</span>
- <span class="sd"> ])])</span>
- <span class="sd"> ])</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">prefix</span><span class="p">,</span> <span class="n">rules</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">=</span> <span class="n">prefix</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">rules</span> <span class="o">=</span> <span class="n">rules</span>
- <span class="k">def</span> <span class="nf">get_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">):</span>
- <span class="k">for</span> <span class="n">rulefactory</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="p">:</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">rulefactory</span><span class="o">.</span><span class="n">get_rules</span><span class="p">(</span><span class="nb">map</span><span class="p">):</span>
- <span class="n">rule</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">empty</span><span class="p">()</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">+</span> <span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span>
- <span class="k">yield</span> <span class="n">rule</span>
- <span class="k">class</span> <span class="nc">RuleTemplate</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
- <span class="sd">"""Returns copies of the rules wrapped and expands string templates in</span>
- <span class="sd"> the endpoint, rule, defaults or subdomain sections.</span>
- <span class="sd"> Here a small example for such a rule template::</span>
- <span class="sd"> from werkzeug.routing import Map, Rule, RuleTemplate</span>
- <span class="sd"> resource = RuleTemplate([</span>
- <span class="sd"> Rule('/$name/', endpoint='$name.list'),</span>
- <span class="sd"> Rule('/$name/<int:id>', endpoint='$name.show')</span>
- <span class="sd"> ])</span>
- <span class="sd"> url_map = Map([resource(name='user'), resource(name='page')])</span>
- <span class="sd"> When a rule template is called the keyword arguments are used to</span>
- <span class="sd"> replace the placeholders in all the string parameters.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rules</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">rules</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">rules</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">RuleTemplateFactory</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
- <span class="k">class</span> <span class="nc">RuleTemplateFactory</span><span class="p">(</span><span class="n">RuleFactory</span><span class="p">):</span>
- <span class="sd">"""A factory that fills in template variables into rules. Used by</span>
- <span class="sd"> `RuleTemplate` internally.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rules</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">rules</span> <span class="o">=</span> <span class="n">rules</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">context</span> <span class="o">=</span> <span class="n">context</span>
- <span class="k">def</span> <span class="nf">get_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">):</span>
- <span class="k">for</span> <span class="n">rulefactory</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">rules</span><span class="p">:</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">rulefactory</span><span class="o">.</span><span class="n">get_rules</span><span class="p">(</span><span class="nb">map</span><span class="p">):</span>
- <span class="n">new_defaults</span> <span class="o">=</span> <span class="n">subdomain</span> <span class="o">=</span> <span class="kc">None</span>
- <span class="k">if</span> <span class="n">rule</span><span class="o">.</span><span class="n">defaults</span><span class="p">:</span>
- <span class="n">new_defaults</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">iteritems</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">defaults</span><span class="p">):</span>
- <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">string_types</span><span class="p">):</span>
- <span class="n">value</span> <span class="o">=</span> <span class="n">format_string</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">)</span>
- <span class="n">new_defaults</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
- <span class="k">if</span> <span class="n">rule</span><span class="o">.</span><span class="n">subdomain</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">subdomain</span> <span class="o">=</span> <span class="n">format_string</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">subdomain</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">)</span>
- <span class="n">new_endpoint</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span>
- <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">new_endpoint</span><span class="p">,</span> <span class="n">string_types</span><span class="p">):</span>
- <span class="n">new_endpoint</span> <span class="o">=</span> <span class="n">format_string</span><span class="p">(</span><span class="n">new_endpoint</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">)</span>
- <span class="k">yield</span> <span class="n">Rule</span><span class="p">(</span>
- <span class="n">format_string</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">rule</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">),</span>
- <span class="n">new_defaults</span><span class="p">,</span>
- <span class="n">subdomain</span><span class="p">,</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">methods</span><span class="p">,</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">build_only</span><span class="p">,</span>
- <span class="n">new_endpoint</span><span class="p">,</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">strict_slashes</span>
- <span class="p">)</span>
- <span class="nd">@implements_to_string</span>
- <span class="k">class</span> <span class="nc">Rule</span><span class="p">(</span><span class="n">RuleFactory</span><span class="p">):</span>
- <span class="sd">"""A Rule represents one URL pattern. There are some options for `Rule`</span>
- <span class="sd"> that change the way it behaves and are passed to the `Rule` constructor.</span>
- <span class="sd"> Note that besides the rule-string all arguments *must* be keyword arguments</span>
- <span class="sd"> in order to not break the application on Werkzeug upgrades.</span>
- <span class="sd"> `string`</span>
- <span class="sd"> Rule strings basically are just normal URL paths with placeholders in</span>
- <span class="sd"> the format ``<converter(arguments):name>`` where the converter and the</span>
- <span class="sd"> arguments are optional. If no converter is defined the `default`</span>
- <span class="sd"> converter is used which means `string` in the normal configuration.</span>
- <span class="sd"> URL rules that end with a slash are branch URLs, others are leaves.</span>
- <span class="sd"> If you have `strict_slashes` enabled (which is the default), all</span>
- <span class="sd"> branch URLs that are matched without a trailing slash will trigger a</span>
- <span class="sd"> redirect to the same URL with the missing slash appended.</span>
- <span class="sd"> The converters are defined on the `Map`.</span>
- <span class="sd"> `endpoint`</span>
- <span class="sd"> The endpoint for this rule. This can be anything. A reference to a</span>
- <span class="sd"> function, a string, a number etc. The preferred way is using a string</span>
- <span class="sd"> because the endpoint is used for URL generation.</span>
- <span class="sd"> `defaults`</span>
- <span class="sd"> An optional dict with defaults for other rules with the same endpoint.</span>
- <span class="sd"> This is a bit tricky but useful if you want to have unique URLs::</span>
- <span class="sd"> url_map = Map([</span>
- <span class="sd"> Rule('/all/', defaults={'page': 1}, endpoint='all_entries'),</span>
- <span class="sd"> Rule('/all/page/<int:page>', endpoint='all_entries')</span>
- <span class="sd"> ])</span>
- <span class="sd"> If a user now visits ``http://example.com/all/page/1`` he will be</span>
- <span class="sd"> redirected to ``http://example.com/all/``. If `redirect_defaults` is</span>
- <span class="sd"> disabled on the `Map` instance this will only affect the URL</span>
- <span class="sd"> generation.</span>
- <span class="sd"> `subdomain`</span>
- <span class="sd"> The subdomain rule string for this rule. If not specified the rule</span>
- <span class="sd"> only matches for the `default_subdomain` of the map. If the map is</span>
- <span class="sd"> not bound to a subdomain this feature is disabled.</span>
- <span class="sd"> Can be useful if you want to have user profiles on different subdomains</span>
- <span class="sd"> and all subdomains are forwarded to your application::</span>
- <span class="sd"> url_map = Map([</span>
- <span class="sd"> Rule('/', subdomain='<username>', endpoint='user/homepage'),</span>
- <span class="sd"> Rule('/stats', subdomain='<username>', endpoint='user/stats')</span>
- <span class="sd"> ])</span>
- <span class="sd"> `methods`</span>
- <span class="sd"> A sequence of http methods this rule applies to. If not specified, all</span>
- <span class="sd"> methods are allowed. For example this can be useful if you want different</span>
- <span class="sd"> endpoints for `POST` and `GET`. If methods are defined and the path</span>
- <span class="sd"> matches but the method matched against is not in this list or in the</span>
- <span class="sd"> list of another rule for that path the error raised is of the type</span>
- <span class="sd"> `MethodNotAllowed` rather than `NotFound`. If `GET` is present in the</span>
- <span class="sd"> list of methods and `HEAD` is not, `HEAD` is added automatically.</span>
- <span class="sd"> .. versionchanged:: 0.6.1</span>
- <span class="sd"> `HEAD` is now automatically added to the methods if `GET` is</span>
- <span class="sd"> present. The reason for this is that existing code often did not</span>
- <span class="sd"> work properly in servers not rewriting `HEAD` to `GET`</span>
- <span class="sd"> automatically and it was not documented how `HEAD` should be</span>
- <span class="sd"> treated. This was considered a bug in Werkzeug because of that.</span>
- <span class="sd"> `strict_slashes`</span>
- <span class="sd"> Override the `Map` setting for `strict_slashes` only for this rule. If</span>
- <span class="sd"> not specified the `Map` setting is used.</span>
- <span class="sd"> `build_only`</span>
- <span class="sd"> Set this to True and the rule will never match but will create a URL</span>
- <span class="sd"> that can be build. This is useful if you have resources on a subdomain</span>
- <span class="sd"> or folder that are not handled by the WSGI application (like static data)</span>
- <span class="sd"> `redirect_to`</span>
- <span class="sd"> If given this must be either a string or callable. In case of a</span>
- <span class="sd"> callable it's called with the url adapter that triggered the match and</span>
- <span class="sd"> the values of the URL as keyword arguments and has to return the target</span>
- <span class="sd"> for the redirect, otherwise it has to be a string with placeholders in</span>
- <span class="sd"> rule syntax::</span>
- <span class="sd"> def foo_with_slug(adapter, id):</span>
- <span class="sd"> # ask the database for the slug for the old id. this of</span>
- <span class="sd"> # course has nothing to do with werkzeug.</span>
- <span class="sd"> return 'foo/' + Foo.get_slug_for_id(id)</span>
- <span class="sd"> url_map = Map([</span>
- <span class="sd"> Rule('/foo/<slug>', endpoint='foo'),</span>
- <span class="sd"> Rule('/some/old/url/<slug>', redirect_to='foo/<slug>'),</span>
- <span class="sd"> Rule('/other/old/url/<int:id>', redirect_to=foo_with_slug)</span>
- <span class="sd"> ])</span>
- <span class="sd"> When the rule is matched the routing system will raise a</span>
- <span class="sd"> `RequestRedirect` exception with the target for the redirect.</span>
- <span class="sd"> Keep in mind that the URL will be joined against the URL root of the</span>
- <span class="sd"> script so don't use a leading slash on the target URL unless you</span>
- <span class="sd"> really mean root of that domain.</span>
- <span class="sd"> `alias`</span>
- <span class="sd"> If enabled this rule serves as an alias for another rule with the same</span>
- <span class="sd"> endpoint and arguments.</span>
- <span class="sd"> `host`</span>
- <span class="sd"> If provided and the URL map has host matching enabled this can be</span>
- <span class="sd"> used to provide a match rule for the whole host. This also means</span>
- <span class="sd"> that the subdomain feature is disabled.</span>
- <span class="sd"> .. versionadded:: 0.7</span>
- <span class="sd"> The `alias` and `host` parameters were added.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">string</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">subdomain</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
- <span class="n">build_only</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">strict_slashes</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
- <span class="n">redirect_to</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">alias</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">host</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="n">string</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'/'</span><span class="p">):</span>
- <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'urls must start with a leading slash'</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">rule</span> <span class="o">=</span> <span class="n">string</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">is_leaf</span> <span class="o">=</span> <span class="ow">not</span> <span class="n">string</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">map</span> <span class="o">=</span> <span class="kc">None</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span> <span class="o">=</span> <span class="n">strict_slashes</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="o">=</span> <span class="n">subdomain</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="o">=</span> <span class="n">host</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">defaults</span> <span class="o">=</span> <span class="n">defaults</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">build_only</span> <span class="o">=</span> <span class="n">build_only</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">alias</span> <span class="o">=</span> <span class="n">alias</span>
- <span class="k">if</span> <span class="n">methods</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">methods</span> <span class="o">=</span> <span class="kc">None</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">methods</span> <span class="o">=</span> <span class="nb">set</span><span class="p">([</span><span class="n">x</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">methods</span><span class="p">])</span>
- <span class="k">if</span> <span class="s1">'HEAD'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">methods</span> <span class="ow">and</span> <span class="s1">'GET'</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">methods</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">methods</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">'HEAD'</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span> <span class="o">=</span> <span class="n">endpoint</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">redirect_to</span> <span class="o">=</span> <span class="n">redirect_to</span>
- <span class="k">if</span> <span class="n">defaults</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">defaults</span><span class="p">))</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_converters</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_regex</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_weights</span> <span class="o">=</span> <span class="kc">None</span>
- <span class="k">def</span> <span class="nf">empty</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="sd">"""</span>
- <span class="sd"> Return an unbound copy of this rule.</span>
- <span class="sd"> This can be useful if want to reuse an already bound URL for another</span>
- <span class="sd"> map. See ``get_empty_kwargs`` to override what keyword arguments are</span>
- <span class="sd"> provided to the new copy.</span>
- <span class="sd"> """</span>
- <span class="k">return</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)(</span><span class="bp">self</span><span class="o">.</span><span class="n">rule</span><span class="p">,</span> <span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">get_empty_kwargs</span><span class="p">())</span>
- <span class="k">def</span> <span class="nf">get_empty_kwargs</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="sd">"""</span>
- <span class="sd"> Provides kwargs for instantiating empty copy with empty()</span>
- <span class="sd"> Use this method to provide custom keyword arguments to the subclass of</span>
- <span class="sd"> ``Rule`` when calling ``some_rule.empty()``. Helpful when the subclass</span>
- <span class="sd"> has custom keyword arguments that are needed at instantiation.</span>
- <span class="sd"> Must return a ``dict`` that will be provided as kwargs to the new</span>
- <span class="sd"> instance of ``Rule``, following the initial ``self.rule`` value which</span>
- <span class="sd"> is always provided as the first, required positional argument.</span>
- <span class="sd"> """</span>
- <span class="n">defaults</span> <span class="o">=</span> <span class="kc">None</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">:</span>
- <span class="n">defaults</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">)</span>
- <span class="k">return</span> <span class="nb">dict</span><span class="p">(</span><span class="n">defaults</span><span class="o">=</span><span class="n">defaults</span><span class="p">,</span> <span class="n">subdomain</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span><span class="p">,</span>
- <span class="n">methods</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">methods</span><span class="p">,</span> <span class="n">build_only</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">build_only</span><span class="p">,</span>
- <span class="n">endpoint</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">strict_slashes</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span><span class="p">,</span>
- <span class="n">redirect_to</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">redirect_to</span><span class="p">,</span> <span class="n">alias</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">alias</span><span class="p">,</span>
- <span class="n">host</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">host</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">get_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">):</span>
- <span class="k">yield</span> <span class="bp">self</span>
- <span class="k">def</span> <span class="nf">refresh</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="sd">"""Rebinds and refreshes the URL. Call this if you modified the</span>
- <span class="sd"> rule in place.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="p">,</span> <span class="n">rebind</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">,</span> <span class="n">rebind</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
- <span class="sd">"""Bind the url to a map and create a regular expression based on</span>
- <span class="sd"> the information from the rule itself and the defaults from the map.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">rebind</span><span class="p">:</span>
- <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">'url rule </span><span class="si">%r</span><span class="s1"> already bound to map </span><span class="si">%r</span><span class="s1">'</span> <span class="o">%</span>
- <span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="p">))</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">map</span> <span class="o">=</span> <span class="nb">map</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span> <span class="o">=</span> <span class="nb">map</span><span class="o">.</span><span class="n">strict_slashes</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="o">=</span> <span class="nb">map</span><span class="o">.</span><span class="n">default_subdomain</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">compile</span><span class="p">()</span>
- <span class="k">def</span> <span class="nf">get_converter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">variable_name</span><span class="p">,</span> <span class="n">converter_name</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span>
- <span class="sd">"""Looks up the converter for the given parameter.</span>
- <span class="sd"> .. versionadded:: 0.9</span>
- <span class="sd"> """</span>
- <span class="k">if</span> <span class="n">converter_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">converters</span><span class="p">:</span>
- <span class="k">raise</span> <span class="ne">LookupError</span><span class="p">(</span><span class="s1">'the converter </span><span class="si">%r</span><span class="s1"> does not exist'</span> <span class="o">%</span> <span class="n">converter_name</span><span class="p">)</span>
- <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">converters</span><span class="p">[</span><span class="n">converter_name</span><span class="p">](</span><span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">compile</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="sd">"""Compiles the regular expression and stores it."""</span>
- <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">,</span> <span class="s1">'rule not bound'</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">host_matching</span><span class="p">:</span>
- <span class="n">domain_rule</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">host</span> <span class="ow">or</span> <span class="s1">''</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">domain_rule</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="ow">or</span> <span class="s1">''</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_converters</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_weights</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="n">regex_parts</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="k">def</span> <span class="nf">_build_regex</span><span class="p">(</span><span class="n">rule</span><span class="p">):</span>
- <span class="k">for</span> <span class="n">converter</span><span class="p">,</span> <span class="n">arguments</span><span class="p">,</span> <span class="n">variable</span> <span class="ow">in</span> <span class="n">parse_rule</span><span class="p">(</span><span class="n">rule</span><span class="p">):</span>
- <span class="k">if</span> <span class="n">converter</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">regex_parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">variable</span><span class="p">))</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="kc">False</span><span class="p">,</span> <span class="n">variable</span><span class="p">))</span>
- <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">variable</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'/'</span><span class="p">):</span>
- <span class="k">if</span> <span class="n">part</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_weights</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="n">part</span><span class="p">)))</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">arguments</span><span class="p">:</span>
- <span class="n">c_args</span><span class="p">,</span> <span class="n">c_kwargs</span> <span class="o">=</span> <span class="n">parse_converter_args</span><span class="p">(</span><span class="n">arguments</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">c_args</span> <span class="o">=</span> <span class="p">()</span>
- <span class="n">c_kwargs</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="n">convobj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_converter</span><span class="p">(</span>
- <span class="n">variable</span><span class="p">,</span> <span class="n">converter</span><span class="p">,</span> <span class="n">c_args</span><span class="p">,</span> <span class="n">c_kwargs</span><span class="p">)</span>
- <span class="n">regex_parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'(?P<</span><span class="si">%s</span><span class="s1">></span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span><span class="n">variable</span><span class="p">,</span> <span class="n">convobj</span><span class="o">.</span><span class="n">regex</span><span class="p">))</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_converters</span><span class="p">[</span><span class="n">variable</span><span class="p">]</span> <span class="o">=</span> <span class="n">convobj</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="kc">True</span><span class="p">,</span> <span class="n">variable</span><span class="p">))</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_weights</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="n">convobj</span><span class="o">.</span><span class="n">weight</span><span class="p">))</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">variable</span><span class="p">))</span>
- <span class="n">_build_regex</span><span class="p">(</span><span class="n">domain_rule</span><span class="p">)</span>
- <span class="n">regex_parts</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'</span><span class="se">\\</span><span class="s1">|'</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="kc">False</span><span class="p">,</span> <span class="s1">'|'</span><span class="p">))</span>
- <span class="n">_build_regex</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">is_leaf</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">rule</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">rule</span><span class="o">.</span><span class="n">rstrip</span><span class="p">(</span><span class="s1">'/'</span><span class="p">))</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_leaf</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="kc">False</span><span class="p">,</span> <span class="s1">'/'</span><span class="p">))</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_only</span><span class="p">:</span>
- <span class="k">return</span>
- <span class="n">regex</span> <span class="o">=</span> <span class="s1">r'^</span><span class="si">%s%s</span><span class="s1">$'</span> <span class="o">%</span> <span class="p">(</span>
- <span class="s1">u''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">regex_parts</span><span class="p">),</span>
- <span class="p">(</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_leaf</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span><span class="p">)</span> <span class="ow">and</span>
- <span class="s1">'(?<!/)(?P<__suffix__>/?)'</span> <span class="ow">or</span> <span class="s1">''</span>
- <span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_regex</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">regex</span><span class="p">,</span> <span class="n">re</span><span class="o">.</span><span class="n">UNICODE</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">match</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
- <span class="sd">"""Check if the rule matches a given path. Path is a string in the</span>
- <span class="sd"> form ``"subdomain|/path(method)"`` and is assembled by the map. If</span>
- <span class="sd"> the map is doing host matching the subdomain part will be the host</span>
- <span class="sd"> instead.</span>
- <span class="sd"> If the rule matches a dict with the converted values is returned,</span>
- <span class="sd"> otherwise the return value is `None`.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_only</span><span class="p">:</span>
- <span class="n">m</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_regex</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">m</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">groups</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">groupdict</span><span class="p">()</span>
- <span class="c1"># we have a folder like part of the url without a trailing</span>
- <span class="c1"># slash and strict slashes enabled. raise an exception that</span>
- <span class="c1"># tells the map to redirect to the same url but with a</span>
- <span class="c1"># trailing slash</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_leaf</span> <span class="ow">and</span> \
- <span class="ow">not</span> <span class="n">groups</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s1">'__suffix__'</span><span class="p">):</span>
- <span class="k">raise</span> <span class="n">RequestSlash</span><span class="p">()</span>
- <span class="c1"># if we are not in strict slashes mode we have to remove</span>
- <span class="c1"># a __suffix__</span>
- <span class="k">elif</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span><span class="p">:</span>
- <span class="k">del</span> <span class="n">groups</span><span class="p">[</span><span class="s1">'__suffix__'</span><span class="p">]</span>
- <span class="n">result</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">iteritems</span><span class="p">(</span><span class="n">groups</span><span class="p">):</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_converters</span><span class="p">[</span><span class="n">name</span><span class="p">]</span><span class="o">.</span><span class="n">to_python</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">except</span> <span class="n">ValidationError</span><span class="p">:</span>
- <span class="k">return</span>
- <span class="n">result</span><span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">name</span><span class="p">)]</span> <span class="o">=</span> <span class="n">value</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">:</span>
- <span class="n">result</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defaults</span><span class="p">)</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">alias</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">redirect_defaults</span><span class="p">:</span>
- <span class="k">raise</span> <span class="n">RequestAliasRedirect</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
- <span class="k">return</span> <span class="n">result</span>
- <span class="k">def</span> <span class="nf">build</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">append_unknown</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
- <span class="sd">"""Assembles the relative url for that rule and the subdomain.</span>
- <span class="sd"> If building doesn't work for some reasons `None` is returned.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="n">tmp</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="n">add</span> <span class="o">=</span> <span class="n">tmp</span><span class="o">.</span><span class="n">append</span>
- <span class="n">processed</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">is_dynamic</span><span class="p">,</span> <span class="n">data</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">is_dynamic</span><span class="p">:</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="n">add</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_converters</span><span class="p">[</span><span class="n">data</span><span class="p">]</span><span class="o">.</span><span class="n">to_url</span><span class="p">(</span><span class="n">values</span><span class="p">[</span><span class="n">data</span><span class="p">]))</span>
- <span class="k">except</span> <span class="n">ValidationError</span><span class="p">:</span>
- <span class="k">return</span>
- <span class="n">processed</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">add</span><span class="p">(</span><span class="n">url_quote</span><span class="p">(</span><span class="n">to_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">charset</span><span class="p">),</span> <span class="n">safe</span><span class="o">=</span><span class="s1">'/:|+'</span><span class="p">))</span>
- <span class="n">domain_part</span><span class="p">,</span> <span class="n">url</span> <span class="o">=</span> <span class="p">(</span><span class="s1">u''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tmp</span><span class="p">))</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">u'|'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">append_unknown</span><span class="p">:</span>
- <span class="n">query_vars</span> <span class="o">=</span> <span class="n">MultiDict</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">processed</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">query_vars</span><span class="p">:</span>
- <span class="k">del</span> <span class="n">query_vars</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
- <span class="k">if</span> <span class="n">query_vars</span><span class="p">:</span>
- <span class="n">url</span> <span class="o">+=</span> <span class="s1">u'?'</span> <span class="o">+</span> <span class="n">url_encode</span><span class="p">(</span><span class="n">query_vars</span><span class="p">,</span> <span class="n">charset</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">charset</span><span class="p">,</span>
- <span class="n">sort</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">sort_parameters</span><span class="p">,</span>
- <span class="n">key</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">sort_key</span><span class="p">)</span>
- <span class="k">return</span> <span class="n">domain_part</span><span class="p">,</span> <span class="n">url</span>
- <span class="k">def</span> <span class="nf">provides_defaults_for</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rule</span><span class="p">):</span>
- <span class="sd">"""Check if this rule has defaults for a given rule.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_only</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">defaults</span> <span class="ow">and</span> \
- <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span> <span class="o">==</span> <span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span> <span class="ow">and</span> <span class="bp">self</span> <span class="o">!=</span> <span class="n">rule</span> <span class="ow">and</span> \
- <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">==</span> <span class="n">rule</span><span class="o">.</span><span class="n">arguments</span>
- <span class="k">def</span> <span class="nf">suitable_for</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""Check if the dict of values has enough data for url generation.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="c1"># if a method was given explicitly and that method is not supported</span>
- <span class="c1"># by this rule, this rule is not suitable.</span>
- <span class="k">if</span> <span class="n">method</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">methods</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> \
- <span class="ow">and</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">methods</span><span class="p">:</span>
- <span class="k">return</span> <span class="kc">False</span>
- <span class="n">defaults</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">defaults</span> <span class="ow">or</span> <span class="p">()</span>
- <span class="c1"># all arguments required must be either in the defaults dict or</span>
- <span class="c1"># the value dictionary otherwise it's not suitable</span>
- <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">defaults</span> <span class="ow">and</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
- <span class="k">return</span> <span class="kc">False</span>
- <span class="c1"># in case defaults are given we ensure taht either the value was</span>
- <span class="c1"># skipped or the value is the same as the default value.</span>
- <span class="k">if</span> <span class="n">defaults</span><span class="p">:</span>
- <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">iteritems</span><span class="p">(</span><span class="n">defaults</span><span class="p">):</span>
- <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">values</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">!=</span> <span class="n">values</span><span class="p">[</span><span class="n">key</span><span class="p">]:</span>
- <span class="k">return</span> <span class="kc">False</span>
- <span class="k">return</span> <span class="kc">True</span>
- <span class="k">def</span> <span class="nf">match_compare_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="sd">"""The match compare key for sorting.</span>
- <span class="sd"> Current implementation:</span>
- <span class="sd"> 1. rules without any arguments come first for performance</span>
- <span class="sd"> reasons only as we expect them to match faster and some</span>
- <span class="sd"> common ones usually don't have any arguments (index pages etc.)</span>
- <span class="sd"> 2. The more complex rules come first so the second argument is the</span>
- <span class="sd"> negative length of the number of weights.</span>
- <span class="sd"> 3. lastly we order by the actual weights.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">),</span> <span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_weights</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_weights</span>
- <span class="k">def</span> <span class="nf">build_compare_key</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="sd">"""The build compare key for sorting.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">alias</span> <span class="ow">and</span> <span class="mi">1</span> <span class="ow">or</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="p">),</span> \
- <span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">defaults</span> <span class="ow">or</span> <span class="p">())</span>
- <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
- <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">is</span> <span class="n">other</span><span class="o">.</span><span class="n">__class__</span> <span class="ow">and</span> \
- <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_trace</span>
- <span class="k">def</span> <span class="nf">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
- <span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">rule</span>
- <span class="nd">@native_string_result</span>
- <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">return</span> <span class="s1">u'<</span><span class="si">%s</span><span class="s1"> (unbound)>'</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span>
- <span class="n">tmp</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="k">for</span> <span class="n">is_dynamic</span><span class="p">,</span> <span class="n">data</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_trace</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">is_dynamic</span><span class="p">:</span>
- <span class="n">tmp</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">u'<</span><span class="si">%s</span><span class="s1">>'</span> <span class="o">%</span> <span class="n">data</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">tmp</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
- <span class="k">return</span> <span class="s1">u'<</span><span class="si">%s</span><span class="s1"> </span><span class="si">%s%s</span><span class="s1"> -> </span><span class="si">%s</span><span class="s1">>'</span> <span class="o">%</span> <span class="p">(</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span>
- <span class="nb">repr</span><span class="p">((</span><span class="s1">u''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tmp</span><span class="p">))</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">u'|'</span><span class="p">))</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">u'u'</span><span class="p">),</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">methods</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
- <span class="ow">and</span> <span class="s1">u' (</span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="s1">u', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">methods</span><span class="p">)</span>
- <span class="ow">or</span> <span class="s1">u''</span><span class="p">,</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">endpoint</span>
- <span class="p">)</span>
- <span class="k">class</span> <span class="nc">BaseConverter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
- <span class="sd">"""Base class for all converters."""</span>
- <span class="n">regex</span> <span class="o">=</span> <span class="s1">'[^/]+'</span>
- <span class="n">weight</span> <span class="o">=</span> <span class="mi">100</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">map</span> <span class="o">=</span> <span class="nb">map</span>
- <span class="k">def</span> <span class="nf">to_python</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">value</span>
- <span class="k">def</span> <span class="nf">to_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">url_quote</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">charset</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">charset</span><span class="p">)</span>
- <span class="k">class</span> <span class="nc">UnicodeConverter</span><span class="p">(</span><span class="n">BaseConverter</span><span class="p">):</span>
- <span class="sd">"""This converter is the default converter and accepts any string but</span>
- <span class="sd"> only one path segment. Thus the string can not include a slash.</span>
- <span class="sd"> This is the default validator.</span>
- <span class="sd"> Example::</span>
- <span class="sd"> Rule('/pages/<page>'),</span>
- <span class="sd"> Rule('/<string(length=2):lang_code>')</span>
- <span class="sd"> :param map: the :class:`Map`.</span>
- <span class="sd"> :param minlength: the minimum length of the string. Must be greater</span>
- <span class="sd"> or equal 1.</span>
- <span class="sd"> :param maxlength: the maximum length of the string.</span>
- <span class="sd"> :param length: the exact length of the string.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">,</span> <span class="n">minlength</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">maxlength</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">length</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="n">BaseConverter</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">length</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">length</span> <span class="o">=</span> <span class="s1">'{</span><span class="si">%d</span><span class="s1">}'</span> <span class="o">%</span> <span class="nb">int</span><span class="p">(</span><span class="n">length</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">maxlength</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">maxlength</span> <span class="o">=</span> <span class="s1">''</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">maxlength</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">maxlength</span><span class="p">)</span>
- <span class="n">length</span> <span class="o">=</span> <span class="s1">'{</span><span class="si">%s</span><span class="s1">,</span><span class="si">%s</span><span class="s1">}'</span> <span class="o">%</span> <span class="p">(</span>
- <span class="nb">int</span><span class="p">(</span><span class="n">minlength</span><span class="p">),</span>
- <span class="n">maxlength</span>
- <span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">regex</span> <span class="o">=</span> <span class="s1">'[^/]'</span> <span class="o">+</span> <span class="n">length</span>
- <span class="k">class</span> <span class="nc">AnyConverter</span><span class="p">(</span><span class="n">BaseConverter</span><span class="p">):</span>
- <span class="sd">"""Matches one of the items provided. Items can either be Python</span>
- <span class="sd"> identifiers or strings::</span>
- <span class="sd"> Rule('/<any(about, help, imprint, class, "foo,bar"):page_name>')</span>
- <span class="sd"> :param map: the :class:`Map`.</span>
- <span class="sd"> :param items: this function accepts the possible items as positional</span>
- <span class="sd"> arguments.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">,</span> <span class="o">*</span><span class="n">items</span><span class="p">):</span>
- <span class="n">BaseConverter</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">regex</span> <span class="o">=</span> <span class="s1">'(?:</span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="s1">'|'</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">items</span><span class="p">])</span>
- <span class="k">class</span> <span class="nc">PathConverter</span><span class="p">(</span><span class="n">BaseConverter</span><span class="p">):</span>
- <span class="sd">"""Like the default :class:`UnicodeConverter`, but it also matches</span>
- <span class="sd"> slashes. This is useful for wikis and similar applications::</span>
- <span class="sd"> Rule('/<path:wikipage>')</span>
- <span class="sd"> Rule('/<path:wikipage>/edit')</span>
- <span class="sd"> :param map: the :class:`Map`.</span>
- <span class="sd"> """</span>
- <span class="n">regex</span> <span class="o">=</span> <span class="s1">'[^/].*?'</span>
- <span class="n">weight</span> <span class="o">=</span> <span class="mi">200</span>
- <span class="k">class</span> <span class="nc">NumberConverter</span><span class="p">(</span><span class="n">BaseConverter</span><span class="p">):</span>
- <span class="sd">"""Baseclass for `IntegerConverter` and `FloatConverter`.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="n">weight</span> <span class="o">=</span> <span class="mi">50</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">,</span> <span class="n">fixed_digits</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="nb">min</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="n">BaseConverter</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">fixed_digits</span> <span class="o">=</span> <span class="n">fixed_digits</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">=</span> <span class="nb">min</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">=</span> <span class="nb">max</span>
- <span class="k">def</span> <span class="nf">to_python</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
- <span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fixed_digits</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fixed_digits</span><span class="p">):</span>
- <span class="k">raise</span> <span class="n">ValidationError</span><span class="p">()</span>
- <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">num_convert</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o"><</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">)</span> <span class="ow">or</span> \
- <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">value</span> <span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="p">):</span>
- <span class="k">raise</span> <span class="n">ValidationError</span><span class="p">()</span>
- <span class="k">return</span> <span class="n">value</span>
- <span class="k">def</span> <span class="nf">to_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
- <span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">num_convert</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fixed_digits</span><span class="p">:</span>
- <span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'</span><span class="si">%%</span><span class="s1">0</span><span class="si">%s</span><span class="s1">d'</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fixed_digits</span><span class="p">)</span> <span class="o">%</span> <span class="n">value</span>
- <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">class</span> <span class="nc">IntegerConverter</span><span class="p">(</span><span class="n">NumberConverter</span><span class="p">):</span>
- <span class="sd">"""This converter only accepts integer values::</span>
- <span class="sd"> Rule('/page/<int:page>')</span>
- <span class="sd"> This converter does not support negative values.</span>
- <span class="sd"> :param map: the :class:`Map`.</span>
- <span class="sd"> :param fixed_digits: the number of fixed digits in the URL. If you set</span>
- <span class="sd"> this to ``4`` for example, the application will</span>
- <span class="sd"> only match if the url looks like ``/0001/``. The</span>
- <span class="sd"> default is variable length.</span>
- <span class="sd"> :param min: the minimal value.</span>
- <span class="sd"> :param max: the maximal value.</span>
- <span class="sd"> """</span>
- <span class="n">regex</span> <span class="o">=</span> <span class="s1">r'\d+'</span>
- <span class="n">num_convert</span> <span class="o">=</span> <span class="nb">int</span>
- <span class="k">class</span> <span class="nc">FloatConverter</span><span class="p">(</span><span class="n">NumberConverter</span><span class="p">):</span>
- <span class="sd">"""This converter only accepts floating point values::</span>
- <span class="sd"> Rule('/probability/<float:probability>')</span>
- <span class="sd"> This converter does not support negative values.</span>
- <span class="sd"> :param map: the :class:`Map`.</span>
- <span class="sd"> :param min: the minimal value.</span>
- <span class="sd"> :param max: the maximal value.</span>
- <span class="sd"> """</span>
- <span class="n">regex</span> <span class="o">=</span> <span class="s1">r'\d+\.\d+'</span>
- <span class="n">num_convert</span> <span class="o">=</span> <span class="nb">float</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">,</span> <span class="nb">min</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="n">NumberConverter</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">min</span><span class="p">,</span> <span class="nb">max</span><span class="p">)</span>
- <span class="k">class</span> <span class="nc">UUIDConverter</span><span class="p">(</span><span class="n">BaseConverter</span><span class="p">):</span>
- <span class="sd">"""This converter only accepts UUID strings::</span>
- <span class="sd"> Rule('/object/<uuid:identifier>')</span>
- <span class="sd"> .. versionadded:: 0.10</span>
- <span class="sd"> :param map: the :class:`Map`.</span>
- <span class="sd"> """</span>
- <span class="n">regex</span> <span class="o">=</span> <span class="s1">r'[A-Fa-f0-9]</span><span class="si">{8}</span><span class="s1">-[A-Fa-f0-9]</span><span class="si">{4}</span><span class="s1">-'</span> \
- <span class="s1">r'[A-Fa-f0-9]</span><span class="si">{4}</span><span class="s1">-[A-Fa-f0-9]</span><span class="si">{4}</span><span class="s1">-[A-Fa-f0-9]</span><span class="si">{12}</span><span class="s1">'</span>
- <span class="k">def</span> <span class="nf">to_python</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">uuid</span><span class="o">.</span><span class="n">UUID</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">to_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
- <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="c1">#: the default converter mapping for the map.</span>
- <span class="n">DEFAULT_CONVERTERS</span> <span class="o">=</span> <span class="p">{</span>
- <span class="s1">'default'</span><span class="p">:</span> <span class="n">UnicodeConverter</span><span class="p">,</span>
- <span class="s1">'string'</span><span class="p">:</span> <span class="n">UnicodeConverter</span><span class="p">,</span>
- <span class="s1">'any'</span><span class="p">:</span> <span class="n">AnyConverter</span><span class="p">,</span>
- <span class="s1">'path'</span><span class="p">:</span> <span class="n">PathConverter</span><span class="p">,</span>
- <span class="s1">'int'</span><span class="p">:</span> <span class="n">IntegerConverter</span><span class="p">,</span>
- <span class="s1">'float'</span><span class="p">:</span> <span class="n">FloatConverter</span><span class="p">,</span>
- <span class="s1">'uuid'</span><span class="p">:</span> <span class="n">UUIDConverter</span><span class="p">,</span>
- <span class="p">}</span>
- <span class="k">class</span> <span class="nc">Map</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
- <span class="sd">"""The map class stores all the URL rules and some configuration</span>
- <span class="sd"> parameters. Some of the configuration values are only stored on the</span>
- <span class="sd"> `Map` instance since those affect all rules, others are just defaults</span>
- <span class="sd"> and can be overridden for each rule. Note that you have to specify all</span>
- <span class="sd"> arguments besides the `rules` as keyword arguments!</span>
- <span class="sd"> :param rules: sequence of url rules for this map.</span>
- <span class="sd"> :param default_subdomain: The default subdomain for rules without a</span>
- <span class="sd"> subdomain defined.</span>
- <span class="sd"> :param charset: charset of the url. defaults to ``"utf-8"``</span>
- <span class="sd"> :param strict_slashes: Take care of trailing slashes.</span>
- <span class="sd"> :param redirect_defaults: This will redirect to the default rule if it</span>
- <span class="sd"> wasn't visited that way. This helps creating</span>
- <span class="sd"> unique URLs.</span>
- <span class="sd"> :param converters: A dict of converters that adds additional converters</span>
- <span class="sd"> to the list of converters. If you redefine one</span>
- <span class="sd"> converter this will override the original one.</span>
- <span class="sd"> :param sort_parameters: If set to `True` the url parameters are sorted.</span>
- <span class="sd"> See `url_encode` for more details.</span>
- <span class="sd"> :param sort_key: The sort key function for `url_encode`.</span>
- <span class="sd"> :param encoding_errors: the error method to use for decoding</span>
- <span class="sd"> :param host_matching: if set to `True` it enables the host matching</span>
- <span class="sd"> feature and disables the subdomain one. If</span>
- <span class="sd"> enabled the `host` parameter to rules is used</span>
- <span class="sd"> instead of the `subdomain` one.</span>
- <span class="sd"> .. versionadded:: 0.5</span>
- <span class="sd"> `sort_parameters` and `sort_key` was added.</span>
- <span class="sd"> .. versionadded:: 0.7</span>
- <span class="sd"> `encoding_errors` and `host_matching` was added.</span>
- <span class="sd"> """</span>
- <span class="c1">#: .. versionadded:: 0.6</span>
- <span class="c1">#: a dict of default converters to be used.</span>
- <span class="n">default_converters</span> <span class="o">=</span> <span class="n">ImmutableDict</span><span class="p">(</span><span class="n">DEFAULT_CONVERTERS</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rules</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">default_subdomain</span><span class="o">=</span><span class="s1">''</span><span class="p">,</span> <span class="n">charset</span><span class="o">=</span><span class="s1">'utf-8'</span><span class="p">,</span>
- <span class="n">strict_slashes</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">redirect_defaults</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
- <span class="n">converters</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">sort_parameters</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">sort_key</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
- <span class="n">encoding_errors</span><span class="o">=</span><span class="s1">'replace'</span><span class="p">,</span> <span class="n">host_matching</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_rules</span> <span class="o">=</span> <span class="p">[]</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_rules_by_endpoint</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_remap</span> <span class="o">=</span> <span class="kc">True</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_remap_lock</span> <span class="o">=</span> <span class="n">Lock</span><span class="p">()</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">default_subdomain</span> <span class="o">=</span> <span class="n">default_subdomain</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">charset</span> <span class="o">=</span> <span class="n">charset</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">encoding_errors</span> <span class="o">=</span> <span class="n">encoding_errors</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">strict_slashes</span> <span class="o">=</span> <span class="n">strict_slashes</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">redirect_defaults</span> <span class="o">=</span> <span class="n">redirect_defaults</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">host_matching</span> <span class="o">=</span> <span class="n">host_matching</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">converters</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_converters</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">converters</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">converters</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">converters</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">sort_parameters</span> <span class="o">=</span> <span class="n">sort_parameters</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">sort_key</span> <span class="o">=</span> <span class="n">sort_key</span>
- <span class="k">for</span> <span class="n">rulefactory</span> <span class="ow">in</span> <span class="n">rules</span> <span class="ow">or</span> <span class="p">():</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">rulefactory</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">is_endpoint_expecting</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">endpoint</span><span class="p">,</span> <span class="o">*</span><span class="n">arguments</span><span class="p">):</span>
- <span class="sd">"""Iterate over all rules and check if the endpoint expects</span>
- <span class="sd"> the arguments provided. This is for example useful if you have</span>
- <span class="sd"> some URLs that expect a language code and others that do not and</span>
- <span class="sd"> you want to wrap the builder a bit so that the current language</span>
- <span class="sd"> code is automatically added if not provided but endpoints expect</span>
- <span class="sd"> it.</span>
- <span class="sd"> :param endpoint: the endpoint to check.</span>
- <span class="sd"> :param arguments: this function accepts one or more arguments</span>
- <span class="sd"> as positional arguments. Each one of them is</span>
- <span class="sd"> checked.</span>
- <span class="sd"> """</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">()</span>
- <span class="n">arguments</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">arguments</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_rules_by_endpoint</span><span class="p">[</span><span class="n">endpoint</span><span class="p">]:</span>
- <span class="k">if</span> <span class="n">arguments</span><span class="o">.</span><span class="n">issubset</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">arguments</span><span class="p">):</span>
- <span class="k">return</span> <span class="kc">True</span>
- <span class="k">return</span> <span class="kc">False</span>
- <span class="k">def</span> <span class="nf">iter_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">endpoint</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""Iterate over all rules or the rules of an endpoint.</span>
- <span class="sd"> :param endpoint: if provided only the rules for that endpoint</span>
- <span class="sd"> are returned.</span>
- <span class="sd"> :return: an iterator</span>
- <span class="sd"> """</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">endpoint</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_rules_by_endpoint</span><span class="p">[</span><span class="n">endpoint</span><span class="p">])</span>
- <span class="k">return</span> <span class="nb">iter</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_rules</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rulefactory</span><span class="p">):</span>
- <span class="sd">"""Add a new rule or factory to the map and bind it. Requires that the</span>
- <span class="sd"> rule is not bound to another map.</span>
- <span class="sd"> :param rulefactory: a :class:`Rule` or :class:`RuleFactory`</span>
- <span class="sd"> """</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">rulefactory</span><span class="o">.</span><span class="n">get_rules</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_rules</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rule</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_rules_by_endpoint</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rule</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_remap</span> <span class="o">=</span> <span class="kc">True</span>
- <span class="k">def</span> <span class="nf">bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">script_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">subdomain</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
- <span class="n">url_scheme</span><span class="o">=</span><span class="s1">'http'</span><span class="p">,</span> <span class="n">default_method</span><span class="o">=</span><span class="s1">'GET'</span><span class="p">,</span> <span class="n">path_info</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
- <span class="n">query_args</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""Return a new :class:`MapAdapter` with the details specified to the</span>
- <span class="sd"> call. Note that `script_name` will default to ``'/'`` if not further</span>
- <span class="sd"> specified or `None`. The `server_name` at least is a requirement</span>
- <span class="sd"> because the HTTP RFC requires absolute URLs for redirects and so all</span>
- <span class="sd"> redirect exceptions raised by Werkzeug will contain the full canonical</span>
- <span class="sd"> URL.</span>
- <span class="sd"> If no path_info is passed to :meth:`match` it will use the default path</span>
- <span class="sd"> info passed to bind. While this doesn't really make sense for</span>
- <span class="sd"> manual bind calls, it's useful if you bind a map to a WSGI</span>
- <span class="sd"> environment which already contains the path info.</span>
- <span class="sd"> `subdomain` will default to the `default_subdomain` for this map if</span>
- <span class="sd"> no defined. If there is no `default_subdomain` you cannot use the</span>
- <span class="sd"> subdomain feature.</span>
- <span class="sd"> .. versionadded:: 0.7</span>
- <span class="sd"> `query_args` added</span>
- <span class="sd"> .. versionadded:: 0.8</span>
- <span class="sd"> `query_args` can now also be a string.</span>
- <span class="sd"> """</span>
- <span class="n">server_name</span> <span class="o">=</span> <span class="n">server_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">host_matching</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">subdomain</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s1">'host matching enabled and a '</span>
- <span class="s1">'subdomain was provided'</span><span class="p">)</span>
- <span class="k">elif</span> <span class="n">subdomain</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">subdomain</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_subdomain</span>
- <span class="k">if</span> <span class="n">script_name</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">script_name</span> <span class="o">=</span> <span class="s1">'/'</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="n">server_name</span> <span class="o">=</span> <span class="n">_encode_idna</span><span class="p">(</span><span class="n">server_name</span><span class="p">)</span>
- <span class="k">except</span> <span class="ne">UnicodeError</span><span class="p">:</span>
- <span class="k">raise</span> <span class="n">BadHost</span><span class="p">()</span>
- <span class="k">return</span> <span class="n">MapAdapter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">script_name</span><span class="p">,</span> <span class="n">subdomain</span><span class="p">,</span>
- <span class="n">url_scheme</span><span class="p">,</span> <span class="n">path_info</span><span class="p">,</span> <span class="n">default_method</span><span class="p">,</span> <span class="n">query_args</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">bind_to_environ</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">environ</span><span class="p">,</span> <span class="n">server_name</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">subdomain</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""Like :meth:`bind` but you can pass it an WSGI environment and it</span>
- <span class="sd"> will fetch the information from that dictionary. Note that because of</span>
- <span class="sd"> limitations in the protocol there is no way to get the current</span>
- <span class="sd"> subdomain and real `server_name` from the environment. If you don't</span>
- <span class="sd"> provide it, Werkzeug will use `SERVER_NAME` and `SERVER_PORT` (or</span>
- <span class="sd"> `HTTP_HOST` if provided) as used `server_name` with disabled subdomain</span>
- <span class="sd"> feature.</span>
- <span class="sd"> If `subdomain` is `None` but an environment and a server name is</span>
- <span class="sd"> provided it will calculate the current subdomain automatically.</span>
- <span class="sd"> Example: `server_name` is ``'example.com'`` and the `SERVER_NAME`</span>
- <span class="sd"> in the wsgi `environ` is ``'staging.dev.example.com'`` the calculated</span>
- <span class="sd"> subdomain will be ``'staging.dev'``.</span>
- <span class="sd"> If the object passed as environ has an environ attribute, the value of</span>
- <span class="sd"> this attribute is used instead. This allows you to pass request</span>
- <span class="sd"> objects. Additionally `PATH_INFO` added as a default of the</span>
- <span class="sd"> :class:`MapAdapter` so that you don't have to pass the path info to</span>
- <span class="sd"> the match method.</span>
- <span class="sd"> .. versionchanged:: 0.5</span>
- <span class="sd"> previously this method accepted a bogus `calculate_subdomain`</span>
- <span class="sd"> parameter that did not have any effect. It was removed because</span>
- <span class="sd"> of that.</span>
- <span class="sd"> .. versionchanged:: 0.8</span>
- <span class="sd"> This will no longer raise a ValueError when an unexpected server</span>
- <span class="sd"> name was passed.</span>
- <span class="sd"> :param environ: a WSGI environment.</span>
- <span class="sd"> :param server_name: an optional server name hint (see above).</span>
- <span class="sd"> :param subdomain: optionally the current subdomain (see above).</span>
- <span class="sd"> """</span>
- <span class="n">environ</span> <span class="o">=</span> <span class="n">_get_environ</span><span class="p">(</span><span class="n">environ</span><span class="p">)</span>
- <span class="k">if</span> <span class="s1">'HTTP_HOST'</span> <span class="ow">in</span> <span class="n">environ</span><span class="p">:</span>
- <span class="n">wsgi_server_name</span> <span class="o">=</span> <span class="n">environ</span><span class="p">[</span><span class="s1">'HTTP_HOST'</span><span class="p">]</span>
- <span class="k">if</span> <span class="n">environ</span><span class="p">[</span><span class="s1">'wsgi.url_scheme'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'http'</span> \
- <span class="ow">and</span> <span class="n">wsgi_server_name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">':80'</span><span class="p">):</span>
- <span class="n">wsgi_server_name</span> <span class="o">=</span> <span class="n">wsgi_server_name</span><span class="p">[:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span>
- <span class="k">elif</span> <span class="n">environ</span><span class="p">[</span><span class="s1">'wsgi.url_scheme'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'https'</span> \
- <span class="ow">and</span> <span class="n">wsgi_server_name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">':443'</span><span class="p">):</span>
- <span class="n">wsgi_server_name</span> <span class="o">=</span> <span class="n">wsgi_server_name</span><span class="p">[:</span><span class="o">-</span><span class="mi">4</span><span class="p">]</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">wsgi_server_name</span> <span class="o">=</span> <span class="n">environ</span><span class="p">[</span><span class="s1">'SERVER_NAME'</span><span class="p">]</span>
- <span class="k">if</span> <span class="p">(</span><span class="n">environ</span><span class="p">[</span><span class="s1">'wsgi.url_scheme'</span><span class="p">],</span> <span class="n">environ</span><span class="p">[</span><span class="s1">'SERVER_PORT'</span><span class="p">])</span> <span class="ow">not</span> \
- <span class="ow">in</span> <span class="p">((</span><span class="s1">'https'</span><span class="p">,</span> <span class="s1">'443'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'http'</span><span class="p">,</span> <span class="s1">'80'</span><span class="p">)):</span>
- <span class="n">wsgi_server_name</span> <span class="o">+=</span> <span class="s1">':'</span> <span class="o">+</span> <span class="n">environ</span><span class="p">[</span><span class="s1">'SERVER_PORT'</span><span class="p">]</span>
- <span class="n">wsgi_server_name</span> <span class="o">=</span> <span class="n">wsgi_server_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">server_name</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">server_name</span> <span class="o">=</span> <span class="n">wsgi_server_name</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">server_name</span> <span class="o">=</span> <span class="n">server_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">subdomain</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">host_matching</span><span class="p">:</span>
- <span class="n">cur_server_name</span> <span class="o">=</span> <span class="n">wsgi_server_name</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)</span>
- <span class="n">real_server_name</span> <span class="o">=</span> <span class="n">server_name</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)</span>
- <span class="n">offset</span> <span class="o">=</span> <span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="n">real_server_name</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">cur_server_name</span><span class="p">[</span><span class="n">offset</span><span class="p">:]</span> <span class="o">!=</span> <span class="n">real_server_name</span><span class="p">:</span>
- <span class="c1"># This can happen even with valid configs if the server was</span>
- <span class="c1"># accesssed directly by IP address under some situations.</span>
- <span class="c1"># Instead of raising an exception like in Werkzeug 0.7 or</span>
- <span class="c1"># earlier we go by an invalid subdomain which will result</span>
- <span class="c1"># in a 404 error on matching.</span>
- <span class="n">subdomain</span> <span class="o">=</span> <span class="s1">'<invalid>'</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">subdomain</span> <span class="o">=</span> <span class="s1">'.'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">cur_server_name</span><span class="p">[:</span><span class="n">offset</span><span class="p">]))</span>
- <span class="k">def</span> <span class="nf">_get_wsgi_string</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
- <span class="n">val</span> <span class="o">=</span> <span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">val</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">wsgi_decoding_dance</span><span class="p">(</span><span class="n">val</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">charset</span><span class="p">)</span>
- <span class="n">script_name</span> <span class="o">=</span> <span class="n">_get_wsgi_string</span><span class="p">(</span><span class="s1">'SCRIPT_NAME'</span><span class="p">)</span>
- <span class="n">path_info</span> <span class="o">=</span> <span class="n">_get_wsgi_string</span><span class="p">(</span><span class="s1">'PATH_INFO'</span><span class="p">)</span>
- <span class="n">query_args</span> <span class="o">=</span> <span class="n">_get_wsgi_string</span><span class="p">(</span><span class="s1">'QUERY_STRING'</span><span class="p">)</span>
- <span class="k">return</span> <span class="n">Map</span><span class="o">.</span><span class="n">bind</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">script_name</span><span class="p">,</span>
- <span class="n">subdomain</span><span class="p">,</span> <span class="n">environ</span><span class="p">[</span><span class="s1">'wsgi.url_scheme'</span><span class="p">],</span>
- <span class="n">environ</span><span class="p">[</span><span class="s1">'REQUEST_METHOD'</span><span class="p">],</span> <span class="n">path_info</span><span class="p">,</span>
- <span class="n">query_args</span><span class="o">=</span><span class="n">query_args</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="sd">"""Called before matching and building to keep the compiled rules</span>
- <span class="sd"> in the correct order after things changed.</span>
- <span class="sd"> """</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remap</span><span class="p">:</span>
- <span class="k">return</span>
- <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remap_lock</span><span class="p">:</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_remap</span><span class="p">:</span>
- <span class="k">return</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_rules</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">match_compare_key</span><span class="p">())</span>
- <span class="k">for</span> <span class="n">rules</span> <span class="ow">in</span> <span class="n">itervalues</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_rules_by_endpoint</span><span class="p">):</span>
- <span class="n">rules</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">build_compare_key</span><span class="p">())</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">_remap</span> <span class="o">=</span> <span class="kc">False</span>
- <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
- <span class="n">rules</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">iter_rules</span><span class="p">()</span>
- <span class="k">return</span> <span class="s1">'</span><span class="si">%s</span><span class="s1">(</span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">__class__</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">pformat</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">rules</span><span class="p">)))</span>
- <span class="k">class</span> <span class="nc">MapAdapter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
- <span class="sd">"""Returned by :meth:`Map.bind` or :meth:`Map.bind_to_environ` and does</span>
- <span class="sd"> the URL matching and building based on runtime information.</span>
- <span class="sd"> """</span>
- <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">map</span><span class="p">,</span> <span class="n">server_name</span><span class="p">,</span> <span class="n">script_name</span><span class="p">,</span> <span class="n">subdomain</span><span class="p">,</span>
- <span class="n">url_scheme</span><span class="p">,</span> <span class="n">path_info</span><span class="p">,</span> <span class="n">default_method</span><span class="p">,</span> <span class="n">query_args</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">map</span> <span class="o">=</span> <span class="nb">map</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">server_name</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">server_name</span><span class="p">)</span>
- <span class="n">script_name</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">script_name</span><span class="p">)</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="n">script_name</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s1">u'/'</span><span class="p">):</span>
- <span class="n">script_name</span> <span class="o">+=</span> <span class="s1">u'/'</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">script_name</span> <span class="o">=</span> <span class="n">script_name</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">subdomain</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">url_scheme</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">url_scheme</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">path_info</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">path_info</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">default_method</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">default_method</span><span class="p">)</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">query_args</span> <span class="o">=</span> <span class="n">query_args</span>
- <span class="k">def</span> <span class="nf">dispatch</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">view_func</span><span class="p">,</span> <span class="n">path_info</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
- <span class="n">catch_http_exceptions</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
- <span class="sd">"""Does the complete dispatching process. `view_func` is called with</span>
- <span class="sd"> the endpoint and a dict with the values for the view. It should</span>
- <span class="sd"> look up the view function, call it, and return a response object</span>
- <span class="sd"> or WSGI application. http exceptions are not caught by default</span>
- <span class="sd"> so that applications can display nicer error messages by just</span>
- <span class="sd"> catching them by hand. If you want to stick with the default</span>
- <span class="sd"> error messages you can pass it ``catch_http_exceptions=True`` and</span>
- <span class="sd"> it will catch the http exceptions.</span>
- <span class="sd"> Here a small example for the dispatch usage::</span>
- <span class="sd"> from werkzeug.wrappers import Request, Response</span>
- <span class="sd"> from werkzeug.wsgi import responder</span>
- <span class="sd"> from werkzeug.routing import Map, Rule</span>
- <span class="sd"> def on_index(request):</span>
- <span class="sd"> return Response('Hello from the index')</span>
- <span class="sd"> url_map = Map([Rule('/', endpoint='index')])</span>
- <span class="sd"> views = {'index': on_index}</span>
- <span class="sd"> @responder</span>
- <span class="sd"> def application(environ, start_response):</span>
- <span class="sd"> request = Request(environ)</span>
- <span class="sd"> urls = url_map.bind_to_environ(environ)</span>
- <span class="sd"> return urls.dispatch(lambda e, v: views[e](request, **v),</span>
- <span class="sd"> catch_http_exceptions=True)</span>
- <span class="sd"> Keep in mind that this method might return exception objects, too, so</span>
- <span class="sd"> use :class:`Response.force_type` to get a response object.</span>
- <span class="sd"> :param view_func: a function that is called with the endpoint as</span>
- <span class="sd"> first argument and the value dict as second. Has</span>
- <span class="sd"> to dispatch to the actual view function with this</span>
- <span class="sd"> information. (see above)</span>
- <span class="sd"> :param path_info: the path info to use for matching. Overrides the</span>
- <span class="sd"> path info specified on binding.</span>
- <span class="sd"> :param method: the HTTP method used for matching. Overrides the</span>
- <span class="sd"> method specified on binding.</span>
- <span class="sd"> :param catch_http_exceptions: set to `True` to catch any of the</span>
- <span class="sd"> werkzeug :class:`HTTPException`\s.</span>
- <span class="sd"> """</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="n">endpoint</span><span class="p">,</span> <span class="n">args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">path_info</span><span class="p">,</span> <span class="n">method</span><span class="p">)</span>
- <span class="k">except</span> <span class="n">RequestRedirect</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">e</span>
- <span class="k">return</span> <span class="n">view_func</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
- <span class="k">except</span> <span class="n">HTTPException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">catch_http_exceptions</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">e</span>
- <span class="k">raise</span>
- <span class="k">def</span> <span class="nf">match</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path_info</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">return_rule</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
- <span class="n">query_args</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""The usage is simple: you just pass the match method the current</span>
- <span class="sd"> path info as well as the method (which defaults to `GET`). The</span>
- <span class="sd"> following things can then happen:</span>
- <span class="sd"> - you receive a `NotFound` exception that indicates that no URL is</span>
- <span class="sd"> matching. A `NotFound` exception is also a WSGI application you</span>
- <span class="sd"> can call to get a default page not found page (happens to be the</span>
- <span class="sd"> same object as `werkzeug.exceptions.NotFound`)</span>
- <span class="sd"> - you receive a `MethodNotAllowed` exception that indicates that there</span>
- <span class="sd"> is a match for this URL but not for the current request method.</span>
- <span class="sd"> This is useful for RESTful applications.</span>
- <span class="sd"> - you receive a `RequestRedirect` exception with a `new_url`</span>
- <span class="sd"> attribute. This exception is used to notify you about a request</span>
- <span class="sd"> Werkzeug requests from your WSGI application. This is for example the</span>
- <span class="sd"> case if you request ``/foo`` although the correct URL is ``/foo/``</span>
- <span class="sd"> You can use the `RequestRedirect` instance as response-like object</span>
- <span class="sd"> similar to all other subclasses of `HTTPException`.</span>
- <span class="sd"> - you get a tuple in the form ``(endpoint, arguments)`` if there is</span>
- <span class="sd"> a match (unless `return_rule` is True, in which case you get a tuple</span>
- <span class="sd"> in the form ``(rule, arguments)``)</span>
- <span class="sd"> If the path info is not passed to the match method the default path</span>
- <span class="sd"> info of the map is used (defaults to the root URL if not defined</span>
- <span class="sd"> explicitly).</span>
- <span class="sd"> All of the exceptions raised are subclasses of `HTTPException` so they</span>
- <span class="sd"> can be used as WSGI responses. The will all render generic error or</span>
- <span class="sd"> redirect pages.</span>
- <span class="sd"> Here is a small example for matching:</span>
- <span class="sd"> >>> m = Map([</span>
- <span class="sd"> ... Rule('/', endpoint='index'),</span>
- <span class="sd"> ... Rule('/downloads/', endpoint='downloads/index'),</span>
- <span class="sd"> ... Rule('/downloads/<int:id>', endpoint='downloads/show')</span>
- <span class="sd"> ... ])</span>
- <span class="sd"> >>> urls = m.bind("example.com", "/")</span>
- <span class="sd"> >>> urls.match("/", "GET")</span>
- <span class="sd"> ('index', {})</span>
- <span class="sd"> >>> urls.match("/downloads/42")</span>
- <span class="sd"> ('downloads/show', {'id': 42})</span>
- <span class="sd"> And here is what happens on redirect and missing URLs:</span>
- <span class="sd"> >>> urls.match("/downloads")</span>
- <span class="sd"> Traceback (most recent call last):</span>
- <span class="sd"> ...</span>
- <span class="sd"> RequestRedirect: http://example.com/downloads/</span>
- <span class="sd"> >>> urls.match("/missing")</span>
- <span class="sd"> Traceback (most recent call last):</span>
- <span class="sd"> ...</span>
- <span class="sd"> NotFound: 404 Not Found</span>
- <span class="sd"> :param path_info: the path info to use for matching. Overrides the</span>
- <span class="sd"> path info specified on binding.</span>
- <span class="sd"> :param method: the HTTP method used for matching. Overrides the</span>
- <span class="sd"> method specified on binding.</span>
- <span class="sd"> :param return_rule: return the rule that matched instead of just the</span>
- <span class="sd"> endpoint (defaults to `False`).</span>
- <span class="sd"> :param query_args: optional query arguments that are used for</span>
- <span class="sd"> automatic redirects as string or dictionary. It's</span>
- <span class="sd"> currently not possible to use the query arguments</span>
- <span class="sd"> for URL matching.</span>
- <span class="sd"> .. versionadded:: 0.6</span>
- <span class="sd"> `return_rule` was added.</span>
- <span class="sd"> .. versionadded:: 0.7</span>
- <span class="sd"> `query_args` was added.</span>
- <span class="sd"> .. versionchanged:: 0.8</span>
- <span class="sd"> `query_args` can now also be a string.</span>
- <span class="sd"> """</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">update</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">path_info</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">path_info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">path_info</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">path_info</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">path_info</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">charset</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">query_args</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">query_args</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">query_args</span>
- <span class="n">method</span> <span class="o">=</span> <span class="p">(</span><span class="n">method</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_method</span><span class="p">)</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
- <span class="n">path</span> <span class="o">=</span> <span class="s1">u'</span><span class="si">%s</span><span class="s1">|</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">host_matching</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">server_name</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span><span class="p">,</span>
- <span class="n">path_info</span> <span class="ow">and</span> <span class="s1">'/</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">path_info</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
- <span class="p">)</span>
- <span class="n">have_match_for</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">_rules</span><span class="p">:</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="n">rv</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
- <span class="k">except</span> <span class="n">RequestSlash</span><span class="p">:</span>
- <span class="k">raise</span> <span class="n">RequestRedirect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">make_redirect_url</span><span class="p">(</span>
- <span class="n">url_quote</span><span class="p">(</span><span class="n">path_info</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">charset</span><span class="p">,</span>
- <span class="n">safe</span><span class="o">=</span><span class="s1">'/:|+'</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'/'</span><span class="p">,</span> <span class="n">query_args</span><span class="p">))</span>
- <span class="k">except</span> <span class="n">RequestAliasRedirect</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
- <span class="k">raise</span> <span class="n">RequestRedirect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">make_alias_redirect_url</span><span class="p">(</span>
- <span class="n">path</span><span class="p">,</span> <span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">e</span><span class="o">.</span><span class="n">matched_values</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">query_args</span><span class="p">))</span>
- <span class="k">if</span> <span class="n">rv</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">continue</span>
- <span class="k">if</span> <span class="n">rule</span><span class="o">.</span><span class="n">methods</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">rule</span><span class="o">.</span><span class="n">methods</span><span class="p">:</span>
- <span class="n">have_match_for</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">methods</span><span class="p">)</span>
- <span class="k">continue</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">redirect_defaults</span><span class="p">:</span>
- <span class="n">redirect_url</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_default_redirect</span><span class="p">(</span><span class="n">rule</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">rv</span><span class="p">,</span>
- <span class="n">query_args</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">redirect_url</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">raise</span> <span class="n">RequestRedirect</span><span class="p">(</span><span class="n">redirect_url</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">rule</span><span class="o">.</span><span class="n">redirect_to</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">redirect_to</span><span class="p">,</span> <span class="n">string_types</span><span class="p">):</span>
- <span class="k">def</span> <span class="nf">_handle_match</span><span class="p">(</span><span class="n">match</span><span class="p">):</span>
- <span class="n">value</span> <span class="o">=</span> <span class="n">rv</span><span class="p">[</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)]</span>
- <span class="k">return</span> <span class="n">rule</span><span class="o">.</span><span class="n">_converters</span><span class="p">[</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)]</span><span class="o">.</span><span class="n">to_url</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- <span class="n">redirect_url</span> <span class="o">=</span> <span class="n">_simple_rule_re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="n">_handle_match</span><span class="p">,</span>
- <span class="n">rule</span><span class="o">.</span><span class="n">redirect_to</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">redirect_url</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">redirect_to</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">rv</span><span class="p">)</span>
- <span class="k">raise</span> <span class="n">RequestRedirect</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">url_join</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="s1">://</span><span class="si">%s%s%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">url_scheme</span> <span class="ow">or</span> <span class="s1">'http'</span><span class="p">,</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span> <span class="o">+</span> <span class="s1">'.'</span> <span class="ow">or</span> <span class="s1">''</span><span class="p">,</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">server_name</span><span class="p">,</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">script_name</span>
- <span class="p">),</span> <span class="n">redirect_url</span><span class="p">)))</span>
- <span class="k">if</span> <span class="n">return_rule</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">rule</span><span class="p">,</span> <span class="n">rv</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">rv</span>
- <span class="k">if</span> <span class="n">have_match_for</span><span class="p">:</span>
- <span class="k">raise</span> <span class="n">MethodNotAllowed</span><span class="p">(</span><span class="n">valid_methods</span><span class="o">=</span><span class="nb">list</span><span class="p">(</span><span class="n">have_match_for</span><span class="p">))</span>
- <span class="k">raise</span> <span class="n">NotFound</span><span class="p">()</span>
- <span class="k">def</span> <span class="nf">test</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path_info</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""Test if a rule would match. Works like `match` but returns `True`</span>
- <span class="sd"> if the URL matches, or `False` if it does not exist.</span>
- <span class="sd"> :param path_info: the path info to use for matching. Overrides the</span>
- <span class="sd"> path info specified on binding.</span>
- <span class="sd"> :param method: the HTTP method used for matching. Overrides the</span>
- <span class="sd"> method specified on binding.</span>
- <span class="sd"> """</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">path_info</span><span class="p">,</span> <span class="n">method</span><span class="p">)</span>
- <span class="k">except</span> <span class="n">RequestRedirect</span><span class="p">:</span>
- <span class="k">pass</span>
- <span class="k">except</span> <span class="n">HTTPException</span><span class="p">:</span>
- <span class="k">return</span> <span class="kc">False</span>
- <span class="k">return</span> <span class="kc">True</span>
- <span class="k">def</span> <span class="nf">allowed_methods</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path_info</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""Returns the valid methods that match for a given path.</span>
- <span class="sd"> .. versionadded:: 0.7</span>
- <span class="sd"> """</span>
- <span class="k">try</span><span class="p">:</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">path_info</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="s1">'--'</span><span class="p">)</span>
- <span class="k">except</span> <span class="n">MethodNotAllowed</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">e</span><span class="o">.</span><span class="n">valid_methods</span>
- <span class="k">except</span> <span class="n">HTTPException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
- <span class="k">pass</span>
- <span class="k">return</span> <span class="p">[]</span>
- <span class="k">def</span> <span class="nf">get_host</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">domain_part</span><span class="p">):</span>
- <span class="sd">"""Figures out the full host name for the given domain part. The</span>
- <span class="sd"> domain part is a subdomain in case host matching is disabled or</span>
- <span class="sd"> a full host name.</span>
- <span class="sd"> """</span>
- <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">host_matching</span><span class="p">:</span>
- <span class="k">if</span> <span class="n">domain_part</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">server_name</span>
- <span class="k">return</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">domain_part</span><span class="p">,</span> <span class="s1">'ascii'</span><span class="p">)</span>
- <span class="n">subdomain</span> <span class="o">=</span> <span class="n">domain_part</span>
- <span class="k">if</span> <span class="n">subdomain</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">subdomain</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">subdomain</span> <span class="o">=</span> <span class="n">to_unicode</span><span class="p">(</span><span class="n">subdomain</span><span class="p">,</span> <span class="s1">'ascii'</span><span class="p">)</span>
- <span class="k">return</span> <span class="p">(</span><span class="n">subdomain</span> <span class="ow">and</span> <span class="n">subdomain</span> <span class="o">+</span> <span class="s1">u'.'</span> <span class="ow">or</span> <span class="s1">u''</span><span class="p">)</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">server_name</span>
- <span class="k">def</span> <span class="nf">get_default_redirect</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rule</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">query_args</span><span class="p">):</span>
- <span class="sd">"""A helper that returns the URL to redirect to if it finds one.</span>
- <span class="sd"> This is used for default redirecting only.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">redirect_defaults</span>
- <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">_rules_by_endpoint</span><span class="p">[</span><span class="n">rule</span><span class="o">.</span><span class="n">endpoint</span><span class="p">]:</span>
- <span class="c1"># every rule that comes after this one, including ourself</span>
- <span class="c1"># has a lower priority for the defaults. We order the ones</span>
- <span class="c1"># with the highest priority up for building.</span>
- <span class="k">if</span> <span class="n">r</span> <span class="ow">is</span> <span class="n">rule</span><span class="p">:</span>
- <span class="k">break</span>
- <span class="k">if</span> <span class="n">r</span><span class="o">.</span><span class="n">provides_defaults_for</span><span class="p">(</span><span class="n">rule</span><span class="p">)</span> <span class="ow">and</span> \
- <span class="n">r</span><span class="o">.</span><span class="n">suitable_for</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">):</span>
- <span class="n">values</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">r</span><span class="o">.</span><span class="n">defaults</span><span class="p">)</span>
- <span class="n">domain_part</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
- <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">make_redirect_url</span><span class="p">(</span>
- <span class="n">path</span><span class="p">,</span> <span class="n">query_args</span><span class="p">,</span> <span class="n">domain_part</span><span class="o">=</span><span class="n">domain_part</span><span class="p">)</span>
- <span class="k">def</span> <span class="nf">encode_query_args</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">query_args</span><span class="p">):</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">query_args</span><span class="p">,</span> <span class="n">string_types</span><span class="p">):</span>
- <span class="n">query_args</span> <span class="o">=</span> <span class="n">url_encode</span><span class="p">(</span><span class="n">query_args</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">charset</span><span class="p">)</span>
- <span class="k">return</span> <span class="n">query_args</span>
- <span class="k">def</span> <span class="nf">make_redirect_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path_info</span><span class="p">,</span> <span class="n">query_args</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">domain_part</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
- <span class="sd">"""Creates a redirect URL.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="n">suffix</span> <span class="o">=</span> <span class="s1">''</span>
- <span class="k">if</span> <span class="n">query_args</span><span class="p">:</span>
- <span class="n">suffix</span> <span class="o">=</span> <span class="s1">'?'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">encode_query_args</span><span class="p">(</span><span class="n">query_args</span><span class="p">)</span>
- <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="s1">://</span><span class="si">%s</span><span class="s1">/</span><span class="si">%s%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">url_scheme</span> <span class="ow">or</span> <span class="s1">'http'</span><span class="p">,</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">get_host</span><span class="p">(</span><span class="n">domain_part</span><span class="p">),</span>
- <span class="n">posixpath</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">script_name</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">'/'</span><span class="p">),</span>
- <span class="n">path_info</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)),</span>
- <span class="n">suffix</span>
- <span class="p">))</span>
- <span class="k">def</span> <span class="nf">make_alias_redirect_url</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">query_args</span><span class="p">):</span>
- <span class="sd">"""Internally called to make an alias redirect URL."""</span>
- <span class="n">url</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">append_unknown</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
- <span class="n">force_external</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">query_args</span><span class="p">:</span>
- <span class="n">url</span> <span class="o">+=</span> <span class="s1">'?'</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">encode_query_args</span><span class="p">(</span><span class="n">query_args</span><span class="p">)</span>
- <span class="k">assert</span> <span class="n">url</span> <span class="o">!=</span> <span class="n">path</span><span class="p">,</span> <span class="s1">'detected invalid alias setting. No canonical '</span> \
- <span class="s1">'URL found'</span>
- <span class="k">return</span> <span class="n">url</span>
- <span class="k">def</span> <span class="nf">_partial_build</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">append_unknown</span><span class="p">):</span>
- <span class="sd">"""Helper for :meth:`build`. Returns subdomain and path for the</span>
- <span class="sd"> rule that accepts this endpoint, values and method.</span>
- <span class="sd"> :internal:</span>
- <span class="sd"> """</span>
- <span class="c1"># in case the method is none, try with the default method first</span>
- <span class="k">if</span> <span class="n">method</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">rv</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_partial_build</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_method</span><span class="p">,</span>
- <span class="n">append_unknown</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">rv</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">rv</span>
- <span class="c1"># default method did not match or a specific method is passed,</span>
- <span class="c1"># check all and go with first result.</span>
- <span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">_rules_by_endpoint</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="p">()):</span>
- <span class="k">if</span> <span class="n">rule</span><span class="o">.</span><span class="n">suitable_for</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">):</span>
- <span class="n">rv</span> <span class="o">=</span> <span class="n">rule</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">append_unknown</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">rv</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">return</span> <span class="n">rv</span>
- <span class="k">def</span> <span class="nf">build</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">method</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">force_external</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
- <span class="n">append_unknown</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
- <span class="sd">"""Building URLs works pretty much the other way round. Instead of</span>
- <span class="sd"> `match` you call `build` and pass it the endpoint and a dict of</span>
- <span class="sd"> arguments for the placeholders.</span>
- <span class="sd"> The `build` function also accepts an argument called `force_external`</span>
- <span class="sd"> which, if you set it to `True` will force external URLs. Per default</span>
- <span class="sd"> external URLs (include the server name) will only be used if the</span>
- <span class="sd"> target URL is on a different subdomain.</span>
- <span class="sd"> >>> m = Map([</span>
- <span class="sd"> ... Rule('/', endpoint='index'),</span>
- <span class="sd"> ... Rule('/downloads/', endpoint='downloads/index'),</span>
- <span class="sd"> ... Rule('/downloads/<int:id>', endpoint='downloads/show')</span>
- <span class="sd"> ... ])</span>
- <span class="sd"> >>> urls = m.bind("example.com", "/")</span>
- <span class="sd"> >>> urls.build("index", {})</span>
- <span class="sd"> '/'</span>
- <span class="sd"> >>> urls.build("downloads/show", {'id': 42})</span>
- <span class="sd"> '/downloads/42'</span>
- <span class="sd"> >>> urls.build("downloads/show", {'id': 42}, force_external=True)</span>
- <span class="sd"> 'http://example.com/downloads/42'</span>
- <span class="sd"> Because URLs cannot contain non ASCII data you will always get</span>
- <span class="sd"> bytestrings back. Non ASCII characters are urlencoded with the</span>
- <span class="sd"> charset defined on the map instance.</span>
- <span class="sd"> Additional values are converted to unicode and appended to the URL as</span>
- <span class="sd"> URL querystring parameters:</span>
- <span class="sd"> >>> urls.build("index", {'q': 'My Searchstring'})</span>
- <span class="sd"> '/?q=My+Searchstring'</span>
- <span class="sd"> When processing those additional values, lists are furthermore</span>
- <span class="sd"> interpreted as multiple values (as per</span>
- <span class="sd"> :py:class:`werkzeug.datastructures.MultiDict`):</span>
- <span class="sd"> >>> urls.build("index", {'q': ['a', 'b', 'c']})</span>
- <span class="sd"> '/?q=a&q=b&q=c'</span>
- <span class="sd"> If a rule does not exist when building a `BuildError` exception is</span>
- <span class="sd"> raised.</span>
- <span class="sd"> The build method accepts an argument called `method` which allows you</span>
- <span class="sd"> to specify the method you want to have an URL built for if you have</span>
- <span class="sd"> different methods for the same endpoint specified.</span>
- <span class="sd"> .. versionadded:: 0.6</span>
- <span class="sd"> the `append_unknown` parameter was added.</span>
- <span class="sd"> :param endpoint: the endpoint of the URL to build.</span>
- <span class="sd"> :param values: the values for the URL to build. Unhandled values are</span>
- <span class="sd"> appended to the URL as query parameters.</span>
- <span class="sd"> :param method: the HTTP method for the rule if there are different</span>
- <span class="sd"> URLs for different methods on the same endpoint.</span>
- <span class="sd"> :param force_external: enforce full canonical external URLs. If the URL</span>
- <span class="sd"> scheme is not provided, this will generate</span>
- <span class="sd"> a protocol-relative URL.</span>
- <span class="sd"> :param append_unknown: unknown parameters are appended to the generated</span>
- <span class="sd"> URL as query string argument. Disable this</span>
- <span class="sd"> if you want the builder to ignore those.</span>
- <span class="sd"> """</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">update</span><span class="p">()</span>
- <span class="k">if</span> <span class="n">values</span><span class="p">:</span>
- <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">MultiDict</span><span class="p">):</span>
- <span class="n">valueiter</span> <span class="o">=</span> <span class="n">iteritems</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">multi</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">valueiter</span> <span class="o">=</span> <span class="n">iteritems</span><span class="p">(</span><span class="n">values</span><span class="p">)</span>
- <span class="n">values</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">((</span><span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">valueiter</span> <span class="k">if</span> <span class="n">v</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">)</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">values</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="n">rv</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_partial_build</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">append_unknown</span><span class="p">)</span>
- <span class="k">if</span> <span class="n">rv</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
- <span class="k">raise</span> <span class="n">BuildError</span><span class="p">(</span><span class="n">endpoint</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
- <span class="n">domain_part</span><span class="p">,</span> <span class="n">path</span> <span class="o">=</span> <span class="n">rv</span>
- <span class="n">host</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_host</span><span class="p">(</span><span class="n">domain_part</span><span class="p">)</span>
- <span class="c1"># shortcut this.</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="n">force_external</span> <span class="ow">and</span> <span class="p">(</span>
- <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">host_matching</span> <span class="ow">and</span> <span class="n">host</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">server_name</span><span class="p">)</span> <span class="ow">or</span>
- <span class="p">(</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">map</span><span class="o">.</span><span class="n">host_matching</span> <span class="ow">and</span> <span class="n">domain_part</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">subdomain</span><span class="p">)</span>
- <span class="p">):</span>
- <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">url_join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">script_name</span><span class="p">,</span> <span class="s1">'./'</span> <span class="o">+</span> <span class="n">path</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)))</span>
- <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="s1">//</span><span class="si">%s%s</span><span class="s1">/</span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">url_scheme</span> <span class="o">+</span> <span class="s1">':'</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">url_scheme</span> <span class="k">else</span> <span class="s1">''</span><span class="p">,</span>
- <span class="n">host</span><span class="p">,</span>
- <span class="bp">self</span><span class="o">.</span><span class="n">script_name</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span>
- <span class="n">path</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span>
- <span class="p">))</span>
- </pre></div>
- </div>
- </div>
- </div>
- <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper"><div class="relations">
- <h3>Related Topics</h3>
- <ul>
- <li><a href="../../index.html">Documentation overview</a><ul>
- <li><a href="../index.html">Module code</a><ul>
- </ul></li>
- </ul></li>
- </ul>
- </div>
- <div id="searchbox" style="display: none" role="search">
- <h3>Quick search</h3>
- <form class="search" action="../../search.html" method="get">
- <div><input type="text" name="q" /></div>
- <div><input type="submit" value="Go" /></div>
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
- </div>
- <script type="text/javascript">$('#searchbox').show(0);</script>
- </div>
- </div>
- <div class="clearer"></div>
- </div>
- <div class="footer">
- ©2016, Author.
-
- |
- Powered by <a href="http://sphinx-doc.org/">Sphinx 1.4.8</a>
- & <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.9</a>
-
- </div>
-
-
- </body>
- </html>
|