Python urllib2 HTTPPasswordMgrWithDefaultRealm';丢失';5次请求后输入密码

Python urllib2 HTTPPasswordMgrWithDefaultRealm';丢失';5次请求后输入密码,python,urllib2,basic-authentication,Python,Urllib2,Basic Authentication,在向发送电子邮件时,我遇到了一个我无法解决的奇怪Python问题:创建的PasswordMgr在尝试4-5次后似乎丢失了密码,然后我收到401身份验证错误 相同的API密钥在以后运行相同的代码时会起作用,因此我100%确定它是有效的,如果我重构代码,在Email.send_Email()(见下文)中构建一个新的HTTPPasswordMgrWithDefaultRealm和opener,整个过程都会很好,但我觉得这不是一个好办法 我正在创建开场白,它是HTTPPasswordMgrWithDef

在向发送电子邮件时,我遇到了一个我无法解决的奇怪Python问题:创建的PasswordMgr在尝试4-5次后似乎丢失了密码,然后我收到401身份验证错误

相同的API密钥在以后运行相同的代码时会起作用,因此我100%确定它是有效的,如果我重构代码,在
Email.send_Email()
(见下文)中构建一个新的
HTTPPasswordMgrWithDefaultRealm
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
然后将此
开场白
传递给为每封电子邮件创建的
电子邮件

class Email(object):
    def __init__(self, details, opener):
        self.details = details
        self.opener  = opener
。。。然后在同一类的send方法中使用,将电子邮件发送到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次提交。。。然后我开始从邮枪那里得到401错误。我确信这不是来自MailGun的节流,也不是我传递的参数的问题,相同的代码最初是有效的,如果脚本重新运行,那么稍后会有效

是否还会发生任何其他可能影响由
urllib2.build\u opener
创建的opener的事情

这是在CentOS 5机器上的Python2.6.8上实现的

其他信息: 通过更多的调试和15封电子邮件的测试,我可以看到服务器对每个请求的响应方式是相同的:使用
401
请求身份验证。对于发送到API的前6封电子邮件,随后会“重新提交”调用
401
的第一个请求,该请求会被
200
接受,我会收到该电子邮件

但是,在这6次请求之后,
urllib2
在请求时停止向服务器发送身份验证详细信息-它只注册
401
,而不向API重新提交POST数据。

好的,使用以下方法“解决”:


考虑使用而不是<代码> URLLIB2 < /代码>?是的,已经考虑过了,但是我有99%个用标准的LIBS来完成,并且如果可能的话,希望避免安装其他的东西……你能尝试用一个工具来控制你实际发送的东西吗?“我认为我们必须首先辨别问题出在哪里。”SergeBallesta向处理程序添加了一些调试,并用15封电子邮件进行了测试。我可以看到服务器以相同的方式响应401,并对所有尝试的身份验证进行挑战。对于前6封电子邮件,urllib然后用身份验证详细信息进行响应,重新发送POST数据和所有工作。但是,突然之间,urllib停止响应这些401挑战,并转到下一封要发送的电子邮件。@mstrudy尝试
请求
的好决定。很可能,你会记得使用
urllib2
的时候,在中年监狱里不得不一直咬一些非常不愉快的东西。祝你有一个愉快的(Pythonic)年龄。你是否正在使用旧的
请求的
2.x之前版本?当前版本使用
respone.json()
(一个方法,而不是一个属性)并更好地处理编码(将符合RFC的默认值更正为UTF-8和UTF编解码器自动检测)。@MartijnPieters是的,它的版本是
0.13.1
。。我们将看一看如何升级它。谢谢你!
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"]