Dennix
Dennix

Reputation: 109

Global variable that persisted only for the lifetime of the request - Python, Webapp2

I have Python script in my WebApp2 application in Google App Engine:

x = 0

class MyHandler(webapp2.RequestHandler):

      def get(self):

          global x
          x = x + 1
          print x

With each refresh of the page (or connect new user), the count increments higher. Python does not kick off a new process on each request (but I expected it). How could I handle scenarios where I'd want a global variable that persisted only for the lifetime of the request? Can I use an instance variable and how exactly?

Upvotes: 0

Views: 746

Answers (1)

Tim Hoffman
Tim Hoffman

Reputation: 12986

The behaviour your seeing is expected. New instances are not started for every request.

Use the request object, env object or a thread local variable to store information that you want to have accessible any where in your code for the life of the request. (Environ is recreated in each request, so it's safe).

See Is threading.local() a safe way to store variables for a single request in Google AppEngine? for a discussion on using thread local storage.

Here is an example of storing the local request object to store specific information for the life of a request. All of this code must be inside your handler. All of the parts are documented in webapp2 docs. By the way I don't use webapp2, so this isn't tested. (I use pyramid/bobo and this model for performing request level caching).

class MyHandler(webapp2.RequestHandler):

  def get(self):
      req = webapp2.get_request()   
      # you have request in self, however this is to show how you get a 
      # request object anywhere in your code.


      key = "Some Key"

      if req:
            # getting some store value from the environ of request (See WebOb docs)
            someval = req.environ.get(key,None)
            if someval :
                # do something

      # and setting
      if req:
            req.environ[key] = 'some value'

Doing it this way there is the limitation that environ['key'] value must be a string.

Read the Webob documents how to store arbitrary values in the request object. http://docs.webob.org/en/stable/reference.html#ad-hoc-attributes -

req.environ['webob.adhoc_attrs']
{'some_attr': 'blah blah blah'}

Also if you have a read of the webapp2 Request object docs, there is a registry that you can use to store information - http://webapp-improved.appspot.com/api/webapp2.html#webapp2.Request

Note, any variable you define outside a request handler is essentially cached, available for the instances lifetime. This is where you are going wrong.

To understand how/why app level caching works - and why your first attempt doesn't do what you want have a look at https://cloud.google.com/appengine/docs/python/requests#Python_App_caching

Upvotes: 1

Related Questions