I am trying to create a phyton script to create a geoprocessing tool to Publish and overwrite web layers within ModelBuilder. I am referring to the instructions within this blog post:
https://www.esri.com/arcgis-blog/products/arcgis-pro/mapping/publish-and-overwrite-web-layers-in-modelbuilder/
The issue that I’m having is the script provided in the link above contains the input “map” and what I would like to select is an input “layer” in the content pane.
Jonah Lay has provided sample code within the comments of the blog post here: https://pro.arcgis.com/en/pro-app/latest/arcpy/sharing/featuresharingdraft-class.htm#GUID-8E27A3ED-A705-4ACF-8C7D-AA861327AD26
The issue is when I try to use that code I continue to receive errors. Is there someone that could help debug this issue? I have zero coding experience.
NameError: name 'layer' is not defined
You don't define what 'layer' is in your inputs to the tool
# --- Where is 'layer' ???? ---- if __name__ == '__main__': # ScriptTool parameters map = arcpy.GetParameter(0) service = arcpy.GetParameterAsText(1) summary = arcpy.GetParameterAsText(2) tags = arcpy.GetParameterAsText(3) description = arcpy.GetParameterAsText(4) overwriteService = arcpy.GetParameter(5) enableEditing = arcpy.GetParameter(6) enableSync = arcpy.GetParameter(7) enableWFS = arcpy.GetParameter(8) timezone = arcpy.GetParameterAsText(9) share_public = arcpy.GetParameterAsText(10) share_organization = arcpy.GetParameterAsText(11) share_groups = arcpy.GetParameterAsText(12) outdir = arcpy.GetParameterAsText(13) rest_endpoint = ScriptTool(layer, service, summary, tags, description, overwriteService, enableEditing, enableSync, enableWFS, timezone, share_public, share_organization, share_groups, outdir) arcpy.SetParameterAsText(1, rest_endpoint) arcpy.AddMessage(rest_endpoint)
Thanks @AlfredBaldenweck , you've identified I wasn't using the correct sample code. (I'm trying to overwrite a weblayer) I've attached the new code and fixed the code that wasn't in line. I've also attached my new error but I'm feeling the solution is around specifying the layers I want. I'm just not sure what line I need to add that code into?
import arcpy import os import xml.dom.minidom as DOM def ScriptTool(map, service, summary, tags, description, overwriteService, enableEditing, enableSync, enableWFS, timezone, share_public, share_organization, share_groups, outdir): """ScriptTool function docstring""" # Set output file names sddraft_filename = service + ".sddraft" sddraft_output_filename = os.path.join(outdir, sddraft_filename) # Reference layers to publish aprx = arcpy.mp.ArcGISProject("CURRENT") m = aprx.listlayers('CURRENT')[0] selected_layer = m.listLayers()[0] # Create FeatureSharingDraft and set service properties sharing_draft = m.getWebLayerSharingDraft("HOSTING_SERVER", "FEATURE", service) sharing_draft.summary = summary sharing_draft.tags = tags sharing_draft.description = description sharing_draft.credits = "My Credits" sharing_draft.useLimitations = "My Use Limitations" sharing_draft.overwriteExistingService = overwriteService # Create Service Definition Draft file sharing_draft.exportToSDDraft(sddraft_output_filename) outsddraft = sddraft_output_filename arcpy.AddMessage("Service definition draft created") # Modify capabilities if enableEditing or enableSync: ModifyCapabilities(sddraft_output_filename, enableEditing, enableSync) if enableWFS: EnableWFS(sddraft_output_filename) # Set time zone if(timezone != ""): property_set = [{ "key": "dateFieldsRespectsDayLightSavingTime", "value": "true" }, { "key": "dateFieldsTimezoneID", "value": timezone }] SetTimezone(sddraft_output_filename, property_set=property_set) # Create Service Definition file sd_filename = service + ".sd" sd_output_filename = os.path.join(outdir, sd_filename) arcpy.StageService_server(sddraft_output_filename, sd_output_filename) arcpy.AddMessage("Service definition created") # Upload to portal output = arcpy.UploadServiceDefinition_server(sd_output_filename, "My Hosted Services", in_override="OVERRIDE_DEFINITION", in_public=share_public, in_organization=share_organization, in_groups=share_groups) arcpy.AddMessage("Service published") return output[5] def ModifyCapabilities(sddraft_output_filename, enableEditing, enableSync): capabilities = "Query" if enableEditing: capabilities += ",Create,Delete,Update,Editing" if enableSync: capabilities += ",Sync" # Modify feature layer capabilities to enable Create and Sync doc = DOM.parse(sddraft_output_filename) typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames: if typeName.firstChild.data == "FeatureServer": extension = typeName.parentNode for extElement in extension.childNodes: if extElement.tagName == 'Definition': for propArray in extElement.childNodes: if propArray.tagName == 'Info': for propSet in propArray.childNodes: for prop in propSet.childNodes: for prop1 in prop.childNodes: if prop1.tagName == "Key": if prop1.firstChild.data == 'webCapabilities': if prop1.nextSibling.hasChildNodes(): prop1.nextSibling.firstChild.data = capabilities else: txt = doc.createTextNode(capabilities) prop1.nextSibling.appendChild(txt) # Write to the .sddraft file f = open(sddraft_output_filename, 'w') doc.writexml(f) f.close() arcpy.AddMessage("Capabilities updated") return def EnableWFS(sddraft_output_filename): doc = DOM.parse(sddraft_output_filename) typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames: # Get the TypeName to enable if typeName.firstChild.data == "EnableWFSServer": extension = typeName.parentNode for extElement in extension.childNodes: # Enable feature access if extElement.tagName == 'Enabled': extElement.firstChild.data = 'true' # Write to the .sddraft file f = open(sddraft_output_filename, 'w') doc.writexml(f) f.close() arcpy.AddMessage("WFS set") return def SetTimezone(sddraftPath, property_set): # Read the sddraft xml doc = DOM.parse(sddraftPath) # Find all elements named TypeName. This is where the server object extension # (SOE) names are defined. typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames: # Get the TypeName to enable if typeName.firstChild.data == "MapServer": extension = typeName.parentNode # prp = extension.childNodes.getElementsByTagNameNS('PropertyArray') for extElement in extension.childNodes: if extElement.tagName == 'Definition': for definition in extElement.childNodes: if definition.tagName == 'ConfigurationProperties': for config_prop in definition.childNodes: if config_prop.tagName == 'PropertyArray': for prop in property_set: prop_set = doc.createElement("PropertySetProperty") attr = doc.createAttribute("xsi:type") attr.value = "typens:PropertySetProperty" prop_set.setAttributeNode(attr) prop_key = doc.createElement("Key") txt = doc.createTextNode(prop["key"]) prop_key.appendChild(txt) prop_set.appendChild(prop_key) prop_value = doc.createElement("Value") attr = doc.createAttribute("xsi:type") attr.value = "xs:string" prop_value.setAttributeNode(attr) txt = doc.createTextNode(prop["value"]) prop_value.appendChild(txt) prop_set.appendChild(prop_value) config_prop.appendChild(prop_set) # Write to the .sddraft file f = open(sddraftPath, 'w') doc.writexml(f) f.close() arcpy.AddMessage("Timezone set") return if __name__ == '__main__': # ScriptTool parameters map = arcpy.GetParameter(0) service = arcpy.GetParameterAsText(1) summary = arcpy.GetParameterAsText(2) tags = arcpy.GetParameterAsText(3) description = arcpy.GetParameterAsText(4) overwriteService = arcpy.GetParameter(5) enableEditing = arcpy.GetParameter(6) enableSync = arcpy.GetParameter(7) enableWFS = arcpy.GetParameter(8) timezone = arcpy.GetParameterAsText(9) share_public = arcpy.GetParameterAsText(10) share_organization = arcpy.GetParameterAsText(11) share_groups = arcpy.GetParameterAsText(12) outdir = arcpy.GetParameterAsText(13) rest_endpoint = ScriptTool(map, service, summary, tags, description, overwriteService, enableEditing, enableSync, enableWFS, timezone, share_public, share_organization, share_groups, outdir) arcpy.SetParameterAsText(1, rest_endpoint) arcpy.AddMessage(rest_endpoint)
Error Message:
Publish Web Feature Layer=====================Parameters
Layer MODIS 15km Buffer Current DayWeb Layer Name DraftSummaryTagsDescriptionOverwrite Existing Web Layer trueEnable EditingEnable SyncEnable WFSTime zoneShare With Everyone PRIVATEShare With Organization SHARE_ORGANIZATIONShare With GroupsOutput Directory S:\GIS\Projects\GIS0000\GIS0014_PECL_Wildfire_Webmap\GIS0014_MODIS_HotSpot_Buffer\outputRest Endpoint=====================Messages
Start Time: Monday, June 12, 2023 4:09:11 PMTraceback (most recent call last):File "S:\GIS\Projects\GIS0000\GIS0014_PECL_Wildfire_Webmap\Python\overwriteweblay.py", line 175, in <module>rest_endpoint = ScriptTool(map, service, summary, tags, description, overwriteService, enableEditing, enableSync, enableWFS, timezone, share_public, share_organization, share_groups, outdir)File "S:\GIS\Projects\GIS0000\GIS0014_PECL_Wildfire_Webmap\Python\overwriteweblay.py", line 14, in ScriptToolm = aprx.listlayers('CURRENT')[0]AttributeError: 'ArcGISProject' object has no attribute 'listlayers'
Failed script Publish Web Feature Layer...Failed to execute (PublishWebFeatureLayer).Failed at Monday, June 12, 2023 4:09:13 PM (Elapsed Time: 2.00 seconds)
Oops, I published that before I should have.
Make sure when creating that draft that you specify the layer(s) you want.
sharing_draft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service, [selected_layer])
You should also make sure that that's actually the layer you want to use; right now you're just grabbing the top layer. If you specify by name, you should be able to grab exactly the right one.
selected_layer = m.listLayers("Grazing Allotments 2023")[0]
Also, you're specifying a Map Image. Is that the type of service you want?
That's an easy fix so far.
Basically that line (#13) is out of line with what's around it. Make it line up with lines 12 and 14 and that particular error will go away.
Python recognizes things like loops or parts of functions by the indentation.
def funct(): # Everything spaced here belongs to funct #This is a different thing def funct3(): # This belongs to funct3 exList = [1,2,3] for e in exList: # Everything in here belongs to this loop # Then when that's done, I can continue on with what I was doing
Depending on what you're writing in (example Notepad++), there should be a setting to show you indentation lines/ white spaces.
Hi AlfredBaldenweck,
This is the code I’m using:
import arcpy import os import xml.dom.minidom as DOM def ScriptTool(map, service, summary, tags, description, overwriteService, portalFolder, timezone, federatedServerUrl, share_public, share_organization, share_groups, outdir): """ScriptTool function docstring""" # Set output file names sddraft_filename = service + ".sddraft" sddraft_output_filename = os.path.join(outdir, sddraft_filename) # Reference layers to publish aprx = arcpy.mp.ArcGISProject("CURRENT") m = aprx.listlayers('CURRENT')[0] selected_layer = m.listLayers()[0] # Create MapImageSharingDraft and set service properties server_type = "FEDERATED_SERVER" federated_server_url = federatedServerUrl sharing_draft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service) sharing_draft.federatedServerUrl = federated_server_url sharing_draft.summary = summary sharing_draft.tags = tags sharing_draft.description = description sharing_draft.credits = "My Credits" sharing_draft.useLimitations = "My Use Limitations" sharing_draft.overwriteExistingService = overwriteService sharing_draft.portalFolder = portalFolder # Create Service Definition Draft file sharing_draft.exportToSDDraft(sddraft_output_filename) outsddraft = sddraft_output_filename arcpy.AddMessage("Service definition draft created") # Set time zone if (timezone != ""): property_set = [{ "key": "dateFieldsRespectsDayLightSavingTime", "value": "true" }, { "key": "dateFieldsTimezoneID", "value": timezone }] SetTimezone(sddraft_output_filename, property_set=property_set) # Create Service Definition file sd_filename = service + ".sd" sd_output_filename = os.path.join(outdir, sd_filename) arcpy.StageService_server(sddraft_output_filename, sd_output_filename) arcpy.AddMessage("Service definition created") # Share to portal output = arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url, in_override="OVERRIDE_DEFINITION", in_public=share_public, in_organization=share_organization, in_groups=share_groups) arcpy.AddMessage("Service published") return output[5] def SetTimezone(sddraftPath, property_set): # Read the sddraft xml. doc = DOM.parse(sddraftPath) # Find all elements named TypeName. This is where the server object extension # (SOE) names are defined. typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames: # Get the TypeName to enable if typeName.firstChild.data == "MapServer": extension = typeName.parentNode # prp = extension.childNodes.getElementsByTagNameNS('PropertyArray') for extElement in extension.childNodes: if extElement.tagName == 'Definition': for definition in extElement.childNodes: if definition.tagName == 'ConfigurationProperties': for config_prop in definition.childNodes: if config_prop.tagName == 'PropertyArray': for prop in property_set: prop_set = doc.createElement("PropertySetProperty") attr = doc.createAttribute("xsi:type") attr.value = "typens:PropertySetProperty" prop_set.setAttributeNode(attr) prop_key = doc.createElement("Key") txt = doc.createTextNode(prop["key"]) prop_key.appendChild(txt) prop_set.appendChild(prop_key) prop_value = doc.createElement("Value") attr = doc.createAttribute("xsi:type") attr.value = "xs:string" prop_value.setAttributeNode(attr) txt = doc.createTextNode(prop["value"]) prop_value.appendChild(txt) prop_set.appendChild(prop_value) config_prop.appendChild(prop_set) # Write to the .sddraft file f = open(sddraftPath, 'w') doc.writexml(f) f.close() arcpy.AddMessage("Time zone set") return if __name__ == '__main__': # ScriptTool parameters map = arcpy.GetParameter(0) service = arcpy.GetParameterAsText(1) summary = arcpy.GetParameterAsText(2) tags = arcpy.GetParameterAsText(3) description = arcpy.GetParameterAsText(4) overwriteService = arcpy.GetParameter(5) portalFolder = arcpy.GetParameterAsText(6) timezone = arcpy.GetParameterAsText(7) federatedServerUrl = arcpy.GetParameterAsText(8) share_public = arcpy.GetParameterAsText(9) share_organization = arcpy.GetParameterAsText(10) share_groups = arcpy.GetParameterAsText(11) outdir = arcpy.GetParameterAsText(12) rest_endpoint = ScriptTool(map, service, summary, tags, description, overwriteService, portalFolder, timezone, federatedServerUrl, share_public, share_organization, share_groups, outdir) arcpy.SetParameterAsText(1, rest_endpoint) arcpy.AddMessage(rest_endpoint)
and this is the error:
It would be helpful if you posted what code you're using, (see formatting guide here) as well as your error messages.
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.