Revised the decorator. Now all the parameters can be configured via the decorator.
There are sensible defaults for everything but the decorator can override them.
diff --git a/contrib/buzz/buzz_appengine.py b/contrib/buzz/buzz_appengine.py
index 68a514b..f8fc9d4 100644
--- a/contrib/buzz/buzz_appengine.py
+++ b/contrib/buzz/buzz_appengine.py
@@ -17,7 +17,6 @@
 
 import apiclient.ext.appengine
 import logging
-import settings
 import simple_buzz_wrapper
 
 
@@ -29,81 +28,101 @@
   credentials = apiclient.ext.appengine.OAuthCredentialsProperty()
 
 
-def oauth_required(handler_method):
-  """A decorator to require that a user has gone through the OAuth dance before accessing a handler.
+class oauth_required(object):
+  def __init__(self, *decorator_args, **decorator_kwargs):
+    """A decorator to require that a user has gone through the OAuth dance before accessing a handler.
   
-  To use it, decorate your get() method like this:
-    @oauth_required
-    def get(self):
-      buzz_wrapper = oauth_handlers.build_buzz_wrapper_for_current_user()
-      user_profile_data = buzz_wrapper.get_profile()
-      self.response.out.write('Hello, ' + user_profile_data.displayName)
+    To use it, decorate your get() method like this:
+      @oauth_required
+      def get(self):
+        buzz_wrapper = oauth_handlers.build_buzz_wrapper_for_current_user()
+        user_profile_data = buzz_wrapper.get_profile()
+        self.response.out.write('Hello, ' + user_profile_data.displayName)
   
-  We will redirect the user to the OAuth endpoint and afterwards the OAuth
-  will send the user back to the DanceFinishingHandler that you have configured.
-  This should only used for GET requests since any payload in a POST request
-  will be lost. Any parameters in the original URL will be preserved.
-  """
-  def check_oauth_credentials(self, *args):
-    if self.request.method != 'GET':
-      raise webapp.Error('The check_oauth decorator can only be used for GET '
-                         'requests')
+    We will redirect the user to the OAuth endpoint and afterwards the OAuth
+    will send the user back to the DanceFinishingHandler that you have configured.
+  
+    This should only used for GET requests since any payload in a POST request
+    will be lost. Any parameters in the original URL will be preserved.
+    """
+    self.decorator_args = decorator_args
+    self.decorator_kwargs = decorator_kwargs
+    
+  def __call__(self, handler_method):
+    def check_oauth_credentials_wrapper(*args, **kwargs):
+      handler_instance = args[0]
+      # TODO(ade) Add support for POST requests
+      if handler_instance.request.method != 'GET':
+        raise webapp.Error('The check_oauth decorator can only be used for GET '
+                           'requests')
 
-    # Is this a request from the OAuth system after finishing the OAuth dance?
-    if self.request.get('oauth_verifier'):
-      user = users.get_current_user()
-      logging.debug('Finished OAuth dance for: %s' % user.email())
+      # Is this a request from the OAuth system after finishing the OAuth dance?
+      if handler_instance.request.get('oauth_verifier'):
+        user = users.get_current_user()
+        logging.debug('Finished OAuth dance for: %s' % user.email())
 
-      f = Flow.get_by_key_name(user.user_id())
-      if f:
-        credentials = f.flow.step2_exchange(self.request.params)
-        c = Credentials(key_name=user.user_id(), credentials=credentials)
-        c.put()
+        f = Flow.get_by_key_name(user.user_id())
+        if f:
+          credentials = f.flow.step2_exchange(handler_instance.request.params)
+          c = Credentials(key_name=user.user_id(), credentials=credentials)
+          c.put()
         
-        # We delete the flow so that a malicious actor can't pretend to be the OAuth service
-        # and replace a valid token with an invalid token
-        f.delete()
-      handler_method(self, *args)
-      return 
+          # We delete the flow so that a malicious actor can't pretend to be the OAuth service
+          # and replace a valid token with an invalid token
+          f.delete()
+          
+          handler_method(*args)
+          return 
 
