views:

79

answers:

2

I am making a Google AppEngine application and am doubting were I should store (sensitive) configuration data like credentials.

Should I make a single bigtable entity for configuration, or is there another advised way to store it.

+3  A: 

Store them in a module. You can go simple, like having a config.py module with, say:

AMAZON_KEY = 'XXXX'

Then use:

import config
service = my_amazon_service(config.AMAZON_KEY)

Or have a slightly more sophisticated config object that allows you to have sensible defaults for your app, namespaced config keys etc.

moraes
+3  A: 

If you're okay with embedding them in your source, you can do that, but if you need it to be dynamically configurable, the datastore is the way to go. You can avoid fetching the settings on every request by caching them in local memory. Here's a helper class for that:

class Configuration(db.Model):
  _INSTANCE = None

  @classmethod
  def get_instance(cls):
    if not cls._INSTANCE:
      cls._INSTANCE = cls.get_or_insert('config')
    return cls._INSTANCE

Simply subclass this with whatever configuration values you need (or modify the class itself). Because loaded code persists between requests, you'll only have to do a single fetch per app instance - though if you want to be able to update the configuration dynamically, you may want to build in a timeout.

If you want to cache stuff for a limited time, your best option is simply storing the timestamp when you fetched it:

class Configuration(db.Model):
  CACHE_TIME = datetime.timedelta(minutes=5)

  _INSTANCE = None
  _INSTANCE_AGE = None

  @classmethod
  def get_instance(cls):
    now = datetime.datetime.now()
    if not cls._INSTANCE or cls._INSTANCE_AGE + cls.CACHE_TIME < now:
      cls._INSTANCE = cls.get_or_insert('config')
      cls._INSTANCE_AGE = now
    return cls._INSTANCE
Nick Johnson
Very interesting, I've never seen this technique before. Typically I would use memcache in order to minimize the number of fetches from the datastore but this looks like to be even faster as long as the instance is loaded. Any memory limit which would prevent from using this too much ?
Franck
Yes, there are memory limits - though they're subject to change. You probably shouldn't use instance memory for generalized caching, but it's ideal for configuration data.
Nick Johnson
Ok thanks I will keep this in mind. Do you have any pointer on how to build the timeout you were talking about ?
Franck
systempuntoout
@Franck @systempuntoout Updated the answer with a demonstration.
Nick Johnson
Thanks again for the update.
Franck
@Nick elegant solution, thanks
systempuntoout