1

I have a small python project that runs on a raspberry pi. It monitors temperatures, checks and sends emails, and controls a PDU. It runs perfectly from the Thonny IDE included in raspbian. However when I run it from the command line, or ideally on startup, it fails in one specific section of code dealing with checking emails.

I installed the email module on the system using pip install. Then I realized this was standard in python so i uninstalled it.

This is the error code.

Traceback (most recent call last):
  File "/home/pi/Documents/Python Files/Temp_Monitor_Project/temp_controller.py", line 122, in <module>
    main()
  File "/home/pi/Documents/Python Files/Temp_Monitor_Project/temp_controller.py", line 104, in main
    check_email_com(state_and_monitoring)
  File "/home/pi/Documents/Python Files/Temp_Monitor_Project/temp_controller.py", line 16, in check_email_com
    command = check_email.check_for_commands()
  File "/home/pi/Documents/Python Files/Temp_Monitor_Project/check_email.py", line 43, in check_for_commands
    command = message.checkMail()
  File "/home/pi/Documents/Python Files/Temp_Monitor_Project/check_email.py", line 20, in checkMail
    email_msg = email.message_from_bytes(data[0][1])
AttributeError: 'module' object has no attribute 'message_from_bytes'

Here is the script it fails in.

import imaplib, struct, time, email, Send_Email

#global sender

class Mail():
    def __init__(self):
        self.user= 'email address'
        self.password= 'password'
        self.M = imaplib.IMAP4_SSL('imap.gmail.com', '993')
        try:
            self.M.login(self.user, self.password)
        except:
            print("mail login failed")

    def checkMail(self):
        self.M.select()
        self.unRead = self.M.search(None, '(SUBJECT "Temp Monitor Command" UnSeen)')
        if len(self.unRead[1][0].split()) > 0:
            status, data = self.M.fetch(self.unRead[1][0], '(RFC822)')
            email_msg = email.message_from_bytes(data[0][1])
            if email_msg.is_multipart():
                for part in email_msg.walk():       
                    if part.get_content_type() == "text/plain":
                        body = part.get_payload(decode=True) 
                        body = body.decode()

                    elif part.get_content_type() == "text/html":
                        continue
            #print(self.M.fetch(self.unRead[1][0], "(BODY[HEADER.FIELDS (FROM)])"))
            return body
        else:
            return -1
OsakaRhymes
  • 96
  • 1
  • 8
  • Did you name one of your own modules `email`? Why are you expecting `email` to have a `message_from_bytes` function? – user2357112 Oct 03 '17 at 21:58
  • 3
    When you run from the command line, which version of python are you using? The docs at https://docs.python.org/3/library/email.parser.html#email.message_from_bytes mention that the message_from_bytes function was introduced in 3.2. – Don Rowe Oct 03 '17 at 22:00
  • @DonRowe I am VERY new to python. I did not realize that the command line call determined the python version used i.e. python script.py could also be python3 script.py. I have just been running it as python script.py & so it would always run 2.x and exclude message_from_bytes. Thanks. – OsakaRhymes Oct 03 '17 at 22:03
  • @DonRowe: what the - that is a frustrating place for top-level module contents to be documented. – user2357112 Oct 03 '17 at 22:04

1 Answers1

0

I think the problem is nearby environment where you try to execute your code. Try to check installed modules in both cases. You can read here about How to list of used modules during execution. Also you should check which python instance used in both cases. To do this you can execute this

import sys 
print(sys.executable)
print(sys.version)