-    # Find out who the user is. If we don't know who you are then we can't 
-    # look up your OAuth credentials thus we must ensure the user is logged in.
-    user = users.get_current_user()
-    if not user:
-      self.redirect(users.create_login_url(self.request.uri))
-      return
+      # Find out who the user is. If we don't know who you are then we can't 
+      # look up your OAuth credentials thus we must ensure the user is logged in.
+      user = users.get_current_user()
+      if not user:
+        handler_instance.redirect(users.create_login_url(handler_instance.request.uri))
+        return
     
-    # Now that we know who the user is look up their OAuth credentials
-    # if we don't find the credentials then send them through the OAuth dance
-    if not Credentials.get_by_key_name(user.user_id()):
-      # TODO(ade) make this more configurable using settings.py
-      # Domain, and scope should be configurable
-      p = apiclient.discovery.build("buzz", "v1")
-      flow = apiclient.oauth.FlowThreeLegged(p.auth_discovery(),
-                     consumer_key=settings.CONSUMER_KEY,
-                     consumer_secret=settings.CONSUMER_SECRET,
-                     user_agent='google-api-client-python-buzz-webapp/1.0',
-                     domain='anonymous',
-                     scope='https://www.googleapis.com/auth/buzz',
-                     xoauth_displayname=settings.DISPLAY_NAME)
+      # Now that we know who the user is look up their OAuth credentials
+      # if we don't find the credentials then send them through the OAuth dance
+      if not Credentials.get_by_key_name(user.user_id()):
+        
+        # Set up the default arguments and override them with whatever values have been given to the decorator
+        flow_settings = {
+        'consumer_key' : 'anonymous',
+        'consumer_secret' : 'anonymous',
+        'user_agent' : 'google-api-client-python-buzz-webapp/1.0',
+        'domain' : 'anonymous',
+        'scope' : 'https://www.googleapis.com/auth/buzz',
+        'xoauth_display_name' : 'Default Display Name For OAuth Application'
+        }
+        
+        flow_settings.update(self.decorator_kwargs)
+        
+        p = apiclient.discovery.build("buzz", "v1")
+        flow = apiclient.oauth.FlowThreeLegged(p.auth_discovery(),
+                                              consumer_key=flow_settings['consumer_key'],
+                                              consumer_secret=flow_settings['consumer_secret'],
+                                              user_agent=flow_settings['user_agent'],
+                                              domain=flow_settings['domain'],
+                                              scope=flow_settings['scope'],
+                                              xoauth_displayname=flow_settings['xoauth_display_name'])
 
-      # The OAuth system needs to send the user right back here so that they
-      # get to the page they originally intended to visit.
-      oauth_return_url = self.request.uri
-      authorize_url = flow.step1_get_authorize_url(oauth_return_url)
+        # The OAuth system needs to send the user right back here so that they
+        # get to the page they originally intended to visit.
+        oauth_return_url = handler_instance.request.uri
+        authorize_url = flow.step1_get_authorize_url(oauth_return_url)
       
-      f = Flow(key_name=user.user_id(), flow=flow)
-      f.put()
+        f = Flow(key_name=user.user_id(), flow=flow)
+        f.put()
       
-      self.redirect(authorize_url)
-      return
+        handler_instance.redirect(authorize_url)
+        return
     
-    # If the user already has a token then call the wrapped handler
-    handler_method(self, *args)
-  return check_oauth_credentials
+      # If the user already has a token then call the wrapped handler
+      handler_method(*args)
+    return check_oauth_credentials_wrapper
 
-def build_buzz_wrapper_for_current_user():
+def build_buzz_wrapper_for_current_user(api_key):
   user = users.get_current_user()
   credentials = Credentials.get_by_key_name(user.user_id()).credentials
-  return simple_buzz_wrapper.SimpleBuzzWrapper(api_key=settings.API_KEY, 
+  return simple_buzz_wrapper.SimpleBuzzWrapper(api_key=api_key, 
                                                  credentials=credentials)
\ No newline at end of file