Python 无法通过本地Google App Engine沙箱中的https协议发布到主机
我想使用mandrilpythonlib与Mandrill的API服务器通信 我已经将相关的源代码添加到我的项目中。我还在app.yaml中启用了库ssl 然而,当我尝试使用一个Mandrill API时,遇到了一个“权限被拒绝”的异常 这是堆栈跟踪Python 无法通过本地Google App Engine沙箱中的https协议发布到主机,python,google-app-engine,python-2.7,mandrill,Python,Google App Engine,Python 2.7,Mandrill,我想使用mandrilpythonlib与Mandrill的API服务器通信 我已经将相关的源代码添加到我的项目中。我还在app.yaml中启用了库ssl 然而,当我尝试使用一个Mandrill API时,遇到了一个“权限被拒绝”的异常 这是堆栈跟踪 File "lib/mandrill/mandrill.py", line 1498, in send_template return self.master.call('messages/send-template', _params
File "lib/mandrill/mandrill.py", line 1498, in send_template
return self.master.call('messages/send-template', _params)
File "lib/mandrill/mandrill.py", line 159, in call
r = self.session.post('%s%s.json' % (ROOT, url), data=params, headers={'content-type': 'application/json', 'user-agent': 'Mandrill-Python/1.0.57'})
File "lib/requests/sessions.py", line 504, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "lib/requests/sessions.py", line 461, in request
resp = self.send(prep, **send_kwargs)
File "lib/requests/sessions.py", line 573, in send
r = adapter.send(request, **kwargs)
File "lib/requests/adapters.py", line 415, in send
raise ConnectionError(err, request=request)
ConnectionError: ('Connection aborted.', error(13, 'Permission denied'))
我已经使用Mandrill命令行实用程序仔细检查了API密钥问题,我确信这不是问题的根源
如果我打印出os.environ,我可以看到这个键值对:“HTTPS”:“off”
此环境变量是否与此问题有关?是什么导致了“权限被拒绝”问题?结果表明,请求库与GAE的本地实例不匹配。问题类似于
在这里,我引用katzlbt对上述问题的根本原因分析:
众所周知,请求的作者不支持谷歌
appengine,将来不会这样做。请求现在可以在现场工作了
环境仅适用于已启用计费的appengine应用程序,但不适用于
本地SDK,它使基于您的库实现解决方案成为可能
appengine上的噩梦,离线时基本不稳定。只有
上传到实时服务器工作
使用类似的技术,这是我的monkey修补代码:
import json
import time
import requests
class _Response(object):
def __init__(self, dict):
self.__dict__ = dict
def _monkeypatched_mandrill_call(self, url, params=None):
from google.appengine.api import urlfetch
from mandrill.mandrill import ROOT
if params is None: params = {}
params['key'] = self.apikey
params = json.dumps(params)
self.log('POST to %s%s.json: %s' % (ROOT, url, params))
start = time.time()
headers = {'content-type': 'application/json', 'user-agent': 'Mandrill-Python/1.0.57'}
uf_response = urlfetch.fetch('%s%s.json' % (ROOT, url), method='post', payload=params, headers=headers)
remote_addr = (None, None)
# construct a request-like response
r = _Response({
'status_code' : uf_response.status_code,
'reason' : None,
'text' : uf_response.content,
'headers' : uf_response.headers,
})
response_body = r.text
complete_time = time.time() - start
self.log('Received %s in %.2fms: %s' % (r.status_code, complete_time * 1000, r.text))
self.last_request = {'url': url, 'request_body': params, 'response_body': r.text, 'remote_addr': remote_addr, 'response': r, 'time': complete_time}
result = json.loads(response_body)
if r.status_code != requests.codes.ok:
raise self.cast_error(result)
return result
def monkey_patch_gae():
''' Call this function to patch mandrill when running a local GAE instance '''
from mandrill import mandrill
mandrill.Mandrill.call = _monkeypatched_mandrill_call
此修补程序适用于mandril api python版本7d041d5我不熟悉Mandrill,但它可能希望您拥有一个良好的SSL证书来启动到它的HTTPS连接?@AlexMartelli Hi,我一直觉得您能回答我的问题是一件非常荣幸的事。非常感谢你,新年快乐!我朝SSL证书的方向看了看,但这不是原因。我想我已经找到了一个解决方案,我会很快发布一个答案!