Force.com for Google App Engine User Guide

Abstract

This document is intended for Developers who want to write Google App Engine Apps that can interact with the Force.com Platform using the Force.com for Google App Engine library.

Prerequisites

This document assumes that you have a general understanding of software development, Web services, the Force.com user interface, the Force.com Platform, Force.com IDE, The Force.com Soap API, Google App Engine, and Python.

For additional Google App Engine reference information, please refer to the Google App Engine Getting Started Guide.

Getting started

Follow the following steps to get started:

  • Install the latest version of the Force.com IDE. The Force.com IDE allows developers a full-featured, Eclipse-based coding environment, with capabilities like code completion, version control,collaborative development, and project sharing.
  • Sign up for App Engine - Signing up is free and only takes a few minutes to complete.
  • Download the source code - The new library is open source and the source code is hosted in a Google Code Repository. If you are not familiar with SVN and source code repositories, you may also use the convenient ZIP file distribution.
  • Rename your Application - It is essential that you rename your Google App Engine application in your app.yaml file to match your application name in your Google App Engine Account.

For instructions on renaming your App, please see Force.com for Google App Engine Setup Guide.

Code Examples

The following examples demonstrate the API methods and provide a few examples of the required Python code.

Include the Python Libraries

First you must import the required libraries.

import os
import beatbox

Background: What is Beatbox?

The term beatbox refers to the library name, this term originated with Simon Fell's Beatbox project, found on the Pocket Soap website. The library has been extended to the latest API version and enhanced by Andrew Burkhalter, to wrap the XML data into nice easy to use Python dictionary objects. Thanks Simon and Andrew!

Create Python Client

Next, create a definition in your code to create a Python client that will be used to communicate with the Force.com Soap API.

self.sforce = beatbox.PythonClient()

Login to Force.com from Google - Cloud-to-Cloud

Your App Engine Application must login to Force.com in order to to initialize the communication cloud-to-cloud. There are two ways that you can login to a Force.com organization:

  1. By prompting for a user name and password (note that a security token may be required in this)
  2. Passing a Salesforce.com session ID and server URL. This method is described in the next section.

Login by Prompting for User name and Password

Below is example code to prompt for user name and password from a Google App Engine App.

self.sforce = beatbox.PythonClient()
try:
	login_result = self.sforce.login(username, password)
except beatbox.SoapFaultError, errorInfo:
	path = os.path.join(os.path.dirname(__file__), 
                                             'templates/simple_login_failed.html')
	self.response.out.write(template.render(path, 
                                                   {'errorCode': errorInfo.faultCode, 
	                                        'errorString': errorInfo.faultString}))
else:
	# Grab the resulting session id
	template_values = {'user_id': login_result['userId'],
	                   'server_url': login_result['serverUrl'],
	                   'session_id': login_result['sessionId']};

	# Render the output
	path = os.path.join(os.path.dirname(__file__), 
                                             'templates/simple_login_result.html')
	self.response.out.write(template.render(path, template_values))		

Login by Passing Session ID and Server URL

When linking directly from a web Tab on Salesforce.com you can pass the server url and session id directly, and therefore avoid prompting the user for a login user name and password.

This technique uses the following steps instead of the login() method.

  1. Create the client
  2. Grab the session id and server URL from the command line that was passed into the google App Engine application.

In this example, we assume that the query string contains the following two parameters

 sid=xxx 
 surl=yyy
 self.sforce = beatbox.PythonClient()
 self.sforce.useSession(self.request.get('sid'), self.request.get('surl'))
 uinfo = self.sfdc.getUserInfo()

Your sid and surl parameters can be constructed in a Force.com web tab using API expression variables

http://yourAPP.appspot.com?sid={!API.Session_ID}&surl={!API.Partner_Server_URL_140}

Force.com API Call Code Examples

Now that you've logged in to Force.com from the Google Cloud, you can take advantage of the Force.com Soap API calls that are supported in the new Force.com for Google App Engine Library.

In the following examples we will explore how to interact with the supported Force.com Soap API Methods from a Python Google App Engine Application using the Force.com for Google App Engine Library.

Supported Force.com Web Services API Methods

The following Soap API calls are currently supported in the Force.com for Google App Engine Library.

  1. Create()
  2. Update()
  3. Delete()
  4. Query()
  5. getUpdated()
  6. getDeleted()
  7. describeGlobal()
  8. describeSobjects()

Create()

You can use the Create() method to add one or more individual records to a Force.com organization. The create() call is analogous to the INSERT statement in SQL.

Example Python code to create a new Account Force.com

sobjects = []
new_acc = { 'type': 'Account', 'name' : 'new GAE account' }
sobjects.append(new_acc)
results = client.create(sobjects)
self.response.out.write( results )

Update()

You can use the Update() method to update one or more existing records in a Force.com organization’s data. The update() call is analogous to the UPDATE statement in SQL.

Example Python Code to Update an Account in Force.com

query_result = client.query( 
       "select id from Account where name like 'new GAE account%' limit 1")
			
