Select to view content in your preferred language

sddraft xml schema

756
0
12-28-2022 12:52 PM
DannyIm
Emerging Contributor

Hello,

I have a python script that I use to publish map and image services to an ArcGIS Enterprise server for my organization, and the script involve creating an .sddraft file, modifying the XML in the .sddraft file, transforming it to a service definition file, then publishing it.

I was wondering if the XML schema for the .sddraft file is documented anywhere? My modifications to the .sddraft file are based on what I find on other ESRI forum posts and documentation, but there are some settings that I don’t know how to configure since I don’t know the XML schema.

Is there a better way to achieve what I am trying to do? If there’s a better approach with a simpler interface that would be wonderful.

I am using ArcPro 3.0 and publishing to ArcGIS Server 10.9.1

Here is the code:

import arcpy
import codecs
import getpass
import logging
import os
import sys
import shutil
import tempfile
import xml.dom.minidom as DOM

from pathlib import Path
from arcgis.gis.server import Server

ags_pw = getpass.getpass("ArcGIS server password: ")
ags_host = "https://localhost:6443"
ags_user = "admin"
project_filename = f"samples/my_example.aprx"
svc_name = "my_example"

def setText(doc, node, newText):
	textnode = doc.createTextNode(newText)
	node.appendChild(textnode)

tmp_sd_pth = os.path.join(os.getcwd(), "tmp.sd")

with tempfile.TemporaryDirectory() as tmp_dir:
	tmp_pth = Path(tmp_dir)
	sd_draft_fn = tmp_pth.joinpath("tempdraft.sddraft")
	new_sd_draft = tmp_pth.joinpath("updatedDraft.sddraft")
	sd = tmp_pth.joinpath(f"{svc_name}.sd")

	mapdoc = arcpy.mp.ArcGISProject(project_filename)
	maps = mapdoc.listMaps()
	map = mapdoc.listMaps()[0]
	sd_draft = arcpy.sharing.CreateSharingDraft("STANDALONE_SERVER", "MAP_SERVICE", svc_name, map)

	sd_draft.offline = True
	sd_draft.offlineTarget = "ENTERPRISE_10x"
	sd_draft.description = "Description"
	sd_draft.serverFolder = "maps"

	sd_draft.overwriteExistingService = True
	sd_draft.exportToSDDraft(sd_draft_fn)

	doc = DOM.parse(sd_draft_fn.as_posix())

	tagsType = doc.getElementsByTagName('Type')
	for tagType in tagsType:
		if tagType.parentNode.tagName == 'SVCManifest':
        		if tagType.hasChildNodes():
        			tagType.firstChild.data = "esriServiceDefinitionType_Replacement"

	tagsState = doc.getElementsByTagName('State')
    	for tagState in tagsState:
        	if tagState.parentNode.tagName == 'SVCManifest':
            		if tagState.hasChildNodes():
                		tagState.firstChild.data = "esriSDState_Published"

	# Turn off caching
	configProps = doc.getElementsByTagName('ConfigurationProperties')[0]
	propArray = configProps.firstChild
	propSets = propArray.childNodes
	for propSet in propSets:
		keyValues = propSet.childNodes
        	for keyValue in keyValues:
        		if keyValue.tagName == 'Key':
				if keyValue.firstChild.data == "isCached":
					keyValue.nextSibling.firstChild.data = "false"
				if keyValue.firstChild.data == "maxRecordCount":
					keyValue.nextSibling.firstChild.data = "2000"

	# Find all elements named TypeName
	# This is where the extensions are defined
	typeNames = doc.getElementsByTagName('TypeName')
	for typeName in typeNames:
		if typeName.firstChild.data == "KmlServer":
			extension = typeName.parentNode
			for extElement in extension.childNodes:
				if extElement.tagName == 'Enabled':
					extElement.firstChild.data = 'true'
		if typeName.firstChild.data == "WFSServer":
			extension = typeName.parentNode
			for extElement in extension.childNodes:
				if extElement.tagName == 'Enabled':
					extElement.firstChild.data = 'true'
		if typeName.firstChild.data == "WMSServer":
			extension = typeName.parentNode
			for extElement in extension.childNodes:
				if extElement.tagName == 'Enabled':
					extElement.firstChild.data = 'true'
		if typeName.firstChild.data == "WCSServer":
			extension = typeName.parentNode
			for extElement in extension.childNodes:
				if extElement.tagName == 'Enabled':
					extElement.firstChild.data = 'true'
		if typeName.firstChild.data == "FeatureServer":
			extension = typeName.parentNode
			for extElement in extension.childNodes:
				if extElement.tagName == 'Enabled':
					extElement.firstChild.data = 'true'
	configProps = doc.getElementsByTagName('Info')[0]
	propArray = configProps.firstChild
	propSets = propArray.childNodes
	for propSet in propSets:
		keyValues = propSet.childNodes
		for keyValue in keyValues:
			if keyValue.tagName == 'Key':
				if keyValue.firstChild.data == "WebCapabilities":
					keyValue.nextSibling.firstChild.data = "Map,Data,Query"
	typeNames = doc.getElementsByTagName('TypeName')
	for typeName in typeNames:
		if typeName.firstChild.data == "WFSServer":
			extension = typeName.parentNode
			for extElement in extension.childNodes:
				if extElement.tagName == "Props":
					for propSet in extElement.childNodes:
						for prop in propSet.childNodes:
							for prop1 in prop.childNodes:
								if prop1.tagName == "Key":
									if prop1.firstChild.data == "title":
										setText(doc, prop1.nextSibling, "Example")
									if prop1.firstChild.data == "abstract":
										setText(doc, prop1.nextSibling, "Abstract")
									if prop1.firstChild.data == "keyword":
										setText(doc, prop1.nextSibling, "Keyword")
	# Write to a new .sddraft file
	with codecs.open(new_sd_draft, "w", "utf-8") as f:
	        doc.writexml(writer=f, encoding="utf-8")

	logging.info("Analyzing and Staging the service...")
	arcpy.server.StageService(new_sd_draft.as_posix(), sd.as_posix())
	warnings = arcpy.GetMessages(1)
	errors = arcpy.GetMessages(2)

	if errors:
		logging.error("errors found in service definition")
		logging.error(errors)
		sys.exit(1)

	shutil.copyfile(sd, tmp_sd_pth)

	server = Server(url=f"{ags_host}/arcgis/admin", token_url=f"{ags_host}/arcgis/tokens/generateToken", username=ags_user, password=ags_pw)
	pr = server.publish_sd(tmp_sd_pth)
	if pr:
		logging.info(f"Service was successfully published")
	else:
		logging.error("Failed to publish service")

 

0 Replies