Appengine Development

I've been quite enjoying writing some code for Google Appengine this week. Just a small project for querying a variety of book retailer websites for information.

I'm really impressed with it so far. Having the ability to simply import and use things like memcache and use it is excellent. It works locally with some kind of cache, and then when I deploy my app it uses a memcache on the server side seamlessly.

I'm also liking that the urlfetch infrastructure built into appengine supports async downloading of webpages, so i can fire off 5+ API queries simultaneously and then collect the results, instead of doing them in sequence.

Here's a random bit of code I threw together that lets me cache the results of doing API queries in memcache so that a user doing reloads won't cause more API requests to occur than are strictly necessary:

from google.appengine.api import urlfetch
from google.appengine.api import memcache

CACHE_TIMEOUT = 3600 # 1 hour

class APIError(Exception):

def cache_result(rpc, url):
    result = rpc.get_result()
    if result.status_code == 200:
        data = result.content
        memcache.add(url, data, CACHE_TIMEOUT)

def apiquery(url):
    data = memcache.get(url)
    if data is not None:
        decoded_data = json.loads(data)
        return lambda:decoded_data

    logging.debug("Cache miss for %r", url)

    rpc = urlfetch.create_rpc()
    rpc.callback = lambda: cache_result(rpc, url)
    urlfetch.make_fetch_call(rpc, url, method=urlfetch.GET)

    def answer():
        result = rpc.get_result()
        if result.status_code == 200:
            data = result.content
            return json.loads(data)
        raise APIError, "Broken!"
    return answer

With the above code I can now do something like:

queries = [apiquery(url) for url in generate_api_queries()]
for query in queries:
    result = query()
    ... # do stuff with result

I don't really like the variable names I've used, but it's an interesting enough bunch of code linking together a few bits and pieces so I thought I'd throw it on my blog.


Cat Pictures


Now that's one statically charged cat. I wonder if someone was
taunting him with catnip or tuna at the top of the slide? At least
he's getting some exercise.


Favicon Finding

I was updating some of my blog settings, and noticed in blogspot that I can customise the favicon that it will use. I thought, "I know, I'll search for a favicon."

Wow, that was a mistake. The entire area of icons, and web icons, is SEO'd to hell (Asking me to spend £0.06 on an icon screams 'credit  card theft' to me, not 'bargain'), and once I found a source of  favicons I was immediately hit with that other problem - too many choices.

I guess I'll just leave the basic blogspot icon on http://shiny.thorne.id.au then.