python - 5 次请求后 urllib2 HTTPPasswordMgrWithDefaultRealm 'loses' 密码

标签 python urllib2 basic-authentication

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

相同的 API key 稍后可用于相同代码的后续运行,因此我 100% 确定它是有效的,如果我重构代码以构建新的 HTTPPasswordMgrWithDefaultRealmEmail.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/

相关文章:

https - 在 URL 中传递的 HTTP 基本身份验证凭据和加密

javascript - 开放层 3 : Basic Authentication

python - 是否可以转义 Python 中的保留字?

python - 使用 gzip 编码分块下载大文件 (Python 3.4)

python - 使用 urllib2 下载网页导致乱码垃圾? (只是有时)

python - urllib2 发送 postdata

python循环迅速增加其内存使用量

python - 如果路由中有任何路径参数,我们如何在 falcon 中间件中获取路径参数?

python - 在 Pandas 中移动窗口以检查特定范围值

wcf - 未调用自定义 UserNamePasswordValidator