[Twisted-web] State and web2 (or, how to not follow REST)

Clark C. Evans cce at clarkevans.com
Mon Nov 21 12:41:47 MST 2005


On IRC today, foom pointed out that my idea for distinguishing between
things that modify a request (a IRequestHandler) such as setting up a
session or authenticating a user, must also be able to happen between
IResources.  The example given was /~user/bing/my-app/foo, where
authentication (and possibly setting up a session) happens:
/~user/bing/{HERE}my-app/foo

So, goal is to distinguish between Resources which should not be
modifying the request's context and RequestFilters which by definition
change the request. The glue can be done by having a ContextResource
that explicitly applies one or more RequestFilters on the current
request.  We can then designate a syntax for asserting that the
application of a particular IRequestFilter has been done on the request.
Anyway, just consider this a random attempt to detail the idea....

  class IRequestFilter(Interface):
      """
          I am a filter that is applied to a given request, examples of
          a RequestFilter are, a "SessionManager", "Authenticator", etc.
      """

      def apply(self, request):
          """ Perform necessary logic on the request, modifying the
              request's context as necessary and/or raising HTTPError
              as needed.   Ideally only an IRequestFilter modifies a
              request's context.
          """

  class IResource:
      # same as before, adding:

      require = Attribute(
                   "A sequence of IRequestFilters which must have
                    been applied to a Request before this resource
                    is accessed")

  class IRequest(Interface):
      # same as before, adding:
      
      filtered = Attribute(
                  "A sequence of IRequestFilters that have been applied.")

      # since there are two objects that are so commonly used, I feel
      # that they merit their own "slot" on the Request object:

      session = Attribute("An optional ISession object added by the 
                  ISessionRequestFilter.")

      avatar = Attribute("An optional IAvatar object added by the
                 IAuthenticateRequestFilter, or other providers of
                 an IAvatar")

  class ContextResource(Resource):  # or SiteResource, or AppResource
      """
          I am a application or site resource which modifies the
          incoming request via a set of RequestFilters.  Only 
          ContextResources should be doing this sort of thing.
      """
       
      filter = None

      def registerFilter(self, requestFilter):
          if not self.filter:
               self.filter = [requestFilter]
               return
          self.filter.append(requestFilter)
     
      def locateChild(self, request, segments):
          for filter in self.filter:
              filter.apply(request)
              request.filtered.append(filter)
          Resource.locateChild(self, request, segments)


myapp = ContextResource()
myapp.registerFilter(SessionManager())
myapp.registerFilter(HTTPAuthHandler())





More information about the Twisted-web mailing list