问题
I'm trying to enable Gmail IMAP access from my web application. Right now, users can grant access to the web application, successfully retrieving and storing the user's token and secret. But, when I try to authenticate the IMAP connection for retrieving emails, it gives the following error:
TypeError: authenticate() takes exactly 3 arguments (4 given)
Here is the code (very simple):
import oauth2 as oauth
import imaplib
consumer = oauth.Consumer('token','secret')
token = oauth.Token('token','secret')
url = "https://mail.google.com/mail/b/username@gmail.com/imap/"
conn = imaplib.IMAP4_SSL('imap.googlemail.com')
conn.debug = 4
conn.authenticate(url,consumer,token)
I tried backing out a little bit to avoid the actual authenticate
function, but to no avail:
imaplib.IMAP4_SSL.authenticate(conn,'XOAUTH',lambda x: oauth.build_xoauth_string(url,consumer,token))
This gives me similar output:
29:03.17 > CMIK6 AUTHENTICATE XOAUTH
29:03.27 < CMIK5 BAD Too many arguments provided s68if10067716yhm.26
29:03.27 BAD response: Too many arguments provided s68if10067716yhm.26
I'm not sure what the problem could be. Why would the authenticate
function think there were 4 arguments? Could the oauth strings be interpreted as multiple strings, i.e., not escaped properly? They have slashes, underscores, plus signs, but no commas.
Any other ideas?
回答1:
When using oauth2 for IMAP, you need to use it in conjunction with oauth2.clients.imap
, so:
import oauth2 as oauth
import oauth2.clients.imap as imaplib
# the rest of your code as it was
You can see an example towards the bottom of this page: https://github.com/simplegeo/python-oauth2
回答2:
The authenticate method only takes 2 arguments (3 when you include self
). This article explains how it works (the docs are not very helpful).
Your second attempt looks promising if you just provide the 2 args:
conn.authenticate('XOAUTH',lambda x: oauth.build_xoauth_string(url,consumer,token))
Hope that helps.
UPDATE - IGNORE THE ABOVE
Ignore all that, I think I know what the problem is. It looks like you are taking your example from the python-oauth2 package. The example they give does not use Python's standard library imaplib
but its own implementation.
You need to use python-oauth2 imap client:
import oauth2.clients.imap as imaplib
Here's the relevant section from thier example - which indeed requires 3 arguments as in your example:
# This is the only thing in the API for impaplib.IMAP4_SSL that has
# changed. You now authenticate with the URL, consumer, and token.
conn.authenticate(url, consumer, token)
来源:https://stackoverflow.com/questions/7963820/gmail-imap-authentication-imaplib-authenticate-takes-exactly-3-args-4-given