无法通过本地Google App Engine沙箱中的https协议发布到主机

时间:2015-01-06 05:47:27

标签: python google-app-engine python-2.7 mandrill

我想使用mandril python lib(https://bitbucket.org/mailchimp/mandrill-api-python)与Mandrill的API服务器(https://mandrillapp.com/)进行通信

我已将相关的源代码添加到我的项目中。我还在ssl

中启用了库app.yaml

但是我遇到了“拒绝权限”#39;我试图使用其中一个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 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'

此环境变量是否与此问题有关?导致“权限被拒绝”的原因是什么?问题

1 个答案:

答案 0 :(得分:0)

事实证明requests库与GAE的本地实例不兼容。问题类似于this issue

在这里,我引用上述票证中的katzlbt根本原因分析:

  

众所周知,“请求”的作者不支持谷歌   appengine,将来也不会这样做。请求现在在现场工作   环境(仅适用于启用结算的应用程序),但不适用于   本地SDK,它基于您的库实现解决方案a   关于appengine的噩梦,基本上离线不稳定。只要   上传到实时服务器。

使用类似的技术,这是我的猴子修补代码:

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

此修补程序适用于版本7d041d5的mandril-api-python