向mailgun API发送电子邮件时,我遇到了一个我无法解决的奇怪的Python问题:urllib2.HTTPPasswordMgrWithDefaultRealm()
创建的PasswordMgr似乎在4-5次尝试后丢失了密码,然后我得到401身份验证错误。
相同的API密钥稍后用于以后运行相同的代码,因此我100%确定它是有效的,如果我重构代码以构建新的HTTPPasswordMgrWithDefaultRealm
和{ {1}} opener
内的{1}}(见下文)每次提交给API,但这并不是一个好方法。
我在这里创建Email.send_email()
并且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 = MailgunConnection(domain, api_key).opener
传递给为每封电子邮件创建的opener
类
Email
...然后在同一个类的send方法中使用,将电子邮件发送到MailGun的API:
class Email(object):
def __init__(self, details, opener):
self.details = details
self.opener = opener
它有效......对于4或5个提交...然后我开始从MailGun收到401错误。我确信它不会受到MailGun的限制,也不会影响我传递的参数,首先是相同的代码,然后是重新运行的脚本。
是否还会发生其他可能影响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)
创建的揭幕战的事情?
这是在CentOS 5盒子上的Python 2.6.8上。
其他信息:
通过更多的调试和15封电子邮件的测试,我可以看到服务器以相同的方式响应每个请求:urllib2.build_opener
请求身份验证。对于发送到API的前6封电子邮件,随后会重新提交调用401
的第一个请求,该请求会被401
接受并收到电子邮件。
然而,在这6个请求之后,200
在请求时停止向服务器发送auth详细信息 - 它只是注册urllib2
并且不会将POST数据重新提交给API。
答案 0 :(得分:1)
好吧,使用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"]