中文版Google App Engine入门指南
本指南将介绍如何开发以及展示一个简单的 Google App Engine 项目。这个示例项目 - 一个用户留言簿 - 将会向你展示如何使用 Google App Engine 的多项服务,包括数据库服务和谷歌帐户服务。 Google App Engine 入门指南包括以下几个部分 : · 介绍 · 编程环境 · Hello, World! · 使用 webapp 框架 · 使用 Google 帐户服务 · 用 webapp 处理表单 · 使用数据库存储 · 使用模板 · 使用静态文件 · 上传你的程序
|
|
介绍 | 中文版 Google App Engine 入门指南
欢迎来到 Google App Engine !创建一个 App Engine 应用程序很简单的,只需要几分钟的时间。而且是免费的,只要你上传你的程序,你的网站就可以和用户见面了,不需要任何付款和投入。 在 Google App Engine 入门指南 中,你将会创建一个用户留言簿,它可以让用户在公共的留言板上发表留言。用户可以匿名留言,也可以使用他们的 Google 帐户留言。 这个留言簿程序将会向你展示如何使用 App Engine 的数据库存储,如何将一个 App Engine 和谷歌帐户进行整合,以及如何使用一个简单的 Python 网站框架(在 App Engine 中叫做 webap )。这个小程序还将会展示如何使用 Django 模板引擎。
|
编程环境 | 中文版 Google App Engine 入门指南
你要通过 App Engine 的 software development kit (SDK) 来开发,上传你的 Google App Engine 程序。 这个 SDK 里包括了一个网站服务器( web server )程序,用来模拟 App Engine 的环境,包括一个本地版的数据库, Google 帐户,以及获取远程地址 (URLs) 和从你的本地计算机发送邮件这一些列 App Engine 的 API 。本 SDK 需要运行在 Python 2.5 上, Python 2.5 的各个版本支持 Windows , Mac OS X 和 Linux 。 如果需要,可以从 Python 的 官方网站 下载适合你的操作系统的 Python 2.5 并安装在你的电脑上。 Mac OS X 10.5 Leopard 用户的电脑上默认已经安装好了 Python 2.5 。 下载 App Engine SDK ,然后按照下载页面上的指示将 SDK 安装在你的计算机上。 在本入门指南中,你将会用到 SDK 中的两个命令 : · dev_appserver.py , 开发版网站服务器 · appcfg.py , 用来上传你的程序到 App Engine 网站 对于 Windows 用户: App Engine SDK 的 Windows 安装程序会将这些命令添加到命令 path 里,在安装之后,你可以直接在命令行中使用这些命令。 对于 Mac 用户: Google App Engine Launcher 会将这些命令包含在程序当中,你可以将这些命令添加到命令 path 通过选择 "GoogleAppEngineLauncher" 菜单里的 “ Mak Symlinks... ” 。或者,你可以直接用 Launcher 来运行开发服务器以及展示你的网页程序。 如果你使用的是 Zip 存档版的 SDK,, 你将在 google_appengine 目录中找到相应的 python 程序。
|
Hello, World!| 中文版 Google App Engine 入门指南
Google App Engine 使用 CGI 标准来和网站服务器进行交互。当服务器接收到来自你的应用程序的一个请求时,它会运行程序,根据环境变量里的请求变量以及标准的输入流(对于 POST 的数据)。对于响应, CGI 会使用标准的输出流来输出,包括 HTTP header 和内容。 让我们首先做一个小程序以显示一则很短的信息。 创建一个简单的 Request Handler 创建一个文件夹名字叫 helloworld . 。所有的这个程序的文件都放在这个目录下面。 在 helloworld 文件夹里,创建一个名字叫 helloworld.py , 的文件,然后在里面输入: print 'Content-Type: text/plain' print '' print 'Hello, world!' 这段 Python 脚本代码将会对每一个 WEB 请求响应一段 HTTP header (用来描述内容),一个空行,以及一则信息 Hello, world! 。 创建配置文件 每个 App Engine 程序 都有一个配置文件叫做 app.yaml 。这个文件用来告诉服务器哪一段 URLs 用哪一个 handler 代码来处理。 在 helloworld 文件夹里,创建一个名叫 app.yaml 的文件,内容如下: application: helloworld version: 1 runtime: python api_version: 1 handlers: - url: /.* script: helloworld.py
从上到下,这个配置文件讲了如下几个关于应用程序的内容: · 这个应用程序的 ID 是 helloworld 。当你在最后一步中上传你的程序时,你得选择一个唯一的 ID ,然后代替掉这个 helloworld 。在调试开发阶段,这个 ID 可以是任何值。现在,我们把它设成 helloworld 。 · 这个程序代码的版本号是 1 ,如果你上传了新的版本的程序, App Engine 会保留以前的版本,通过管理控制台,你可以将你的 App Engine 程序恢复到以前的版本。 · 这段代码是在 python 运行时环境下运行的,版本号是 1. 其他的 runtime 环境和语言可能会在将来得到支持。 · 每个符合正则表达式 /.* ( 即所有 URLs) 都将用 helloworld.py 这段代码进行处理。 The syntax of this file is YAML . For a complete list of configuration options, see the app.yaml reference . 这个文件的语法是 YAML . 。关于完整的配置选项,参见 the app.yaml reference 。 调试程序 有了处理脚本代码和用来映射 URL 的配置文件之后,这个程序就完整了。你现在可以使用 App Engine SDK 内置的服务器测试你的程序了。 用下面的命令来启动 web 服务器,将 helloworld 的文件夹地址添加到命令后面: google_appengine/dev_appserver.py helloworld/
这个 web 服务器现在就开始运行了,监听端口为 8080. 使用下面的地址就可以在浏览器中调试你的程序了: · http://localhost:8080/ 想要获取更多关于运行开发 web 服务器的信息,比如如何改变监听端口,参见 the Dev Web Server reference ,或者在命令后面添加 --help 。 继续开发 你可以在服务器运行的时候继续开发你的程序, web 服务器会查看你的源文件的改变,并在需要的时候重新加载。 试试看:让 web 服务器保持运行,然后编辑 helloworld.py 里的文件内容,将 Hello, world! 改成其他的内容,然后重新访问 http://localhost:8080/ ,你会看到页面发生了改变 ~ 想要关闭 web 服务器,只要在 terminal 窗口激活的情况下,按 Control-C (或者对于你的控制台来说正确的打断命令)。 你可以在本使用指南的下面的部分中一直保持 web 服务器运行,如果你需要关闭它,下次你仍可以使用上面的代码来将 web 服务器重新开启。
|
使用 webapp 框架 | 中文版 Google App Engine 入门指南
CGI 标准是很简单的,但是要把所有的代码一一写出来还是很繁重的。 WEB app 框架帮你解决了这些具体问题,这样你就可以将你的精力集中在你的程序的功能上了。 Google App Engine 支持所有用 Python 写的关于 CGI 的网站框架(包括使用 CGI adaptor 的 WSGI -compliant 框架),包括 Django , CherryPy , Pylons , 以及 web.py . 。你只需要吧这个框架的代码复制到你的程序目录下就可以使用这个框架了。 App Engine 包括了一个很简单的 web 应用框架,叫做 webapp 。这个 webapp 框架已经在 App Engine 开发环境和 SDK 中安装好了,所以你不需要添加任何代码到你的程序中去,就可以使用这个框架了。在下面的教程中我们将使用 webapp 框架。 Hello, webapp! 一个 webapp 程序包含三个部分 : · 一个或多个 RequestHandler 类用来处理请求和产生响应。 · 一个 WSGIApplication 实例用来根据发送请求的 URL 对应到相应的类 · 一个主程序用来运行 WSGIApplication (使用 CGI adaptor ) 下面让我们来把我们的欢迎辞改写成一个 webapp 程序 . 编辑 helloworld/helloworld.py 文件,替换为下面的代码 : from google . appengine . ext import webapp from google . appengine . ext . webapp . util import run_wsgi_app 在你的浏览器中重新加载 http://localhost:8080/ ,你将会看到改变。 ( 如果你关闭了 web server ,那么可以重新打开,方法详见 "Hello, World!" .) webapp 做了些什么呢? 这个 webapp 模块是在 google.appengine.ext 包里面的。这个模块由 SDK 提供,在发布版的运行环境中也会包括。 上面这段代码定义了一个 request handler , MainPage ,映射到根目录 URL(/) 。当 webapp 接收到一个来自 URL/ 的 HTTP GET 请求后,它就会初始化 MainPage 类,然后调用这个实例的 get 方法。在这个方法里面,关于请求的信息可以通过 self.request 来获得。通常,这个方法都会设置 self.response 的属性以进行响应,然后退出方法。 webapp 将会根据 MainPage 实例的生命期最后的状态发送出响应。 应用程序本身由一个 webapp.WSGIApplication 实例所代表。 参数 debug=true 将会传递给生产函数,告诉 webapp 如果在程序运行过程中遇到错误,输出堆栈调用的记录。对于产品版的程序,你可能会去掉这个参数。 函数 run_wsgi_app() 接收 WSGIApplication 实例 ( 或者其他 WSGI-compatible 程序对象 ) ,然后将这个程序在 App Engine's CGI environment 里运行。 run_wsgi_app() 和 Python 标准库里提供的 wsgiref 模块中的 WSGI-to-CGI adaptor ,但提供了一些额外的功能。比如,它可以自动检测程序是否是运行在调试环境,并且可以在调试环境中输出错误。 我们将会在下面的入门指南中使用很多 webapp 的功能,想要了解更多关于 webapp 的内容,访问: the webapp reference 。
|
使用 Google 帐户服务 | 中文版 Google App Engine 入门指南
Google App Engine 提供了很多基于 Google 框架下的有用的服务,可以通过 SDK 中提供的类库来调用这些服务。一个很重要的服务就是用户服务,它可以让你的应用程序和 Google 账户用户集成,有了这个用户服务,你的用户只需要拥有 Google 帐号就可以登录到你的网站了。 下面我们用用户类服务来个性化我们的欢迎辞: 使用 Users 类 编辑 helloworld/helloworld.py , 替换为以下代码 : from google . appengine . api import users from google . appengine . ext import webapp from google . appengine . ext . webapp . util import run_wsgi_app 重新加载你的网页,你的程序将会重定向到一个本地版的 Google 登录界面,输入你想要的用户名,那么你的应用程序将会看到这个基于你给的用户名所创建的一个虚拟的 User 类对象。 当你的应用程序运行在 App Engine 上之后,用户将会被重定向到 Google 账户登录页面,然后会返回到成功登陆前或者创建用户之前用户所在的页面。 Users 类的 API 让我们仔细来看看这些代码 : user = users . get_current_user () 如果用户已经登录了 , get_current_user() 将会返回一个 User 对象,否则,将会返回 None 。 if user : 如果用户已经登录了,将会根据用户的账户,输出一段含有用户昵称的欢迎辞。 else : 如果用户没有登录,则告诉 webapp 让它将页面重定向到 Google 账户登录页面。 这个重定向包含了用户所在的页面 URI ( self.request.uri ) 所以之后将会返回到成功登陆前或者创建用户之前用户所在的页面。 想了解更多关于 Users 类的 API ,访问 the Users reference 。
|
用 webapp 处理表单 | 中文版 Google App Engine 入门指南
如果你希望用户自己可以留言,那么你需要一种处理用户输入信息的办法。而 webapp 让数据处理变得很简单。 用 webapp 处理 Web 表单的数据 用下面的代码替换 helloworld/helloworld.py : import cgi 重新加载你的程序页面,你将会看到表单,试着写点东西提交吧。 这个版本的程序有两个 handler : MainPage , 映射到 URL / , 用来展示表单 . Guestbook , 映射到 URL /sign , 用来展示用户提交表单的内容。 Guestbook handler 有一个 post() 方法(而不是 get() 方法)。 这是因为用 MainPage 所展示的页面里用了 HTTP POST 方法 ( method="post" ) 来提交表单里的数据。如果你需要在一个类中同时使用这两个方法( post() get() ),只需要各自分别定义在一个类下面就可以了。 post() 方法里的代码可以从 self.request 中 获取表单数据,在将这些数据返回并展示给用户之前,它调用了 cgi.escape() 方法来去掉用户输入中的一些 HTML 代码标识符。 cgi 是标准 Python 类库中的一个模块,详见 the documentation for cgi 。 注意 : App Engine 编程环境包含了所有 Python 2.5 的标准类库。但是,不是所有的方法都被允许的。 App Engine 程序与性在一个受限制的环境中,这样 App Engine 可以安全地将这些程序规模化。比如,底层的一些对于操作系统,网络操作,以及一些文件系统的操作都是不允许的,如果试图调用这些函数,将引发错误。更多信息,请访问 The Python Runtime Environment 。
|
使用数据库存储 | 中文版 Google App Engine 入门指南
对于一个数据量大的网站应用来说数据存储是个很有技巧的的事情。用户可能在一个特定的时间发出了一个数据请求,但是下一个时间又发出了另外一个完全不同的数据请求。所有的 WEB 服务都需要协调这些相互影响的请求,并且这些请求可能来自世界的各个地方。 由于有了 Google App Engine ,你再也不需要为这些发愁了。 Google App Engine 架构将为提供分布式的数据处理,解决负载平衡的问题,并且提供了 API 来实现所有关于数据存储的问题。 数据存储完整实例 下面是一个最新版的 helloworld/helloworld.py 代码,用来存储用户的留言。下面的所有文字都是用来解释这段代码的。 import cgi 将上面的代码替换掉 helloworld/helloworld.py 原有的代码,然后重新加载 http://localhost:8080/ 试着发布一条留言,看看你的留言是否被正确地存储并且正常地显示了。 存储用户提交的留言 App Engine 包含了一个基于 Python 的数据存储模型 . 这个模型类似于 Django's data modelling API , 但是使用了 Google 自己的存储环境 . 对于上一章实现的留言程序 , 我们想要把用户提交的留言保存起来,每个留言都包含作者名称,消息内容,发布时间等等,并且按照留言的先后将其显示出来。 为了使用 data modeling API ,在代码顶部添加 google.appengine.ext.db 模块: from google . appengine . ext import db 下面的这段代码定义了一个用来存储用户留言的模块: class Greeting ( db . Model ): 这段代码定义了 Greeting 模型的三个属性: author 是一个 User 对象, content 是一个字符串对象, and date 是一个 datetime.datetime 对象。 其中一些属性包含了默认值 : 比如 db.StringProperty 类型中 multiline=True 表明该字符串中可以包含换行符 ; db.DateTimeProperty 类型中 auto_now_add=True 表明当 Greeting 对象创建的时候,将使用当前时间初始化这个属性。关于数据模型的属性的更多帮助,请查看 the Datastore reference 。 既然我们已经定义了一个数据对象模型,接下来,我们创建一个 Greeting 对象,并且把它保存起来。编辑 Guestbook handler : class Guestbook ( webapp . RequestHandler ): 这个新的 Guestbook handler 创建了一个新的 Greeting 对象,然后根据用户提交的数据设置 author 和 content 的属性值。 它并没有甚至 date 的值,所以 date 会自动设成当前时间,因为我们在模型建立的时候已经设置了。 最后一行, greeting.put() 将新创建的对象保存进数据库,如果 put() 进去的是从数据库中提取的对象, put() 会更新那条数据记录,而现在我们是新创建的一个对象,所以 put() 会添加一条新的记录到数据存储里。 使用 GQL 获取数据记录 App Engine datastore 使用了一套复杂的数据储存系统 . 但是它并不是一个标准的关系数据库,所以不能使用标准的 Sql 语句进行查询。作为一个替代, Google 准备了一套类 Sql 的查询语句,称之为 GQL.GQL 提供了和 SQL 基本类似的语法来读取数据。 下面是新版的 MainPage handler 代码,用来查询数据库中的所有留言。 class MainPage ( webapp . RequestHandler ): 查询语句出现在这一行: greetings = db . GqlQuery ( "SELECT * FROM Greeting ORDER BY date DESC LIMIT 10" ) 或者,你也可以在 Greeting 类里面调用 gql(...) 方法,那样就不必使用 SELECT * FROM Greeting 这样的查询语句了: greetings = Greeting . gql ( "ORDER BY date DESC LIMIT 10" ) 和 SQL 语句类似,关键字 ( 比如 SELECT ) 是大小写无视的,字段名是区分大小写的。 要注意的是, GQL 语句总是返回完整的对象,所以 GQL 查询语句不能指定要查询的字段名。也就是说,所有的 GQL 语句都是以 SELECT * FROM model 开头的。 一个 GQL 查询语句可以用 WHERE 指定查询条件,你可以指定一个或多个条件。 和 SQL 不同的是, GQL 查询不 能包含变量值: GQL 使用参数绑定查询中所有的变量 . 例如 , 获取当前登录用户的留言: if users . get_current_user (): 你也可以使用命名参数代替之: greetings = Greeting . gql ( "WHERE author = :author ORDER BY date DESC" , 另外 , Google datastore API 还提供了另外一种获取数据的方法 : : greetings = Greeting . all () 想了解 GQL 查询语法的更多内容 , 请查看 the Datastore reference 。 清空开发版服务器中的数据存储 为了方便你测试自己的应用, GAE 开发环境使用了一个临时文件来保存本地的数据,要清空本地开发环境的数据,可以使用如下的命令行: dev_appserver.py --clear_datastore helloworld/
|
使用模板 | 中文版 Google App Engine 入门指南
HTML 里面嵌入在编程代码里是非常杂乱的,所以 我们 最好使用一个独立的文件来专门处理 HTML 代码,以便于将界面显示和数据获取的过程相互独立出来。有很多使用 Python 实现的模板系统,比如 : EZT , Cheetah , ClearSilver , Quixote , Django 等等 . 你可以选择这里面的任意一个。 为了大家方便 , webapp 模块默认包含了 Django 的模板系统 .Django 模板是 Google App Engine 的一部分,所以你不需要单独进行绑定就可以直接使用。 使用 Django 模板 首先在 helloworld/helloworld.py 中引入 template 模块: import os from google . appengine . ext . webapp import template 重新编写 MainPage handler : class MainPage ( webapp . RequestHandler ): 最后 , 在 helloworld 的目录下面创建一个新文件 index.html , 内容如下 :
{% for greeting in greetings %} {% if greeting.author %} {{ greeting.author.nickname }} wrote: {% else %} An anonymous person wrote: {% endif %} {% endfor %}
刷新浏览器,然后查看网页上的变化。 template.render(path, template_values) 接受输入一个文件路径和一个 dictionary 类型的数据字典 , 并输出一段经过处理的文本。这个模板使用了 Django 模板的语法 . 在模板文件中可以直接使用引入的值,并且可以使用这些对象的属性。在许多实际例子里,你可以直接使用 GAE 数据模型,并访问他们的属性。 提示: App Engine 应用程序对所有上传的文件的访问权限都是只读的,所以对文件的写操作是被禁止的;当前工作路径是应用程序的根目录,所以 index.html 的路径可以简单写成 "index.html" 。 想要了解更多关于 Django 模板引擎的内容,参见 the Django 0.96 template documentation 。
|
使用静态文件 | 中文版 Google App Engine 入门指南 和其他的 web 发布环境不同, Google App Engine 不支持直接将应用目录下的文件直接输出的功能。也就是说,如果我们将模板文件取名为 index.html , 我们并不能直接通过 URL /index.html 来访问这个文件。但是现在有非常多的应用需要我们提供文件直接输出的功能,例如图片, CSS,JavaScript 等等,这些类型的文件都需要直接输出到客户端。 GAE 提供了这样的功能,你不需要编写自己的处理模块来进行额外的处理。 使用静态文件 编辑 helloworld/app.yaml 修改里面的代码: application: helloworld version: 1 runtime: python api_version: 1
handlers: - url: /stylesheets static_dir: stylesheets
- url: /.* script: helloworld.py
新加的 handlers 部分定义了两个 URL 处理模块,其中 /stylesheets 开头的所有 URL 都定义并转向了静态文件夹 stylesheets ,如果在这个文件夹中发现了请求的文件,就会直接把这个文件的内容返回给客户端;而其他请求都会由 helloworld.py 脚本进行处理。 默认情况下, App Engine 按照文件名后缀处理静态文件,如 .css 结尾的文件就会使用 MIME 类型 text/css 。 GAE 按照在 app.yaml 定义的顺序对 URL 进行处理。在这个例子里 /stylesheets 将先于 /.* 对路径进行处理。 想要了解更多在 app.yaml 中的选项,请查看 the app.yaml reference 。 下面,我们创建 helloworld/stylesheets 目录,并且在这个目录下创建一个新文件 main.css : body { font-family: Verdana, Helvetica, sans-serif; background-color: #DDDDDD; }
最后,编辑 helloworld/index.html 插入如下几行:
刷新并查看效果,新版本的程序使用了样式表。
|
上传你的程序 | 中文版 Google App Engine 入门指南
用户创建和管理 GAE 应用程序,都需要使用 GAE 控制台程序来进行。其中,用于上传的命令行工具叫做 appcfg.py 。 注意 : 到目前为止,还没有办法删除已经发布的应用。这个功能会在稍后提供。在现在的预览测试阶段,每个用户可以注册 3 个应用程序 ID, 如果你不想使用你自己的应用程序 ID, 你可以仅仅读一下这一章,到你真正想发布自己的应用的时候再尝试。 注册应用程序 访问 http://appengine.google.com/ ,使用你的 Google 帐号登录到 App Engine 管理平台。(如果你还没有 Google 帐号,请先 申请一个 ) 。 为了创建一个新的 GAE 应用,请点击按钮 "Create an Application" ,按照提示注册应用程序 ID, 应用程序 ID 的名字必须是唯一的。创建 ID 后,你就可以拥有一个 http://application-id .appspot.com/ 这样的 URL 地址来访问你的 WEB 应用了 . 当然,如果你拥有自己的域名的话,也可以将其绑定到你自己的应用。 修改 app.yaml , 吧 application: 的值设置为你刚刚申请的应用程序 ID 。 上传你的 Application 上传你的程序,使用下面的命令: appcfg.py update helloworld/
按照提示,输入您自己的 Google 用户名和密码。 现在你已经可以使用如下地址访问您刚刚上传的 WEB 应用了: http://application-id .appspot.com 恭喜你 ! 你已经完成了这个教程的学习了 . 想要了解关于 Google App Engine 的更多相关内容,您可以继续查看 the App Engine documentation 。
|