SAE python入门教程(2)-相关服务使用以及调试

上文中讲到了sae的初步使用以及sae python环境的相关资料,如果你不了解这些知识,你可以点击 http://skirt.sinaapp.com/?p=392 查看。那么从本文开始,我们将开始介绍如何在sae的python环境下使用sae提供的几大服务,其中包括文件存取服务storage,内存缓存memcache,网页抓取fetchurl,邮件服务等等。

操作storage

在sae使用storage服务,首先,我们需要在sae的管理面板创建一个storage的domain,如下图所示,我们点击创建一个domain,例如应用名test,那么创建完我们就可以用python脚本来管理它了。

在上一篇文章中,我们接触了hello wolrd,那么在本次教程中我们将继续延伸上次的脚本,我们创建一个操作storage的脚本storage.py,在其中将一个演示的操作封装为一个函数storage,脚本的内容如下:

# -*- coding: utf-8 -*-
import sae.storage
def storage():
        # 初始化一个Storage客户端。
        s = sae.storage.Client()
        # PUT object至某个domain下面,put操作返回object的public url。
        ob = sae.storage.Object('hello lazy')
        s.put('test', 'lazy', ob)
        # GET某个domain下的object
        ob = s.get('test', 'lazy')
        data = ob.data
        # 获取object的public url
        url = s.url('test', 'lazy')
        return url

注意,这里的文件编码一定要指定,# -*- coding: utf-8 -*- 这个很重要,不然会报错。我们使用的domain name是 test,可以参见以上为test的部分,操作的api请参考http://appstack.sinaapp.com/static/doc/release/testing/service.html#storage
那么在index.wsgi中调用这个脚本,调用的方式如下:

import sae
from storage import storage
def app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    result = storage()
    print(result)
    return ['Hello, world!']

application = sae.create_wsgi_app(app)

注意,此时我们通过from storage import storage 引入了我们刚刚封装的storage,在app函数中执行了一次storage函数,并将得到的结果print了出来,那么是不是刷新应用就能看到打出的信息呢?经验告诉我们这里的print并不能将信息打到屏幕上,而是作为sae python的调试信息存起来了。我们登陆sae的管理面板,找到对应应用的日志中心,选择分类为“debug”此时我们可以看到:

显然我们已经成功的上传并得到了上传文件的绝对地址。那么关于删除,修改属性等等大家可以自己按照相应的方式操作下~

操作memcache

想要使用 sae 的memcache 服务,首先需要在sae的管理面板上开始memcache 服务,具体开启的大小可以按照你的需要来。一般推荐不需要超过20M,我这里只是提供教学,只开启了1M,根据文档介绍,SAE Python使用 http://sendapatch.se/projects/pylibmc/ 作为mc客户端。 不同之处在于,创建Client时不用指定servers。也就是说是在调用的时候,sae已经帮我们创建了连接,具体代码如下:

# -*- coding: utf-8 -*-
import pylibmc
def memcachess():
        mc = pylibmc.Client()
        mc.set("sae", "sae is great")
        value = mc.get("sae")
        return value

我们在index.wsgi 中稍微修改下代码使用下我们封装的memcache操作函数,具体可以如下:

import sae
#from storage import storage
from memcache import memcachess
def app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    #result = storage()
    result = memcachess()
    print(result)
    return ["%s" % result]

application = sae.create_wsgi_app(app)

注意此时我们直接将result的结果打在了屏幕上了,更方便调试,那么此时屏幕上不应该显示hello world了,而应该显示 sae is great,我们访问下此时的应用:

哈,操作memcache成功了。

操作Mysql

mysql作为一种最常用的存取服务了,那么在sae python环境下怎么操作mysql呢。我们也采用上面的方式,用一个实例来操作创建在sae 上的数据。首先我们需要知道我们的mysql的连接主机,端口,等等信息,那么在sae python的环境下我们需要手工引入sae的相关常量信息:

import sae.const

其中以下就给出了数据库的连接信息:

sae.const.MYSQL_DB # 数据库名
sae.const.MYSQL_USER # 用户名
sae.const.MYSQL_PASS # 密码
sae.const.MYSQL_HOST # 主库域名(可读写)
sae.const.MYSQL_PORT # 端口,类型为,请根据框架要求自行转换为int
sae.const.MYSQL_HOST_S # 从库域名(只读)

SAE是支持MySQLdb的,那么在得到了数据库的连接信息之后我们就可以管理我们的数据库了,先到 SAE 的管理面板上激活你的python应用的mysql,在phpmyadmin中创建一个简单的表:

CREATE TABLE IF NOT EXISTS `hellosae` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `age` int(5) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

那么此时我们的mysql.py代码如下:

#!/usr/bin/python
import MySQLdb
import sae.const
MYSQL_DB = sae.const.MYSQL_DB
MYSQL_USER = sae.const.MYSQL_USER
MYSQL_PASS = sae.const.MYSQL_PASS
MYSQL_HOST_M = sae.const.MYSQL_HOST
MYSQL_HOST_S = sae.const.MYSQL_HOST_S
MYSQL_PORT = int(sae.const.MYSQL_PORT)

def mysql():
        connection = MySQLdb.connection(host=MYSQL_HOST_M,port=MYSQL_PORT,user=MYSQL_USER,passwd=MYSQL_PASS)
        connection.select_db(MYSQL_DB)
        connection.query("""select * from hellosae limit 2""")
        r = connection.store_result()
        result = r.fetch_row()
        return result

这其中有几个值得注意的问题,第一个就是mysql的端口问题,在MySQLdb的连接参数中,port必须是int型的,而sae返回的常量信息中port是字符串类型,所以需要进行强制类型转换。
我们在index.wsgi中修改下代码使用我们刚刚封装的mysql函数,代码如下:

import sae
#from storage import storage
#from memcache import memcachess
from mysql import mysql
def app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    #result = storage()
    result = mysql()
    #print(result)
    return ["%s" % result]

application = sae.create_wsgi_app(app)

那么此时我们再刷新我们的应用,可以看到输出是:

其中我在数据库插入了两条数据,如下:,

可以发现,此时我们已经成功的操作了Mysql,那么关于更多的 insert,update,replace,delete等操作请参考MySQLdb的官方文档:http://mysql-python.sourceforge.net/MySQLdb.html#mysqldb

发送Mail

本次最后介绍一个典型的服务,SAE 的mail 服务。关于mail服务的详细介绍请参考 http://appstack.sinaapp.com/static/doc/release/testing/service.html#mail 在这里我用一个实际的例子来演示邮件的发送。我们封装一个mail发送的函数,具体的代码如下:

# -*- coding: utf-8 -*-
from sae.mail import send_mail
def  send_mail_lazy():
        send_mail("webmaster@changes.com.cn", "Sae python send mail test", "Hello SAE python!",("smtp.sina.com.cn", 25, "oozhuming@sina.com", "你的密码", False))

此时小小的修改下index.wsgi使用mail

import sae
#from storage import storage
#from memcache import memcachess
#from mysql import mysql
from mail import send_mail_lazy
def app(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    #result = storage()
    #result = mysql()
    result = send_mail_lazy()
    #print(result)
    return ["%s" % result]

application = sae.create_wsgi_app(app)

此时访问下应用 可以发现输出是一个None,原因是sae的mail发送是异步,所以没有返回值,要看邮件的调试信息可以到sae的管理面板中选择日志中心,选择mail,如下:

可以看到一封发送失败的邮件,刚才执行的脚本邮件已经发送成功了,

本次教程所有代码打包下载:

http://quixote-test.stor.sinaapp.com/sae_python_demo.zip

  1. 你好楼主!你的教程对我很有帮助,但是我发现在SAE官网上面发布的利用python操控的storage的手册里面,有的东西并没有写,例如你用到的sae.storage.Client()以及sae.storage.Object(‘hello lazy’)这些类名。请问你是如何知道这些的?谢谢!我的邮箱409498637@qq.com,希望有幸能够与你通信!