if ( query_result['records'].__len__() < 1 ): 
	self.response.out.write('no account found with name : new GAE account ')
else 	:
        account = query_result['records'][0]
	self.response.out.write( account )
			
	account['Name'] = 'new GAE account UPDATED'
	
	results = client.update( account )
	self.response.out.write( results )

Delete()

You can use the Delete() method to delete one or more existing records in your Force.com organization’s data. The delete() call is analogous to the DELETE statement in SQL.

Example Python Code to Delete an Account in Force.com

query_result = client.query( 
          "select id from Account where name like 'new GAE account%' limit 1")
accounts = []
for account in query_result['records'] :
	accounts.append( account['Id'] )
		
if ( accounts.__len__() < 1 ): 
	self.response.out.write('no account found with name : new GAE account ')
else 	:
	results = client.delete( accounts )
	self.response.out.write( results )

Query()

You can use the Query() method to retrieve data from an object in Force.com. When a client application invokes the query() call, it passes in a query expression that specifies the object to query, the fields to retrieve, and any conditions that determine whether a given object qualifies. For an extensive discussion about the syntax and rules used for queries, see Salesforce Object Query Language (SOQL).

Example Python Code to Query Accounts in Force.com

soql = 'select name from Account limit 12'
self.response.out.write('<b>'+soql+'</b>')   
			
query_result = client.query( soql )
for account in query_result['records'] : 	
	self.response.out.write('<li>' + account['Name'] )   

getUpdated()

You can use the getUpdated() method for data replication applications to retrieve a set of IDs for objects of the specified object that have been created or updated within the time window specified.

It is advisable to read Data Replication before using getUpdated() in your client application.

The getUpdated() method takes three parameters, a list of object names, a start time and end time and returns an array of objects that have been updated in the system within the time window specified

Example Python Code to Get Changed Accounts in Force.com

In this simple example, we are looking at any Accounts that have changed today.

now = datetime.now()
then = datetime(now.year, now.month, now.day-1 )
results = client.getUpdated('Account', then, now )
self.response.out.write( results )

getDeleted()

You can use the getDeleted() method for data replication applications to retrieve a list of object instances that have been deleted from your organization’s data within the specified timespan.

The getDeleted() call retrieves a GetDeletedResult object that contains an array of DeletedRecord objects containing the ID of each deleted object and the date/time on which it was deleted.

It is advisable to read Data Replication before using getDeleted() in your client application.

getDeleted() is generally used to synchronize data in remote systems, so that objects deleted in the Force.com system may also be deleted in any remote systems.

Example Python Code to Get Deleted Accounts in Force.com

This method takes three parameters, a list of object names, a start time and end time and returns a list of objects that have been deleted in the system within the time window specified.

In this example we are asking for deleted Accounts. In this simple example, we are looking at any Accounts that have been deleted today.

now = datetime.now()
then = datetime(now.year, now.month, now.day-1 )
results = client.getDeleted('Account', then, now )
self.response.out.write( results )

describeGlobal()

You can use the describeGlobal() method to obtain a list of available objects for your organization. You can then iterate through this list and use describeSobjects() to obtain metadata about individual objects.

Note: Your client application must be logged in with sufficient access rights to retrieve metadata about your organization’s data. For more information, see Factors that Affect Data Access.

Example Python Code to Obtain a List of Available Objects in Force.com

describe = client.describeGlobal()
self.response.out.write( describe )

describeSobjects()

You can use the describeSobjects() method to obtain metadata for a given object or array of objects. You can first call describeGlobal() to retrieve a list of all objects for your organization, then iterate through the list and use describeSObjects() to obtain metadata about individual objects.

Important describeSobjects() Notes

  1. The describeSobjects() API call is limited to a maximum of 100 objects returned.
  2. Your client application must be logged in with sufficient access rights to retrieve metadata about your Force.com organization’s data. For more information, see Factors that Affect Data Access.
  3. In organizations where person accounts are enabled, this call shows Accounts as not createable if the profile does not have access to any business account record types.

describeSobjects() takes a list of strings or a single string as a single argument, this argument specifies the name of the tables to describe and returns a list of dictionaries, each dictionary contains keys for data that describes the table in Salesforce.com, you may access the dictionary members using the keys() instance method of a dictionary and the [] access method of reading data elements in a dictionary.

Example Python Code to Describe Account in Force.com

dict = client.describeSObjects('Account')[0]
self.response.out.write( '<dl>')
for key in dict.keys():
	self.response.out.write( '<dt>'+ key + '</dt><dd>' 
						        + str(dict[key]) + '</dd>' )

Other Force.com Soap API Methods

The Force.com SOAP contains several other methods that are not currently included in the library provided here, these are the subject of future work and include methods in the Metadata API as well as methods for processing workflow, sending email and merging accounts. Please check back for these in a future release of this library. If you are interested in contributing your work or samples please contact us at the Force.com Code Share project and we can add you as project members.

Thanks, Share and Enjoy!

Related Content