Send me an email telling me if my geoprocessing task failed or was successful

1165
6
04-04-2022 02:23 PM
MelissaJohnson
Occasional Contributor II

I have a model that I have been using the Scheduled Task to run.  I am finding that it fails at times (sometimes my drive gets disconnected and the model doesn't know what to do, since Pro doesn't seem to use the UNC path in the model it causes a failure)sure, but I have no way of knowing unless I open it every day and look. 

I am trying to see if there is a way to get an email, or other kind of notification that it has run and either succeeded or failed to complete as it should.  Is there a way to do that using Python?

Thanks in advance,

Melissa

6 Replies
RhettZufelt
MVP Frequent Contributor

Though I'm not familiar scheduling Models with task scheduler, for python scripts, I use sendmail for that.

In my script, I have a Mailer() function

 

import smtplib
from email.mime.text import MIMEText

msgtext = 'default text for message'
subtext = 'default text for subject'

def Mailer():
     ############################################
     ##Variables to set for notification emails##
     ############################################
     server = smtplib.SMTP(MSERV)
     TO = [MTO]             # set to email you want results sent to
     FROM = MFROM         # set to email you want results sent FROM
     msg = MIMEText( msgtext )
     msg['Subject'] = subtext
     msg['From'] = FROM
     msg['To'] = ','.join(TO)
     server.sendmail(FROM, TO, msg.as_string())
     server.quit()

 

If there are any errors, the except: block modifies the msgtext and subtext to include error message stuff:

 

msgtext = '--ERROR----------ERROR----------ERROR----------ERROR--\nPYTHON ERRORS:\nTraceback Info:\n' + tbinfo + '\nError Info:\n' + str(sys.exc_type) + ': ' + str(sys.exc_value) + '\n'
subtext = 'Program Failed.'

 

 

Then, in my finally: block, I run

Mailer()

This way, I always get an email with default message UNLESS there was an error, then I get the error as well.

R_

MelissaJohnson
Occasional Contributor II

Okay thanks!  I will try to incorporate that and see if I can get it to work.

0 Kudos
HeathAnderson
Occasional Contributor II

Hi @RhettZufelt,

This is great.  Is there anyway you could show your whole script?

 

Cheers,

Heath

0 Kudos
RhettZufelt
MVP Frequent Contributor

Sure, at least the email reporting part.

Lines 7 &  8 set my default email message and subject.

If an exception occurs, the msgtext and subtext variables are overwritten to include error information in the except: block.

After the script is finished, the Mailer() def is run from the finally: block and sends the email with original message if no errors, or with modified message if exception thrown.

import arcpy, os, traceback, sys, smtplib
from email.mime.text import MIMEText

##########################################################
####      Def to eMail progress reports to user       ####
##########################################################
compname = os.getenv('COMPUTERNAME')
subtext = "   Report of " + os.path.basename((inspect.getfile(lambda:None))) + " From " + compname
msgtext = "   Message from " + os.path.basename((inspect.getfile(lambda:None))) + " running on " + compname + "\n"

def Mailer():
    ############################################
    ##Variables to set for notification emails##
    ############################################
    server = smtplib.SMTP(MSERV)
    TO = [MTO]             # set to email you want results sent to
    FROM = MFROM           # set to email you want results sent FROM
    msg = MIMEText( msgtext )
    msg['Subject'] = subtext
    msg['From'] = FROM
    msg['To'] = ','.join(TO)
    server.sendmail(FROM, TO, msg.as_string())
    server.quit()


def Work():
    ##   put working commands here

    #  This is where I put the working python    
    
try:
  if __name__ == "__main__":    # Funny statement to keep from running module on import.
                                # though, this module not designed to be imported.
    Work()   

except:
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    msgtext = '--ERROR----------ERROR----------ERROR----------ERROR--\nPYTHON ERRORS:\nTraceback Info:\n' + tbinfo + '\nError Info:\n' + str(sys.exc_type) + ': ' + str(sys.exc_value) + '\n'
    subtext = 'Program Failed.'

finally:
    #Do Stuff here at end of run
    Mailer()   #  Send the email 

 

R_

 

0 Kudos
HeathAnderson
Occasional Contributor II

Hi R_,

The script is working well.  Thank you.  The only thing is that the python error isn't coming through in the body of the email.  The script is only returning the following line.  Any thoughts?

msgtext = " Message from " + os.path.basename((inspect.getfile(lambda:None))) + " running on " + compname + "\n"

Cheers,

Heath

0 Kudos
RhettZufelt
MVP Frequent Contributor

Sorry, guess I stripped off one too many imports. Looks like I included some that aren't needed also.

Should just need to add inspect to the imports:

 

import os, sys, traceback, smtplib, inspect

 

However, that line is just trying to add the name of the script.py file that is running as all my scripts include this.  that way, I know what script fired it.

You can always customize the message to suit your needs.

R_

 

0 Kudos