Hello guys
Trade secrets are not a concern at this point. I have to say that my
current musings with App Engine just happen to be the first experience
with Python and the whole Pythonic ecosystem (love it so far). Here's
a link (
http://wiki.developers.facebook.com/index.php/
PythonPyFacebookTutorial) to tutorial that covers some of the aspects
of using PyFacebook. I personally found it easy to use the core
offered by the PyFacebook (mainly due to any previous experience with
Django). In a nutshell here's the usage scenario (please take it with
a grain of salt). Note: Facebook.create() - static method I added that
provides all the required credentials to the Facebook constructor
f = Facebook.create()
if f.check_session(self.request):
# normal workflow
else:
if not f.added:
#app needs to be adde
url2AddApp = f.get_add_url()
self.response.out.write('<fb:redirect url="%s" />' %
url2AddApp)
else:
# login
It would make sense to wrap this functionality as part of the subclass
of webapp.RequestHandler.
If check_session returned true, you are basically ready to go. Take a
look at METHODS dictionary that has all the api supported by the
Facebook class:
METHODS = {
# feed methods
'feed': {
'publishStoryToUser': [
('title', str, []),
('body', str, ['optional']),
('image_1', str, ['optional']),
('image_1_link', str, ['optional']),
('image_2', str, ['optional']),
('image_2_link', str, ['optional']),
('image_3', str, ['optional']),
('image_3_link', str, ['optional']),
('image_4', str, ['optional']),
('image_4_link', str, ['optional']),
('priority', int, ['optional']),
],
'publishActionOfUser': [
('title', str, []),
('body', str, ['optional']),
('image_1', str, ['optional']),
('image_1_link', str, ['optional']),
('image_2', str, ['optional']),
('image_2_link', str, ['optional']),
('image_3', str, ['optional']),
('image_3_link', str, ['optional']),
('image_4', str, ['optional']),
('image_4_link', str, ['optional']),
('priority', int, ['optional']),
],
'publishTemplatizedAction': [
# facebook expects title_data and body_data to be JSON
# simplejson.dumps({'place':'Florida'}) would do fine
# actor_id is now deprecated, use page_actor_id instead
('actor_id', int, []),
('page_actor_id', int, []),
('title_template', str, []),
('title_data', str, ['optional']),
('body_template', str, ['optional']),
('body_data', str, ['optional']),
('body_general', str, ['optional']),
('image_1', str, ['optional']),
('image_1_link', str, ['optional']),
('image_2', str, ['optional']),
('image_2_link', str, ['optional']),
('image_3', str, ['optional']),
('image_3_link', str, ['optional']),
('image_4', str, ['optional']),
('image_4_link', str, ['optional']),
('target_ids', list, ['optional']),
],
},
# fql methods
'fql': {
'query': [
('query', str, []),
],
},
# friends methods
'friends': {
'areFriends': [
('uids1', list, []),
('uids2', list, []),
],
'get': [],
'getAppUsers': [],
},
# notifications methods
'notifications': {
'get': [],
'send': [
('to_ids', list, []),
('notification', str, []),
('email', str, ['optional']),
],
'sendRequest': [
('to_ids', list, []),
('type', str, []),
('content', str, []),
('image', str, []),
('invite', bool, []),
],
'sendEmail': [
('recipients', list, []),
('subject', str, []),
('text', str, ['optional']),
('fbml', str, ['optional']),
]
},
# profile methods
'profile': {
'setFBML': [
('markup', str, ['optional']),
('uid', int, ['optional']),
('profile', str, ['optional']),
('profile_action', str, ['optional']),
('mobile_fbml', str, ['optional']),
],
'getFBML': [
('uid', int, ['optional']),
],
},
# users methods
'users': {
'getInfo': [
('uids', list, []),
('fields', list, [('default', ['name'])]),
],
'getLoggedInUser': [],
'isAppAdded': [],
'hasAppPermission': [
('ext_perm', str, []),
],
'setStatus': [
('status', str, []),
('clear', bool, []),
],
},
# events methods
'events': {
'get': [
('uid', int, ['optional']),
('eids', list, ['optional']),
('start_time', int, ['optional']),
('end_time', int, ['optional']),
('rsvp_status', str, ['optional']),
],
'getMembers': [
('eid', int, []),
],
},
# update methods
'update': {
'decodeIDs': [
('ids', list, []),
],
},
# groups methods
'groups': {
'get': [
('uid', int, ['optional']),
('gids', list, ['optional']),
],
'getMembers': [
('gid', int, []),
],
},
# marketplace methods
'marketplace': {
'createListing': [
('listing_id', int, []),
('show_on_profile', bool, []),
('listing_attrs', str, []),
],
'getCategories': [],
'getListings': [
('listing_ids', list, []),
('uids', list, []),
],
'getSubCategories': [
('category', str, []),
],
'removeListing': [
('listing_id', int, []),
('status', str, []),
],
'search': [
('category', str, ['optional']),
('subcategory', str, ['optional']),
('query', str, ['optional']),
],
},
# pages methods
'pages': {
'getInfo': [
('page_ids', list, ['optional']),
('uid', int, ['optional']),
],
'isAdmin': [
('page_id', int, []),
],
'isAppAdded': [
('page_id', int, []),
],
'isFan': [
('page_id', int, []),
('uid', int, []),
],
},
# photos methods
'photos': {
'addTag': [
('pid', int, []),
('tag_uid', int, [('default', 0)]),
('tag_text', str, [('default', '')]),
('x', float, [('default', 50)]),
('y', float, [('default', 50)]),
('tags', str, ['optional']),
],
'createAlbum': [
('name', str, []),
('location', str, ['optional']),
('description', str, ['optional']),
],
'get': [
('subj_id', int, ['optional']),
('aid', int, ['optional']),
('pids', list, ['optional']),
],
'getAlbums': [
('uid', int, ['optional']),
('aids', list, ['optional']),
],
'getTags': [
('pids', list, []),
],
},
# fbml methods
'fbml': {
'refreshImgSrc': [
('url', str, []),
],
'refreshRefUrl': [
('url', str, []),
],
'setRefHandle': [
('handle', str, []),
('fbml', str, []),
],
},
'data': {
'getCookies': [
('uid', int, []),
('string', str, []),
],
'setCookie': [
('uid', int, []),
('name', str, []),
('value', str, []),
('expires', int, ['optional']),
('path', str, ['optional']),
],
},
}
To get a list of current user friends that use the app, for example,
you do the following
f.friends.getAppUsers()
Which gives you a list of their uids. Most methods supported by
Facebook class take a list of fields to fetch so you have some pretty
awesome control on what you actually fetch.
Hope this helps (please correct any inaccuracies)