向 mailgun API 发送电子邮件时我遇到了一个我无法解决的奇怪的 Python 问题:urllib2.HTTPPasswordMgrWithDefaultRealm()
创建的 PasswordMgr似乎在尝试 4-5 次后丢失了密码,然后我收到 401 身份验证错误。
相同的 API key 稍后可用于相同代码的后续运行,因此我 100% 确定它是有效的,如果我重构代码以构建新的 HTTPPasswordMgrWithDefaultRealm
和 Email.send_email()
中的 opener
(见下文)用于每次向 API 提交,但这并不是一个好方法。
我正在创建 opener
,这里是 HTTPPasswordMgrWithDefaultRealm
:
class MailgunConnection(object):
def __init__(self, domain, api_key):
self.api_key = api_key
self.domain = domain ## https://api.mailgun.net
self.opener = self.mg_opener()
def mg_opener(self):
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, self.domain, 'api', self.api_key)
auth_handler = urllib2.HTTPBasicAuthHandler(passman)
return urllib2.build_opener(auth_handler)
一旦通过以下调用创建了 opener,它就不会再次创建或被代码修改:
opener = MailgunConnection(domain, api_key).opener
此opener
然后被传递给为每封电子邮件创建的Email
类
class Email(object):
def __init__(self, details, opener):
self.details = details
self.opener = opener
...然后在同一个类的发送方法中稍后用于将电子邮件发送到 MailGun 的 API:
def send_email(self):
data = urllib.urlencode(self.details)
## ... snips for brevity ...
try:
response = self.opener.open('https://api.mailgun.net/v2/my.example.com/messages', data)
而且它有效...对于 4 或 5 次提交...然后我开始从 MailGun 返回 401 错误。我确定它不是来自 MailGun 的节流,也不是我传递的参数的问题,相同的代码首先起作用,然后如果重新运行脚本,则稍后起作用。
是否还有其他事情会影响 urllib2.build_opener
创建的开启器?
这是在 CentOS 5 机器上的 Python 2.6.8。
附加信息:
通过更多的调试和 15 封电子邮件的测试,我可以看到服务器以相同的方式响应每个请求:使用 401
请求身份验证。对于发送到 API 的前 6 封电子邮件,随后会“重新提交”第一个调用 401
的请求,该请求被 200
接受,我收到电子邮件。
然而,在这 6 次请求之后,urllib2
在请求时停止向服务器发送身份验证详细信息 - 它只是注册 401
而不会重新提交 POST 数据到API。
最佳答案
好吧,通过使用 requests
“解决”了:
r = requests.post(conf.email_api_gateway,
auth=('api', conf.email_api_key),
data={'to': self.email_add,
'from': self.get_email_from(),
'subject': self.get_email_subject(),
'html': self.get_email_html(),
'text': self.get_email_text() })
## manually set UTF-8 so we can json the response
r.encoding = 'UTF-8'
if r.status_code == 200:
mail_id = r.json[u"id"]
关于python - 5 次请求后 urllib2 HTTPPasswordMgrWithDefaultRealm 'loses' 密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24665535/