Search code examples
pythongithub-actionsimaplib

imaplib.py: 'NoneType' object has no attribute 'replace'


I've set up a workflow on GitHub and when I run it, I'm getting the following error:

 1    Run python app.py
 2    python app.py
 3    shell: /usr/bin/bash -e {0}
 4    env:
 5      pythonLocation: /opt/hostedtoolcache/Python/3.9.6/x64
 6      LD_LIBRARY_PATH: /opt/hostedtoolcache/Python/3.9.6/x64/lib
 8  Traceback (most recent call last):
 9    File "/home/runner/work/Bot-Deschamps-Newsletter/Bot-Deschamps-Newsletter/app.py", line 9, in <module>
10      main()
11    File "/home/runner/work/Bot-Deschamps-Newsletter/Bot-Deschamps-Newsletter/app.py", line 5, in main
12      mail_connect()
13    File "/home/runner/work/Bot-Deschamps-Newsletter/Bot-Deschamps-Newsletter/read_email.py", line 13, in mail_connect
14      mailbox = MailBox(SMTP_SERVER).login(
15    File "/opt/hostedtoolcache/Python/3.9.6/x64/lib/python3.9/site-packages/imap_tools/mailbox.py", line 46, in login
16      login_result = self.box.login(username, password)
17    File "/opt/hostedtoolcache/Python/3.9.6/x64/lib/python3.9/imaplib.py", line 610, in login
18      typ, dat = self._simple_command('LOGIN', user, self._quote(password))
19    File "/opt/hostedtoolcache/Python/3.9.6/x64/lib/python3.9/imaplib.py", line 1222, in _quote
20      arg = arg.replace('\\', '\\\\')
21  AttributeError: 'NoneType' object has no attribute 'replace'
22  Error: Process completed with exit code 1.

This imaplib.py file isn't in my project, but I'm importing the imap-tools dependency and I don't know if it could be the cause. Is it possible that this has something to do with it? The only solution would be to look for some other dependency or is there an alternative?

EDIT 1:

Here is the file I run in the workflow:

#app.py
from read_email import mail_connect

def main():
    mail_connect()


if __name__ == '__main__':
    main()

Here in the workflow executed in GitHub Actions:

#main.yml
name: Python Script Workflow

on:
  - cron: "*/10 11-13 * * 1-5"
  
  workflow_dispatch:
    inputs:
      name:
        required: true
        default: 'Tweet'
  
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository content
        uses: actions/checkout@v2 # Checkout the repository content to github runner.

      - name: Setup Python Version
        uses: actions/setup-python@v2
        with:
          python-version: 3.9.6

      - name: Install Python dependencies
        uses: py-actions/py-dependency-install@v2
        with:
          path: "requirements.txt"

      - name: Execute Python script # Run the app.py
        run: python app.py

And this is the requirements.txt:

imap-tools==0.49.1
python-dotenv==0.19.0
tweepy==4.0.1

EDIT 2:

Here is the only file that uses imap_toolts:

#read_email.py
from imap_tools import MailBox, MailMessageFlags, A
from os import getenv
from dotenv import load_dotenv
from post_tweet import post_tweet


def mail_connect():
    load_dotenv()
    FROM_EMAIL = getenv('FROM_EMAIL')
    FROM_PWD = getenv('FROM_PWD')
    SMTP_SERVER = "imap.gmail.com"

    mailbox = MailBox(SMTP_SERVER).login(
        FROM_EMAIL, FROM_PWD, initial_folder='INBOX')

    read_email(mailbox)


def read_email(mailbox):
    posts = []
    for msg in mailbox.fetch():
        posts = msg.text.replace('*', '').split('\r\n\r\n')
        posts = posts[2:-3]
        mark_as_read(mailbox)
        archive_message(mailbox, msg.uid)
    post_tweet(posts)


def mark_as_read(mailbox):
    flags = (MailMessageFlags.ANSWERED, MailMessageFlags.FLAGGED)
    mailbox.flag(mailbox.fetch(A(seen=False)), flags, True)
    mailbox.flag(mailbox.fetch("SENTON 01-Jan-2021"),
                 MailMessageFlags.SEEN, False)


def archive_message(mailbox, msg_uid):
    move_to = 'Tweeted'
    mailbox.move(msg_uid, move_to)


Solution

  • The issue is that the environment variables for your email and password are not set in the GitHub workflow environment. Modify the YAML for your workflow as follows:

    environment:
      name: production
    
      - name: Execute Python script # Run the app.py
        env:
          FROM_PWD: ${{secrets.FROM_PWD}}
          FROM_EMAIL: ${{secrets.FROM_EMAIL}}
    
        run: python app.py
    

    Modify if necessary based on how you named the secrets when you created them in GitHub.