Saturday, February 28, 2009

用python寫facebook application

前陣子 剛好在看google提出的service時 注意到了app engine
因為它整個都是python寫的 重燃了我對web的小小興趣
發現google上有一篇關於facebook的文章 於是就開始熱血了

照理說 工程師的第一個sample code 應該是hello world
但是對我而言 我的hello world就是sudoku
Once upon a time ......

Download the source code for this example application here:

I. Set up the working environment
a. install Google App Engine:
svn checkout googleappengine-read-only

b. install pyfacebook:
svn checkout pyfacebook

c. create a new 'app engine' application :
remember the app URL and app ID

d. set up a new facebook application:
remember the API, secret key, fill out the callback URL

II. Start coding
a. how to make a 9*9 sudoku puzzle: use html table & CSS style

b. using Django html templates:
this part is really like what i did for daily news website. The designers
make a beautiful html page. We cut some places in html page and paste with
'{{ params }}'. These {{ params}} would replace with DB data or other
programming result. I made three html template files for this demo, main puzzle page,
score page and upload score result page.

c. prepare 'app.yaml':
this file can define the application name and handlers for URLs. It can make
the App more organized.

d. prepare '':

this file would take care of facebook login problem and retrieve data from
facebook website.

Example 1: try to get auth_token from Facebook by your keys, it would ask user login first.

# instantiate the Facebook API wrapper with your FB App's keys
fb = facebook.Facebook(_FbApiKey, _FbSecret)
auth_token = self.request.get('auth_token')

if not fb.check_session(self.request) or not auth_token:
url = fb.get_login_url()
session_key = self.request.get('fb_sig_session_key')
uid = self.request.get('fb_sig_user')

Example 2: Retrieve the user detailed information by user ID

# retrieve the user data from facebook by few keys
fb = facebook.Facebook(_FbApiKey, _FbSecret)
fb.session_key = self.request.get('session_key')
fb.uid = self.request.get('uid')
info = fb.users.getInfo([fb.uid],['name','pic','profile_url'])
user = info[0]
player_name = str(user['name'])

e. how to keep the game score data: (using google data store API)
Before, I need to use a MySQL to store the data, but google provides a very useful datastore api. It can define table schema and make sql querys. Then you can store the web data like database.

Example 1: define a GameScore class like a table in DB

# define GameScore like a table
class GameScore(db.Model):
player = db.StringProperty()
date = db.DateProperty(auto_now_add=True)
score = db.IntegerProperty()
level = db.StringProperty()
show = db.BooleanProperty()
content = db.StringProperty(multiline=True)
name = db.StringProperty()
photo = db.LinkProperty()
profile = db.LinkProperty()

Example 2: retrieve top ten records by date (make a SQL query)

# retrieve today top ten records only
q = db.GqlQuery("SELECT * FROM GameScore " +
"WHERE date = :1 AND level = :2 " +
"ORDER BY score ",
result = q.fetch(10)

III. Upload the application and Run it
a. testing it at localhost:
google_appengine/ todaysudoku/

b. upload the whole folder:
google_appengine/ update todaysudoku/

c. run it: We can now this application running on App Engine.


IV. Check Google App engine service:

a. Dashboard:
* up-to-the-minute overview of our system status with real-time, unedited data
* daily overall serving status for each of our APIs, including any outages or downtime
* detailed historical latency and error-rate graphs for the App Engine Datastore, Images, Mail, Memcache, Serving, URL Fetch, and Users components

b. Logs: it would store all error log information and it's very convenient for debugging.

c. Data Viewer: it is like php-mysql admin style. You can see the table data and make some query or delete data.