Bill Katz

My Brain

An occasionally updated repository of thoughts, past work, and links.

Remote API "Hello World"

Update: There's a Google article on the remote API.

Here are some tips for developers trying to play with the remote_api module release with the 1.1.9 App Engine SDK.

You can look at the bulkloader.py utility.  It uses remote_api and shows how to setup some essential environment variables (os.environ['AUTH_DOMAIN'] and from my tests, you'll also need os.environ['USER_EMAIL']).  On to the hello world...

First, wire the remote_api handler into your app.yaml:

handlers:
- url: /remote_api
 script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
 login: admin

Second, write your local script that will use the remote_api_stub.  This script will have to set the python paths to the appengine modules.  For an elegant approach, look at how Google's SDK provides a convenience wrapper for starting an appengine tool.  You can find this wrapper at:

C:\Program Files\Google\google_appengine\bulkloader.py (on Windows)
/usr/local/bin/bulkloader.py (on Mac)

In the above wrappers, you'll see a global DIR_PATH set to the location of the wrapper file.  You'll have to replace that with the known install location of the SDK.  On Mac, look at the link from /usr/local/bin/bulkloader.py to the actual location in the Applications directory.  On Windows, by default it's in C:\Program Files\Google\google_appengine.

The quickest and dirtiest way to get your script running is to hardwire the appengine directories into your script via the python sys.path.extend(my_sdk_lib_dirs) command.

You can now write a local script that will manipulate your datastore in the cloud.

#!/usr/bin/env python
#
import os
import sys

# Hardwire in appengine modules to PYTHONPATH
# or use wrapper to do it more elegantly
appengine_dirs = ['/Applications/blah/blah/google_appengine'...]
sys.path.extend(appengine_dirs)
# Add your models to path
my_root_dir = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, my_root_dir)

from google.appengine.ext import db
from google.appengine.ext.remote_api import remote_api_stub
import getpass

from models.mystuff import Foo

APP_NAME = 'my-app'
os.environ['AUTH_DOMAIN'] = 'gmail.com'
os.environ['USER_EMAIL'] = 'me@gmail.com'

def auth_func():
 return (raw_input('Username:'), getpass.getpass('Password:'))

# Use local dev server by passing in as parameter:
# servername='localhost:8080'
# Otherwise, remote_api assumes you are targeting APP_NAME.appspot.com
remote_api_stub.ConfigureRemoteDatastore(APP_NAME,
 '/remote_api', auth_func)

# Do stuff like your code was running on App Engine

foos = Foo.all().fetch(100)
for foo in foos:
 foo.note = 'Hello World!'
db.puts(foos)

Category: App Engine

Comments are closed

6 Comments

  1. Thanks! by Jackson (2009-02-14)

    I am not sure how I missed the announcement, but this will be very handy.

    Bulkloader is great for importing data, but this almost eliminates the need for background processes.

    Thanks for the write up!
  2. About your blog by kang (2009-02-15)

    I like your blog very much. However, ghs.google.com is banned in China. Wish you can use ghs.billkatz.com, and point it to 74.125.47.121
    and use your ghs.billkatz.com. 74.125.47.121 is not banned in China. Thank you. 
  3. Thanks! by Jackson (2009-02-16)

    I am not sure how I missed the announcement, but this will be very handy.

    Bulkloader is great for importing data, but this almost eliminates the need for background processes.

    Thanks for the write up!
  4. Re: Article by Andy (2009-02-19)

    Thanks, Bill. This was actually extremely helpful.
  5. Ensure you have retries by Sam (2009-02-25)

    Ensure you have a retry around any datastore operation as its likely that in a large batch of processing you will get at least 1 error.

    eg:

                    #Handle potential timeouts
                    retry_count = 0               
                    while retry_count < 3:
                        try:    
                            entity.put()
                            break
                        except:

                            retry_count = retry_count + 1
                            print "Put error attempt " + str(retry_count)

  6. Article on the App Engine site by Ryan Barrett (2009-02-27)

    thanks, bill! we've also posted an article on remote_api on the app engine site:

    http://code.google.com/appengine/articles/remote_api.html

    happy (remote) hacking!