Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I kill off a Python web app on GAE early following a redirect?

Disclaimer: completely new to Python from a PHP background

Ok I'm using Python on Google App Engine with Google's webapp framework.

I have a function which I import as it contains things which need to be processed on each page.

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        self.redirect('/main/new')

This works fine when I call it, but how can I make sure the app is killed off after the redirection. I don't want anything else processing. For example I will do this:

class Dashboard(webapp.RequestHandler):
    def get(self):
        some_function(self)
        #Continue with normal code here
        self.response.out.write('Some output here')

I want to make sure that once the redirection is made in some_function() (which works fine), that no processing is done in the get() function following the redirection, nor is the "Some output here" outputted.

What should I be looking at to make this all work properly? I can't just exit the script because the webapp framework needs to run.

I realise that more than likely I'm just doing things in completely the wrong way any way for a Python app, so any guidance would be a great help. Hopefully I have explained myself properly and someone will be able to point me in the right direction.

Thanks

like image 229
Mike Avatar asked Jun 08 '10 23:06

Mike


2 Answers

How about this?

class Dashboard(webapp.RequestHandler):
    def some_function(self):
        if data['user'].new_user and not self.request.path == '/main/new':
            self.redirect('/main/new')
            return True
        else:
            return False
    def get(self):
        if not self.some_function():
            self.response.out.write('Some output here')

For reference, if you're going to need some_function() in a lot of RequestHandlers it would be pythonic to make a class that your other RequestHandlers can subclass from:

class BaseHandler(webapp.RequestHandler):
    def some_function(self):
        if data['user'].new_user and not self.request.path == '/main/new':
            self.redirect('/main/new')
            return False
        else:
            return True

class Dashboard(BaseHandler):
    def get(self):
        if not self.some_function():
            self.response.out.write('Some output here')
like image 172
Dan McDougall Avatar answered Sep 22 '22 15:09

Dan McDougall


I suggest you return a boolean from some_function() based on whether the caller should continue execution or not. Example:

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        self.redirect('/main/new')
        return True
    return False

class Dashboard(webapp.RequestHandler):
    def get(self):
        if some_function(self):
            return
        #Continue with normal code here
        self.response.out.write('Some output here')

There's also a slightly more complicated alternative that might be helpful if some_function() is nested several levels deep, or if you may have many functions like this. The idea: raise an exception indicating that you want processing to stop, and use a subclass of webapp.RequestHandler which simply catches and ignores this exception. Here's a rough idea of how this might go:

class RedirectException(Exception):
    """Raise this from any method on a MyRequestHandler object to redirect immediately."""
    def __init__(self, uri, permanent=False):
        self.uri = uri
        self.permanent = permanent

class RedirectRequestHandler(webapp.RequestHandler):
    def handle_exception(self, exception, debug_mode):
        if isinstance(exception, RedirectException):
            self.redirect(exception.uri, exception.permanent)
        else:
            super(MyRequestHandler, self).handle_exception(exception, debug_mode)

This might make it a little easier to work with some_function() (and make your other request handlers a bit easier to read). For example:

def some_function(self):
    if data['user'].new_user and not self.request.path == '/main/new':
        raise RedirectException('/main/new')

class Dashboard(RedirectRequestHandler):
     # rest of the implementation is the same ...
like image 42
David Underhill Avatar answered Sep 22 '22 15:09

David Underhill