[Grok-dev] view predicates in Grok?

Paul Wilson paulalexwilson at gmail.com
Mon Jan 4 06:46:02 EST 2010


2010/1/2 Martijn Faassen <faassen at startifact.com>:
> Could you sketch out some brief "science fiction" documentation (or at
> least code samples) where Grok uses predicates? If you can't come up
> with a good spelling, please just show the alternatives so we can talk
> it over.

If Grok was to mimic the BFG system, it would look something like this:

class FooView(grok.View):
	grok.context(...)
	grok.name(...)
	grok.predicate(containment=MyContainer,
		       request_method='POST')

	...

You see, in BFG you are provided a restricted set of predicates from which
you can construct propositions, which are evaluated on a per-request basis.
The set includes things such as `request_method` which can be set to 'GET',
'POST', and so on, `request_param` which checks the parameters set in the
URL or POST form, `accept` which represents the mime-type of the HTTP request,
and so on. All such predicates have to evaluate to 'True' for the view to
match.

This is in contrast to the authorization framework `repoze.what`'s predicate
checker system, which gives a slighter fuller 'predicate calculus', allowing
you to match when `any` of the predicates evaluate to True.

It's also worth noting that the BFG system allows you to define a list of
predicate functions that are also involved in the view selection process.
For example, you can define a function:

def predicate1(request, context):
	if request.header['foo'] == 'bar' and
	   context.foo == 'bar':
		return True

and specify it as follows:

class FooView(grok.View):
	grok.context(...)
	grok.name(...)
	grok.predicate(containment=MyContainer,
		       custom_predicates=[predicate1,
		                          predicate2,
					  predicate3])
	...

This allows any kind of logical spelling to be given as part of the view
matching process, inside or outside of the domain of requests and contexts.
Want your views to be selected based on prevailing weather conditions? No
problem!

I did entertain the idea of allowing the provided predicates to be used within
your predicate function:

class FooView(grok.View)
	grok.context(...)
	grok.name(...)
	grok.predicate.containment(MyContainer)
	grok.predicate.custom_predicates=predicate1 # Can also be a sequence
	...

def predicate1(request, context):
	if grok.predicate.request_method('POST') and
	   context.foo == 'bar':
		return True

Using some deep Python magic this is probably possible, but it is
unnecessary magic;
the request API is simple enough anyway for you to be able to feasibly
recreate any of
the predicate's work anyway! However, splitting the predicates out
like this would allow us
to use martian's built in checkers to perform validation on predicates
in a natural way. Also,
we could inherit predicates from parent views too:

class POSTView(grok.View):
	grok.predicate.request_method('POST')

Any thoughts?

Hope that helps,
Paul


More information about the Grok-dev mailing list