如何编译使用boto访问S3的Python代码?
我正在尝试把一个简单的Python程序编译成一个可以分享的.exe文件,这个程序是用boto包上传文件到S3存储桶的。我对任何编译方法都持开放态度。目前我已经尝试过bbfreeze
和py2exe
这两种工具,但结果都是一样的。出问题的代码大致如下:
import boto
#...snip...
fname_base = os.path.basename(fname)
s3 = boto.connect_s3(aws_access_key_id=_aws_key, aws_secret_access_key=_aws_secret_key, is_secure=False);
bucket = s3.get_bucket(_bucket)
key = bucket.new_key(fname_base)
key.set_contents_from_filename(fname)
用这两种工具编译后运行,我得到的结果是:
Traceback (most recent call last):
File "s3stash.py", line 238, in <module>
sys.exit(main())
File "s3stash.py", line 225, in main
push_file_to_s3(f, options)
File "s3stash.py", line 160, in push_file_to_s3
_push_with_boto(fname)
File "s3stash.py", line 148, in _push_with_boto
s3 = boto.connect_s3(aws_access_key_id=_aws_key, aws_secret_access_key=_aws_secret_key, is_secure=False);
File "boto\__init__.pyo", line 104, in connect_s3
File "zipextimporter.pyo", line 82, in load_module
File "boto\s3\connection.pyo", line 27, in <module>
File "zipextimporter.pyo", line 82, in load_module
File "boto\utils.pyo", line 55, in <module>
File "email\__init__.pyo", line 79, in __getattr__
ImportError: No module named multipart
我在Windows XP SP3上使用的是ActiveState Python 2.6。boto包是通过以下方式安装的:
easy_installer --always-unzip boto
我使用了--always-unzip
这个选项,因为我在这里看到关于py2exe
处理解压的egg文件有问题。不幸的是,即使我用bb-freeze
来构建可执行文件,得到的错误也是一样的。
从py2exe
的输出中,接近结尾的地方有以下信息:
The following modules appear to be missing
['_scproxy', 'email.Encoders', 'email.MIMEBase', 'email.MIMEMultipart', 'email.MIMEText', 'email.Utils', 'simplejson']
这给了一些线索。我尝试了其他帖子中建议的方法,特别是当用py2exe
编译时推荐使用-i
选项,但可惜没有任何帮助。在那些问题中,用户自己明确地包含了email子模块。我没办法把那些解决方案适应到我的情况中,单单用-i
添加它们也没能阻止py2exe
警告我缺少模块,或者导致生成的exe因为缺少模块而失败。
有人能帮我把这个代码打包成可以分享的版本吗?
3 个回答
我成功用boto和py2exe创建了一个可用的exe文件。
接下来,把下面的代码加到你的script.py里:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
接下来遇到的问题是HTTPS连接,似乎py2exe在某种程度上“隐藏”了证书文件。解决这个问题的方法有两个:
1) 使用HTTP
或者
2) 不检查证书
1) 使用HTTP
conn = boto.connect_dynamodb(
aws_access_key_id = ' ',
aws_secret_access_key = ' ',
is_secure = False)
这里的“is_secure = False”非常重要。
2) 不检查证书
conn = boto.connect_dynamodb(
aws_access_key_id = ' ',
aws_secret_access_key = ' ',
is_secure = True,
validate_certs = False)
这里的“validate_certs = False”也非常重要。
如果有人找到解决证书验证错误的方法,请回复我!
我知道这个问题已经很久了,但我也遇到过同样的问题,并且在使用py2exe和py2app的时候解决了它。只需要在你的setup.py文件中使用'packages'选项,而不是'includes'选项:
extra = {}
mainscript = "foo/__main__.py"
if is_os_x():
extra["setup_requires"] =['py2app']
extra["app"] = [mainscript]
extra["options"] = { "py2app": {
"packages": ['email'],
}
}
elif is_windows():
extra["setup_requires"] =['py2exe']
extra['console'] = [mainscript]
extra['options'] = {'py2exe': {
# Includes that py2exe doesn't include automatically
'packages': ['email'],
}
}
setup(
# snip
** extra
)
希望这能帮到你。
我实际上让这个问题解决了。答案是放弃使用boto,而是改用poster库。我仍然使用boto来生成一个签名的策略和一些必要的表单字段,这些是通过poster来完成的,但真正执行POST请求的部分现在只用poster。因为只用poster,所以py2exe在为我创建一个可以重新分发的独立可执行文件时没有任何问题。