In order to support a very large number of map consumers, that don't ever edit anything or create data, I rely on AGOL to host Map (Hosted Feature Services), hook those back to Portal as "Items", and keep my ArcGIS Server Farm service instances low, only spawning what is needed to support editors. Through security controls, the map service that automatically comes with a feature services is un-discoverable. I don't want people hitting the map services and spawning more service instances. This is in effect a "Collaboration"for people that can't enable Collaboration on their Portal.
https://www.esri.com/arcgis-blog/products/api-python/analytics/updating-your-hosted-feature-services... has been pretty handy for the past few years, via a scheduled task, it updates (nightly) several hundred feature services by pulling data from SDE into a Pro Project and overwriting what's on AGOL. Unfortunately, it doesn't allow you to preserve "Allow Export to other formats" setting on AGOL.
Enter https://pro.arcgis.com/en/pro-app/arcpy/sharing/introduction-to-arcpy-sharing.htm, which I've finally rolled my sleeves up on and have converted all my python doo-hickeys to use https://pro.arcgis.com/en/pro-app/arcpy/sharing/featuresharingdraft-class.htm, https://pro.arcgis.com/en/pro-app/tool-reference/server/stage-service.htm, and https://pro.arcgis.com/en/pro-app/tool-reference/server/upload-service-definition.htm. Coincidentally there's a lot more options to control service parameters.
Disclaimer: I know nothing about python, so I'm sure there's all sorts of inefficiencies in here, but it works.
import arcpy
import sys, string, os, calendar, datetime, traceback,smtplib
from arcpy import env
from subprocess import call
# Mail Server Settings
service = "GRSM_SASQUATCH"
sd_filename = service + ".sd"
try:
d = datetime.datetime.now()
log = open("C:\\PYTHON_LOGS\LOG."+service+".txt","a")
log.write("----------------------------" + "\n")
log.write("----------------------------" + "\n")
log.write("Log: " + str(d) + "\n")
log.write("\n")
# Start process...
starttime = datetime.datetime.now()
log.write("Begin process:\n")
log.write(" Process started at " + str(starttime) + "\n")
log.write("\n")
# Mail Server Settings
SERVER = "1.2.34"
PORT = "25"
FROM = "sasquatch@big.foot.com"
MAILDOMAIN = '@big.foot.com'
# Data Steward getting the email. Needs to be their email address...without @big.foot.comat the end
userList=["yeti"]
# get a list of usernames from the list of named tuples returned from ListUsers
userNames = [u for u in userList]
# take the userNames list and make email addresses by appending the appropriate suffix.
emailList = [name + MAILDOMAIN for name in userNames]
TO = emailList
# Grab date for the email
DATE = d
# Sign in to portal
arcpy.SignInToPortal('https://www.arcgis.com', 'userid', 'password')
# Set output file names
outdir = r"C:\PRODUCTION\GRSM_SASQUATCH"
sddraft_filename = service + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
#Delete any left over SD files from failed previous run
try:
os.remove(sd_filename)
print("Successfully deleted ", sd_filename)
except:
print("Error while deleting file ", sd_filename, ", perhaps it doesn't exist")
try:
os.remove(sddraft_output_filename)
print("Successfully deleted ", sddraft_output_filename)
except:
print("Error while deleting file ", sddraft_output_filename, ", perhaps it doesn't exist")
# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\PRODUCTION\GRSM_SASQUATCH\GRSM_SASQUATCH.aprx")
m = aprx.listMaps("GRSM_SASQUATCH_LOCATIONS")[0]
# Create FeatureSharingDraft and set service properties
# https://pro.arcgis.com/en/pro-app/arcpy/sharing/featuresharingdraft-class.htm
sharing_draft = m.getWebLayerSharingDraft("HOSTING_SERVER", "FEATURE", service)
sharing_draft.summary = "Sasquatch Locations"
sharing_draft.tags = "Sasquatch, Fur, Hairy, Big Foot"
sharing_draft.description = "Hide and Seek Champion"
sharing_draft.credits = "Yeti"
sharing_draft.useLimitations = "This is not real"
#sharing_draft.portalFolder = "Front Country"
sharing_draft.overwriteExistingService = "true"
sharing_draft.allowExporting = "true"
# Create Service Definition Draft file
sharing_draft.exportToSDDraft(sddraft_output_filename)
# Stage Service
# https://pro.arcgis.com/en/pro-app/tool-reference/server/stage-service.htm
sd_output_filename = os.path.join(outdir, sd_filename)
arcpy.StageService_server(sddraft_output_filename, sd_output_filename)
# Share to portal
# https://pro.arcgis.com/en/pro-app/tool-reference/server/upload-service-definition.htm
print("Uploading Service Definition...")
arcpy.UploadServiceDefinition_server(sd_output_filename,
"My Hosted Services",
"",
"",
"EXISTING",
"existingFolder",
"",
"OVERRIDE_DEFINITION",
"SHARE_ONLINE",
"PUBLIC",
"SHARE_ORGANIZATION",
["GRSM","Great Smoky Mountains National Park Open Data"] )
# Clean up SD files
try:
os.remove(sd_filename)
print("Successfully deleted ", sd_filename)
except:
print("Error while deleting file ", sd_filename, ", perhaps it doesn't exist")
try:
os.remove(sddraft_output_filename)
print("Successfully deleted ", sddraft_output_filename)
except:
print("Error while deleting file ", sddraft_output_filename, ", perhaps it doesn't exist")
# Write nothing to log if success.
endtime = datetime.datetime.now()
log.write(" Completed successfully in "
+ str(endtime - starttime) + "\n")
log.write("\n")
log.close()
print('done')
except:
# Get the traceback object
tb = sys.exc_info()[2]
tbinfo = traceback.format_tb(tb)[0]
# Concatenate information together concerning
# the error into a message string
pymsg = "PYTHON ERRORS:\nTraceback info:\n" + tbinfo + "\nError Info:\n" + str(sys.exc_info()[1])
msgs = "ArcPy ERRORS:\n" + arcpy.GetMessages(2) + "\n"
# Return python error messages for use in
# script tool or Python Window
arcpy.AddError(pymsg)
arcpy.AddError(msgs)
# Print Python error messages for use in
# Python / Python Window
log.write("" + pymsg + "\n")
log.write("" + msgs + "")
log.close()
# Define email message if something went wrong
SUBJECT = "Notification of Un-Successful AGOL Update of "+service
MSG = "Did Not Update: {} - ID: {} at "+ str(DATE)+ "; " +pymsg + "; " + msgs
print (MSG)
print (emailList)
# Send an email notifying steward of successful archive
#MESSAGE = "\ From: %s To: %s Subject: %s %s" % (FROM, ", ".join(TO), SUBJECT, MSG)
MESSAGE = "Subject: %s\n\n%s" % (SUBJECT, MSG)
try:
try:
print("Connecting to Server...")
server = smtplib.SMTP(SERVER,PORT)
try:
print("Login...")
try:
print("Sending mail...")
server.sendmail(FROM, TO, MESSAGE)
except Exception as e:
print("Send Error Mail\n" + e.message)
except Exception as e:
print("Error Authentication Server: check the credentials \n" + e.message)
except Exception as e:
print("Error Connecting to Server : check the URL of the server and communications port ( 25 and ' the default ) \n" + e.message)
print("Quit.")
server.quit()
except Exception as e:
print (e.message)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.