常见问题¶
BUG反馈以及问题求助¶
关于新浪云Python相关服务的问题可以在以下地方反馈和提问。
新浪云Python邮件列表 (推荐)
订阅邮件列表 发送邮件至: sae-python+subscribe@googlegroups.com
退订邮件列表 发送邮件至: sae-python+unsubscribe@googlegroups.com
发表主题 发送邮件至: sae-python@googlegroups.com
订阅和退订时发送空邮件即可。如果想修改订阅方式,可以登录Google论坛后在设置中进行更改。
关于Python编程的其它问题,推荐到 CPyUG邮件列表 寻求帮助。
如何调试¶
复杂程序建议您本地调试成功后,再上传运行。
新浪云 Python 版本为 2.7.3,本地调试时注意不要使用高于此版本的Python。
如果你使用内置的第三方库,本地调试时最好使用同样的版本。
对于50x页面,如果异常被web框架捕获,则需要打开web框架的调试开关,查看详细的异常信息。如果异常被Python Server捕获,Python Server会直接在浏览器中打印出异常。
注解
在header已经发出的情况下,异常在浏览器中可能显示不出来,请查看日志。
没有我要使用的包怎么办¶
对于纯python的package,参考 添加第三方依赖包
对于含有c extension的package,目前新浪云还无法直接支持,如果需要这些package,可以申请预装。
注解
很多package对package里的c extension都会提供一个python的fallback版本,这类package在sae上也可以 直接使用,只是速度上相对于使用c extension会稍慢一点。
如何使用新浪微博API¶
使用 weibopy
该模块已经内置,可以直接使用。 完整示例请参考: examples/weibo 。
使用 sinaweibopy (推荐)
新浪微博API OAuth 2 Python客户端
如何在Cron中使用微博API¶
因为现在weibo api需要提供调用者的ip(合法的公网ip),新浪云默认提供的是http请求的client的ip,但是对于Cron和Taskqueue,由于是新浪云的内部请求,无法获取公网ip。所以需要用户手工设置一个。设置方法如下:
import os
os.environ['REMOTE_ADDR'] = 调用者公网ip
请务必将这段代码放在请求处理代码执行的必经路径上。比如在Flask中::
@app.before_request
def before_request():
import os
os.environ['REMOTE_ADDR'] = 调用者公网ip
MySQL gone away问题¶
MySQL连接超时时间为30s,不是默认的8小时,所以你需要在代码中检查是否超时,是否需要重连。
对于使用sqlalchemy的用户,需要在请求处理结束时调用 db.session.close() ,关闭当前session,将mysql连接还给连接池,并且将连接池的连接recyle时间设的小一点(推荐为60s)。
MySQL InterfaceError: (-1, ‘error totally whack(xxx)’)¶
这个错误表示mysql返回的错误码是新浪云自定义的错误码,其中totally whack后面括号中的数字是具体的错误码。
你可以在 共享 MySQL 文档中查询到相关错误码具体代表的信息。
如何区分本地开发环境和线上环境¶
if 'SERVER_SOFTWARE' in os.environ:
# SAE
else:
# Local
如何使用virtualenv管理依赖关系¶
当你的应用依赖很多第三方包时,可以使用virtualenv来管理并导出这些依赖包,流程如下:
首先,创建一个全新的Python虚拟环境目录ENV,启动虚拟环境。
$ virtualenv --no-site-packages ENV
$ source ENV/bin/activate
(ENV)$
可以看到命令行提示符的前面多了一个(ENV)的前缀,现在我们已经在一个全新的虚拟环境中了。
使用pip安装应用所依赖的包并导出依赖关系到requirements.txt。
(ENV)$ pip install Flask Flask-Cache Flask-SQLAlchemy
(ENV)$ pip freeze > requirements.txt
编辑requirements.txt文件,删除一些新浪云内置的模块,eg. flask, jinja2, wtforms。
使用dev_server/bundle_local.py工具,将所有requirements.txt中列出的包导出到本地目录virtualenv.bundle目录中。如果文件比较多的话,推荐压缩后再上传。
(ENV)$ bundle_local.py -r requirements.txt
(ENV)$ cd virtualenv.bundle/
(ENV)$ zip -r ../virtualenv.bundle.zip .
将virutalenv.bundle目录或者virtualenv.bundle.zip拷贝到应用的目录下。
修改index.wsgi文件,在导入其它模块之前,将virtualenv.bundle目录或者virtualenv.bundle.zip添加到module的搜索路径中,示例代码如下:
import os
import sys
app_root = os.path.dirname(__file__)
# 两者取其一
sys.path.insert(0, os.path.join(app_root, 'virtualenv.bundle'))
sys.path.insert(0, os.path.join(app_root, 'virtualenv.bundle.zip'))
到此,所有的依赖包已经导出并加入到应用的目录里了。
更多virtualenv的使用可以参考其官方文档。 http://pypi.python.org/pypi/virtualenv
注解
- 请删除requirements.txt中的wsgiref==0.1.2这个依赖关系,否则可能导致 bundle_local.py导出依赖包失败。
- 有些包是not-zip-safe的,可能不工作,有待验证。 含有c扩展的package 不能工作。
Matplotlib使用常见问题¶
Matplotlib使用了numpy,所以需要在config.yaml文件里将numpy和matplotlib添加到libraries里(对应的版本请参看: 使用预装模块 )。否则会导致matplotlib import失败。
libraries:
- name: numpy
version: "1.6.1"
- name: matplotlib
version: "1.1.1"
新浪云环境不支持matplotlib的interative模式,所以无法使用 pyplot.show() 直接来显示图像,只能使用 pyplot.savefig() 将图像保存到一个输出流中(比如一个cStringIO.StringIO的实例中)。
如果想要在matplotlib中显示中文,可以使用以下任一方法。
方法一:
import os.path from matplotlib.font_manager import FontProperties zh_font = FontProperties(fname=os.path.abspath('wqy-microhei.ttf')) import matplotlib.pyplot as plt plt.title(u'中文', fontproperties=zh_font)方法二:
import os # 设置自定义字体文件所在目录路径,多条路径之间使用分号(:)隔开 os.environ['TTFPATH'] = os.getcwd() import matplotlib # 设置默认字体名 matplotlib.rcParams['font.family'] = 'WenQuanYi Micro Hei' import matplotlib.pyplot as plt plt.title(u'中文')
其中方法一适用于ttf和ttc字体,方法二适用于只适用于ttf字体
如果有 matplotlibrc 配置文件,请将该文件与index.wsgi放在同一个目录下(默认的当前路径)。
设置基于主机的访问控制¶
Python运行环境目前无法通过config.yaml来配置基于主机的访问控制,用户如果需要这个设置,可以通过wsgi middleware来完成。
def filter_middleware(app):
def _(environ, start_response):
remote_addr = environ.get('REMOTE_ADDR')
# 判断remote_addr是否在允许访问范围内
# ...
if ok:
return app(environ, start_response)
start_response('401 Unauthorized', [])
return ["<b>401 Unauthorized</b>",]
return _
# 给application加上访问控制的中间件
application = filter_middleware(application)