What would it take to do the following in a Python script? (script to be run weekly on a server as a Windows scheduled task)
The assumption being my IT department will be able to set up SMTP.
ArcGIS Pro 3.1. ArcGIS Notebook Server is not an option.
I’m inexperienced with Python. So any help would be appreciated.
If you want to write a script for this, start out with pseudo code. Write what you want it to do, logically, step-by-step. It will help when you go to fill in the code bits and will most likely be the beginning of your comments.
One way I'd attempt this is probably by using a search cursor to iterate through every file in the folder, checking the # of rows in your attribute table.
I would actually suggest storing the results of your search, and then sending all of the results in one email. That way, you don't potentially end up with 100 emails if you have 100 LYRX files that fit this criteria.
So that would probably mean you create a list/dictionary that stores the name of each file that you test that returns as TRUE for your query. Then you can create an email, dump the list into an email, and send it off. IF your dictionary is empty, then no email.
Roughly, I think your script could follow the below steps.
#import modules
#set variables
#search through folder & store files that meet criteria
For every file in folder:
count number of rows
if row > 0:
add name to list
#Create an email and dump list/dictionary of file names into the message body
Is list empty?
No email
Does list have entries?
create email
identify receivers
drop list into body
Hi.
To do the task that you describe, you need to create a pythonscript that finds all the lyrx files in the directory, then create a featurelayer and get the number of features of that layer. There are several options for getting the layerfiles, using the modules os, glob or pathlib (from Python 3.4). This example uses the glob-module
import glob
folder = r'C:\Maps\LayerFiles\*.lyrx' # your folder with lyrx
elements = glob.glob(folder) #get the files
Then you need to iterate each of the files, create a featurelayer and get the number of features:
for element in elements:
featurelayer = "FeatureLayer"
arcpy.MakeFeatureLayer_management(in_features=element, out_layer=featurelayer) # create featurelayer from element
c = arcpy.GetCount_management(featurelayer) # get count of features
arcpy.Delete_management(in_data=featurelayer) # delete featurelayer
For sending the e-mail, you need to use the smtp-library, and call the sendEmail method each time the count is greater than 0. You can see the use of the smtplib here:
import smtplib
def sendEmail(layername):
sender = 'from@fromdomain.com'
receivers = ['to@todomain.com']
message = """From: From Person <from@fromdomain.com>
To: To Person <to@todomain.com>
Subject: Issues found in {0}
Records where found in the {0} query. Please investigate""".format(layername)
try:
smtpObj = smtplib.SMTP('localhost')
smtpObj.sendmail(sender, receivers, message)
print "Successfully sent email"
except SMTPException:
print "Error: unable to send email"
Good luck 🙂
For my notes, the requirements in the original post are over-simplified -- just to keep things simple for a first attempt at the script. Ultimately, I think I'd need a table (CSV?) in the network folder that would store information like:
So eventually, the Python script would need to loop through the table and read the values.
I do something like that. Below is a simple code I use to read a list of features (unique identifier is used) from a CSV and then do something with them (in this case, it just creates a selection).
import csv
import os
import arcpy
workspace = '[FILE PATH]'
selList = "selection.csv"
#opens up my csv
csvRead = open(os.path.join(workspace, selList), 'r')
with csvRead as r:
# creates a list
csvList = []
reader = csv.reader(r, delimiter = ',')'
#reads the rows in the CSV from column A
#for every row in Col A, it adds the value to a list selecting only certain characters
for row in reader:
UPI = row[0]
clippedUPI = UPI[0:23]
csvList.append(clippedUPI)
#this part does something with my list of values, in this case adding it to #an existing selection
for x in csvList:
selection = '"Name" = ' + "'" + x + "'"
arcpy.SelectLayerByAttribute_management(r"Parcel Fabric\Parcels", "ADD_TO_SELECTION", selection)
print("Selection Completed")
del selList, csvRead
I keep a list of mine in an .ini file (fancy txt file really) as fc | email distro list since we have different people to email based on the dataset.
import arcpy
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
iniFile = 'editNotifications.ini'
fclist = [line.rstrip('\n') for line in open(iniFile)]
for l in fclist:
fc_con = fr'path to lyrx maybe\{l.split(" | ")[0]}'
if int(arcpy.GetCount_management(fc_con).getOutput(0)) > 0:
# Create the body of the message (a plain-text and an HTML version).
disclaim = "so they know its auto generated.\n"
# formatting lines
text = "\n\n" + f'{fc_con.split(".")[-1]} has {arcpy.GetCount_management(fc_con).getOutput(0)}'
# Create the root message and fill in the from, to, and subject headers
msg = MIMEMultipart('related')
msg['From'] = 'spoofer@mydomain.gov'
msg['To'] = ','.join([x.rstrip() for x in l.split(' | ')[1].split(', ')])
msg['Subject'] = f'{l.split(" | ")[0]} has edits'
msgText = MIMEText(str(disclaim + text), 'plain')
# Send the email
smtp = smtplib.SMTP('smtp.domain.gov')
smtp.send_message(msg, msg['From'], msg['To'])
smtp.quit()
else:
print('yuppers')