Package: matcha
A WSGI dispatcher.At a glancematcha is a dispatcher for all WSGI application
based on a matching pattern of PATH_INFO in environ.Let’s register your WSGI applications to matchings and
create WSGI application.>>>fromwsgiref.simple_serverimportmake_server>>>frommatchaimportMatchingasm,bundle,make_wsgi_app>>>>>>fromyourprojectimporthome_app>>>fromyourproject.blogimportpost_list_app,post_detail_app>>>>>>>>>matching=bundle(...m('/',home_app,'home'),...m('/post/',post_list_app,'post_list'),...m('/post/{post_slug}/',post_detail_app,'post_detail'),...)>>>>>>if__name__=='__main__':...app=make_wsgi_app(matching)......httpd=make_server('',8000,app)...httpd.serve_forever()Now, accessing from your browser:http://127.0.0.1:8000/=> home_app will be calledhttp://127.0.0.1:8000/post/=> post_list_app will be calledhttp://127.0.0.1:8000/post/some_slug/=> post_detail_app will be calledURL argumentsWhen path elements covered with braces, this handled asURL arguments.
This path element can match any string and you can use that string
in your WSGI application.The URL arguments can get fromenviron[‘matcha.matched_dict’]in your WSGI application.
For instance, accessing to‘/post/hello_world/’,
you can get‘hello_world’string as URL arguments like this:>>># In post_detail_app:>>>environ['matcha.matched_dict']{'post_slug':'hello_world'}WildcardIf the last element in pattern starts with ‘*’,
the following string is considered aswildcard_name.
And correspond path will always match.>>>matching=bundle(m('/',home_app,'home'),m('/docs/*doc_tree',document_app,'docs'))And then, you can access them:http://127.0.0.1:8000/=> home_apphttp://127.0.0.1:8000/docs=> document_apphttp://127.0.0.1:8000/docs/about=> document_apphttp://127.0.0.1:8000/docs/about/contributing=> document_appAfter /docs/ it will match any cases.And getting the argument.>>># In document_app, when accessed by '/docs/about/contributing'>>>environ['matcha.mathed_dict']{'doc_tree',['about','contributing']}>>>environ['PATH_INFO']'/about/contributing'>>>environ['SCRIPT_NAME']'/docs'You can also use this implementation to call another WSGI application
such as dispatching again by using the left PATH_INFOReversingWeb pages usually contains some URLs for a another page.
In this case, post list page is for showing URLs
to each Blog posts (to post_detail application).Let’s take URL to post_detail application. You can do like this:>>># In post_list_app>>>matching=environ['matcha.matching']>>>matching.reverse('post_detail',post_slug='about_matcha')'/post/about_matcha/'The first positional argument is a signature string for applications.
It provided as the third argument of each Matching’s constructors.The keyword argument is a string to fill up the URL arguments.Careflly, reverse method will raise NotReverced exception when
any URLs is not matched.OK. and then, you can provide this URL to some TemplateEngines
to display HTML pages.Including another matchingsFor more reusability, let’s separate applications for blogs
from core matching.# In yourproject/blog/matching.py filefrommatchaimportMatchingasm,bundlefromyourproject.blogimportpost_list_app,post_detail_appmatching=bundle(m('/',post_list_app,'post_list'),m('/{post_slug}/',post_detail_app,'post_detail'),)And then, applying this to core by usingincludefunction:>>>frommatchaimportinclude>>>fromyourproject.blog.matchingimportmatchingasblog_matching>>>>>>matching=bundle(...m('/',home_app,'home'),...include('/post/',blog_matching)...)Matching paths will be like this:/=> home application/post/=> post_list application/post/some_slug/=> post_detail applicationBy usinginclude, you can separate paths based on each applications
and avoid repeating of descriptions (such as ‘/post/’).Name for reverisng to childs are not affected in any way.
This value should be unique, even in the all of matchings
(fixed in matcha 0.3):>>>matching.reverse('post_detail',post_slug='some_slug')'/post/some_slug/'Setting your 404 WSGI applicationThe path matching failed the maked application by matcha will
return a plain 404 page.
But most cases, you want to custorm this page more friendly
for users.For solving this,matcha.make_wsgi_appcan takenot_found_appkeyword argument to provide your own WSGI application for showing
404 page.By default, the not_found_app is matcha.not_found_app.What is Matching objectsAlmost core features provided by matcha dispatcher
is implamented as Matching objects.Now, through above example, you recognize matching is like this:matching is created by using bundle function and Matching class.Registering WSGI apllications to matching.matching can get from environ dictionalyNot wrong, but Matching class is something more flexible than
your recognition.Callingmatching is callabletaking environ dictionarysideeffecting environ dictionaryreturning matched case and dictionaryThat sideeffection is for PATH_INFO and SCRIPT_NAME to tell
which path elements are processed to another WSGI application.>>>environ={'PATH_INFO':'/htt','SCRIPT_NAME':'/about'}>>>Matching('/htt',about_htt_app)(environ)(about_htt_app,{})>>>environ{'PATH_INFO':'','SCRIPT_NAME':'/about/htt'}Getitem from matchingcailling of matching requires environ dictionaly, but using getitem
you can only apply path to get matched case and dictionaly.>>>Matching('/htt',about_htt_app)['/htt'](about_htt_app,{})Registering not only WSGI appSecond positional argument (casekeyword argument) of Matching class
can take any objects you like, not only WSGI app.>>>Matching('/home','home')['/home']('home',{})For instance, you can register strings and use this as signature
for some views. something likeroute_nameonPyramid.Adding matchingsActually,bundlefunction used in above examples is just for
adding provided positional arguments (addable objects).
So you can make WSGI application without this function:>>>app=make_wsgi_app(...Matching('/',home_app)+\...Matching('/abount',about_app)...)Thanksmatcha dispatcher has been influenced these dispatchers:Django‘s URL dispatcherWebDispatchgargant.dispatchThanks for them.ResourcesPyPIRepositoryTestingChanges0.3Un-supporting name argument on include functionBefore this change, user applied include name,
the reversing in included app will break, because
the name for reversing already changed.0.2Supporting Wildcard0.1Initial release.