robocorp / rpaframework

Collection of open-source libraries and tools for Robotic Process Automation (RPA), designed to be used with both Robot Framework and Python
https://www.rpaframework.org/
Apache License 2.0
1.17k stars 225 forks source link

RPA.Email.ImapSmtp Authorize fails with Python <locals>.<lambda>() error #1118

Closed mark-lambert closed 1 year ago

mark-lambert commented 1 year ago

I was trying to use the example oauth 2 code (https://github.com/robocorp/example-oauth-email/blob/master/tasks.robot): ${status} ${ret}= Run Keyword And Ignore Error RPA.Email.ImapSmtp.Authorize account=${username}

... password=${SECRETS}[password]

running this fails with this eror: Python .() takes 0 positional arguments but 1 was given

it does work for IMAP only as in ${status} ${ret}= Run Keyword And Ignore Error RPA.Email.ImapSmtp.Authorize IMAP account=${username}

... password=${SECRETS}[password]

The error is reproducible in rpaframework version 23.5.2 and above

IMAP is sufficient for my current use case, so I am reporting for the benefit of future users.

Here is the faulty code form line 398: if account and password: if is_oauth: self.smtpconn.auth( "XOAUTH2", lambda: base64.b64decode(password.encode()).decode() // needs an ignored arg ) else: self.smtp_conn.login(account, password)

Compare with the IMAP code: if is_oauth: self.imapconn.authenticate( "XOAUTH2", lambda : base64.b64decode(password.encode()) ) else: self.imap_conn.login(account, password) self.imap_conn.select("INBOX")

mikahanninen commented 1 year ago

Hi @mark-lambert . I was able to run the repository task Send Google Email successfully 🤔

Your inclusions of Run Keyword And Ignore Error keyword seem unnecessary...

Have you modified your conda.yaml versions or the code some other way ?

mark-lambert commented 1 year ago

Hi Mika, Thanks for looking into the issue. Given the code works for you, I am thinking there must be a relevant difference in the installations.

Answers to your points/questions: !. The "Run Keyword and ignore Error" was added by me in my robot for debugging purposes, I missed removing it when reporting the issue. Indeed, it is not necessary for the working code using IMAP protocol.

  1. I have not modified the RPA library code in any way. I installed the libraries using pip, because I am only using the RPA email library. However, I am using Python version: Python 3.11.5, which may be stricter on lambda invocations.

To avoid taking up more or your time, if you know the line of code in RPA.Email.ImapSmtp below is correct, please close the issue. self.smtpconn.auth( "XOAUTH2", lambda: base64.b64decode(password.encode()).decode() // needs an ignored arg )

cmin764 commented 1 year ago

Even if it looks like it should be aligned, the IMAP4_SSL.authenticate sends an object to the mechanism which is our lambda function accepting and ignoring one argument. While on the SMTP.auth side the lambda function doesn't receive any (thus there's no argument to ignore).

We have tested with good coverage the framework with versions up to Python 3.10, so for 3.11 maybe something changed in the standard libraries so that it sends now an argument that should be ignored there as well.


Would appreciate if you can post the full trace (after running the Task with a shell: entry-point like: python -m robot -d output -L TRACE --logtitle "Task log" --task "Send Google Email" tasks.robot) so we understand it better. Then a quick patch PR would be something like:

                    self.smtp_conn.auth(
                        "XOAUTH2", lambda *_: base64.b64decode(password.encode()).decode()
                    )

so we'd have something compatible for both Py 3.11 and lower versions, if that's the culprit indeed.

mark-lambert commented 1 year ago

Hi cmin764, Thanks for taking the time to check the code and propose a patch. Possibly, the problem may not be Py 3.11 related, but could be intermittent due to an unusal response from the google gmail servers. Or, probably some now lost programming error of mine.

Unfortunately, my apologies, after some hours, I cannot reproduce the problem, even after recovering the source code closest to that at the time of the most recent failure (Oct 20):

python -m robot -V ../config/ml.yaml -V ../config/dev2.yaml resources/imap_email.robot 2023-10-20 12:54:17,662 - RPA.core.certificates - INFO - Truststore not in use, HTTPS traffic validated against certifi package. (requires Python 3.10.12 and 'pip' 23.2.1 at minimum)

Imap Email :: Send an e-mail with Google or Microsoft (not included) in a m...

Read Google Email :: Read e-mail with GMail. Currently only App Pa... | FAIL | TypeError: ImapSmtp.authorize_smtp..() takes 0 positional arguments but 1 was given

Imap Email :: Send an e-mail with Google or Microsoft (not include... | FAIL | 1 task, 0 passed, 1 failed

After reading the SMTP doco https://docs.python.org/3/library/smtplib.html, the issue may have been dependent on the google SMTP server, as the auth doco says in part: SMTP.auth(mechanism, authobject, *, initial_response_ok=True) Issue an SMTP AUTH command for the specified authentication mechanism, and handle the challenge response via authobject. mechanism specifies which authentication mechanism is to be used ... authobject must be a callable object taking an optional single argument

And then: If the initial response check returns None, ..., authobject() will be called to process the server’s challenge response; the challenge argument it is passed will be a bytes. It should return ASCII str data that will be base64 encoded and sent to the server.

Sorry, I could not be of more help, particularly given your prompt response.

cmin764 commented 1 year ago

Will close this for now, please re-open if the issue re-appears with the supported Python interpreter range 3.8-3.10.