大家好!我是Marsbug团队的Damien。今天起,我会在本blog陆续发表一系列关于Python, Django, Google App Engine以及SNS应用开发的文章。
SNS应用可以说是web2.0时代mashup概念的一个非常成功的例子。从Facebook F8平台开始,SNS应用经过1年的发展已经深入人心。而在F8开放一年之际,国内的SNS领域也开始了一场开放平台大战,这也是我们开发者一展身手的好机会。今天,让我先从开发校内应用谈起吧。
开发技术的选择
目前Marsbug已经在校内、Manyou、51.com上开发了多款应用。我们使用的技术,主要包括Python+Django+Google App Engine,以及RoR+Heroku。在服务器方面,我们选择的都是新兴的云计算服务,是因为它们非常适合我们团队的需要:从零成本起步,按需付费,即使访问量上去了,也不必过多操心性能问题。
那么,怎么使用Google App Engine开发校内应用呢?
首先,GAE目前只支持Python作为开发语言,所以我选择了Python+Django来开发应用。本质上来讲,SNS应用的开发和网站开发没有本质区别。最大的不同在于SNS应用的Mashup性质:需要调用SNS平台的API接口来完成一些交互功能。
校内平台官方提供的是Java API开发包,并没有Python开发包。为此,我在PyFacebook基础上为校内平台定制了PyXn开发包,提供和PyFacebook一致的使用方式,维持了良好的可扩展性和轻量封装的理念,也已经经过了我们多款应用的实战检验。PyXn的代码可以从Google Code上得到:http://pyxn.googlecode.com 请直接checkout svn最新版,目前没有提供打包下载。
Django+PyXn的使用
PyXn对校内API调用进行了轻量封装,对Django和GAE做了特别支持。所以,使用PyXn在Django+GAE上进行开发是一件很轻松的事。由于PyXn的GAE支持对开发者是透明的,本文就以Django+PyXn的组合作为例子。GAE的开发细节留待下一篇文章说明。
首先,建立一个新的Django site
django-admin.py startproject mysite
然后,建立一个app
django-admin.py startapp myapp
把PyXn文件包整个复制到django site根目录下面,和django app目录同级。也就是:
mysite>myapp>pyxnmanage.pysettings.pyurls.py
在settings.py里,配置好PyXn需要的参数
MIDDLEWARE_CLASSES = [ ... 'pyxn.djangoxn.XiaoneiMiddleware', ...]XIAONEI_API_KEY = 'api_key'XIAONEI_SECRET_KEY = 'api_secret'XIAONEI_APP_NAME = 'my_app'XIAONEI_CALLBACK_PATH = "/xn/" #相对于url根的callback_path
这样,就能开始利用PyXn进行校内应用开发了。注意到我们添加了PyXn提供的’pyxn.djangoxn.XiaoneiMiddleware’,这个Middleware的作用是再每个request中自动加入一个pyxn.Xiaonei的实例,调用校内API就是通过直接调用这个Xiaonei实例中定义的函数来做的。同时,djangoxn模块里还提供了require_add()这个decorator,对于对应于一个XNML页面的view函数,需要用require_add()来修饰,从而得到一个直接可用的xiaonei实例。看下面这个例子。
import pyxn.djangoxn as xnfrom django.utils import simplejson@xn.require_add()def foo(request): xn = request.xiaonei #make api calls now friends = xn.friends.getFriends() xn.profile.setXNML(profile='some xnml') xn.feed.publishTemplatizedAction(template_id='1', title_data=simplejson.dumps({'foo':'bar'}))
在上面这段代码中,@xn.require_add()这步decorator操作实际上做的事情是检查request里从校内服务器传过来的参数,如果必须的用户登录信息都存在,那么就自动建立一个完整的xiaonei实例;否则,自动重定向到app安装页面,要求用户安装后才能访问这个页面。
调用校内API的时候需要在POST数据里提供一些必须的app和用户数据,包括预定义的api_key, api_secret,以及从request里得到的session_key,uid。而xn.require_add()这步检查做的事情就是把这些必须的参数填入新建的Xiaonei实例,而通过xiaonei实例调用api的时候会自动把必须的参数封装整理到POST数据里。也就是说,只有一个定义了必须参数值的xiaonei实例才能成功调用api,而xn.require_add()对于需要调用api的view函数是必须的。
以上的例子适用于XNML页面对应的view函数,因为用于重定向到安装页面的方法实际上是返回<xn:redirect>给校内服务器。在开发校内应用的时候,还经常会需要用到iframe页面,比较多的情况是xnml页面上嵌入iframe页面。iframe页面对应的view函数就不能直接利用@require_add来修饰了,而是通过xiaonei.check_session()函数来显式的检查request参数,并自动构造一个xiaonei实例,并填入调用api必须的参数。实际上,xn.require_add()这个decorator也是通过check_session()函数来从构造完整的Xiaonei实例的。我们在iframe的情形下,只不过是不需要redirect这一步,而是直接check_session()就行了。
def iframe_view(request): xn = request.xiaonei xn.check_session(request) #make api calls now friends = xn.friends.getFriends()
你可能会问,那么这种情况下,用户没有安装就访问这个页面的时候怎么把用户重定向到安装地址呢?这就可以通过给包含着这个iframe的xnml页面对应的view加上xn.require_add()这个decorator就行了。(不推荐纯iframe形式的app)
小提示
所有校内API的调用,都是通过Xiaonei类的实例进行的。而调用格式完全可以参照校内api的定义来推测。比如,friends.getFriends()这个api,就是用xiaonei.friends.getFriends()。而api需要的参数,也按照api定义的类型来提供。
推荐大家略读一下pyxn.__init__.py的代码,从114行开始定义的METHODS dict就能方便的看出具体api调用函数的格式。例如这个定义:
'feed': { 'publishTemplatizedAction': [ ('template_id', int, []), ('title_data', json, ['optional']), ('body_data', json, ['optional']), ('resource_id', int, ['optional']), ], },
这就是定义了xiaonei.feed.publishTemplatizedAction这个api方法。其中,template_id参数是必填的,类型是int,其余都是可选参数,类型分别是json和int。具体调用例子请参考上文实例。
总结
好了,在Django环境下使用PyXn今天就介绍到这里。下次会详细谈一下我们是如何在Google App Engine上,运用Django+PyXn这套工具来开发应用的。