Sunday, January 31, 2010

Adding "Remove" function

Not a huge amount of code, but I added an action to delete a run from the tracker.  Basically the run page now has a little trash can next to each run you log.  I found this cool site that has a great page of icons.  I am no design dude, so this was a real life saver.  Selecting the trash can passes the run's BigTable key into the new web action.


class RemoveRunAction(webapp.RequestHandler):
    '''The handler used to remove a Run from the system'''
    def get(self):
        key = self.request.get('key')
        run = Run.get(key)
        run.delete()
        ClearRunCache()
        self.redirect('/')


Like I said, not a lot of code!  Basically get the key from the request, find the run, delete the run, and clear the memcache.  The call I used to clear the cache is memcache.delete which clears the run cache for this one runner only.  It doesn't reset the entire caching system. All the code is updated on github, the links on the left point you to my branch and to the application.  I copy/pasted the code above from github, just noticed it looks a lot better than the copy/paste from eclipse.

Friday, January 22, 2010

Source added to git hub

Motivated by a discussion at work, I added all the source for this app to github.  It is a pretty cool free source code repository.  Free if you want everyone to see your code, pay a few dollars if you want it private.  Very easy setup and configuration.  Feel free to check out my code and offer and comments or suggestions.

http://github.com/jamessummerlin/pyruntracker

You can look at the code right on the site.  They display the code syntax highlighted and with line numbers!

Thursday, January 21, 2010

Using Google App Engine memcache

I finally got memcache working correctly with my Google App Engine Model.  I have read where this version of memcache is a bit different than you would expect.  It works just like memcached, but specific to GAE and perhaps a different backend implementation.  Either way, it keeps with memcached APIs and is very easy to use.  I wanted to play with this and see how it works on my test app, the run tracker.  My app's data model is a runner who has entered many runs.  I figured a good use of a cache was to cache the list of runs a runner has entered.

A "Run" is an app engine Model class.  My initial thought was to add that to memcache using this call:

memcache.set(users.get_current_user().email(), runs)

Turns out I made a rookie mistake here.  What I intended to do was add the set of "runs" to the cache with the users email address as the key.  The problem is that it never worked.  I kept getting errors on the template rendering telling me that "'Runs' object is not iterable".  My assumption is that Runs is not a dataset anymore.  Turns out I was correct.  I found this blog post that pointed out my mistake.  I was caching the query and not the data itself.  I had to get the data first

runs = Runs.all().ancestor(runner)

Now this worked, memcache is working on my app!  To get my set of runs from the cache, all I had to do is this:

runs = memcache.get(users.get_current_user().email())

Very easy, no problems after that one speed bump.  I did see something interesting in that blog post I posted above though.  A link at the end of it pointed to this blog.  This is an excellent article on making your memcache more efficient.  I implemented the serialize/deserialize code in my app.  Not sure how much my app will benefit, but it was nice to put in there.

That is it, I need to clean up some code and will post new versions soon.

Thursday, January 14, 2010

APUG Presentation

I presented what I have coded so far to the Austin Python Users Group (APUG).  It was a lot of fun.  I was a bit nervous, this was only the second meeting I have attended.  This is a great group of super bright people, so it was nice to bounce this stuff off them and get their input, feedback and brainstorming.  I love that environment.

I have shared by presentation and code through Google Docs.  Feel free to check out what I have done and give me any feedback.

Saturday, January 9, 2010

Revision 0.0

Today I sat down to finish up some styling, clean up some code, and publish this test run tracking program to the Google App Engine to see what will happen.  Exciting day!

First I worked on a bit of styling.  If you know me, you know this isn't a strength of mine, but I wanted to at least line things up, give it some color and some font love.  Played CSS for a few hours making the table and forms "presentable".  Still far from a nice looking application, but it will do for now.

Then some code cleanup.  Removed a ton of code that I thought I needed, but turned out I didn't.  It always makes you feel good to remove stuff that was causing bugs anyway.  Then you really feel you have a good clean foundation to start with.  Note a few items.

  1. There is no error checking in this version.  The goal was to learn how to go from zero to something that persists data on the Google Application Engine.  Error checking is next :-)
  2. No Delete function. That is coming next, before the other next thing.
  3. Form fields are just text, no number validation or minutes conversion.
  4. Avatars are supported by Gravatar, not the Google profile avatar.  Not sure why Google isn't using their own profile, but I didn't see anyway to get to the Google profile avatar, so I used Gravatar.

Probably a million other items, but those are what is on my list now.  I don't really have a list, this blog is it so I will probably post thoughts on missing pieces as they come up.

So I cleaned up the code, styled it a bit, and it seems ready to go.  Now to get it up on the Google App Engine.  It is a simple procedure really, you register for an app account.  You only get 10 applications, so don't go crazy registering apps.  You give your app a name, and that is it.

Put the application name in your app.yaml file.  appl.yaml needs to live in the root directory of your project, this is what you use to configure you application.  Add your application name here, my app name is "pyruntracker"


application: pyruntracker
version: 1
runtime: python
api_version: 1


Then you use appcfg.py to deploy your project out to Google.  This is the cool part.  Just use the following command line to deploy, appcfg.py is in the app engine SDK.

appcfg.py update directory

Enter your Google email address/password, and off it goes!  It runs a test to see that it is up and running, and that is it.  Super easy, worked perfectly.  Here is the URL to my app

http://pyruntracker.appspot.com/

I am going to post the code too, I just have to figure out a nice way to do that on a blog.  Suggestions are welcome.  Maybe I will create a blog post per file, so I can describe what I did.  There isn't that much code.