Summary
The MapServiceDraft class allows you to configure map service properties and create a service definition draft (.sddraft) file, which can be shared to ArcGIS Server.
Discussion
To create a MapServiceDraft object, use the arcpy.sharing.CreateSharingDraft function and set the server_type parameter to STANDALONE_SERVER and the service_type parameter to MAP_SERVICE. The MapServiceDraft object can then be configured by setting service-level properties. Use the targetServer property to specify the server to which the map service is published. After the MapServiceDraft object is configured, it can be saved to a service definition draft (.sddraft) file using the exportToSDDraft function. It can then be staged and shared to ArcGIS Server using the Stage Service and Upload Service Definition tools. For more information, see Introduction to arcpy.sharing.
Once the .sddraft file has been staged and uploaded to the server, the tools in the Caching toolset can be used to create and manage map server caches for faster display of map services, such as the Manage Map Server Cache Tiles tool. The tiling scheme can also be modified by editing the .sddraft file using XML libraries such as the xml.dom.minidom library. However, due to the complexity of the tiling scheme XML structure, it is recommended that you use the Caching toolset whenever possible.
Code samples are available for the following:
Properties
Property | Explanation | Data Type |
copyDataToServer (Read and Write) | Specifies whether the data in your map will be copied to the server. A value of True will copy all of the data in your map, including data that is registered with your server. A value of False will only copy data that is not registered with your server; data registered with your server will be referenced by the service. | Boolean |
credits (Read and Write) | The credits of the map service draft. | String |
description (Read and Write) | The description of the map service draft. | String |
offline (Read and Write) | Specifies whether to use a server connection. If set to False, you must provide a server URL or an ArcGIS Server connection file (.ags) to the targetServer property to create a service definition draft (.sddraft) file using the exportToSDDraft function. If set to True, a service definition draft file can be created without populating the targetServer property. | Boolean |
overwriteExistingService (Read and Write) | Specifies whether an existing service with the same name will be overwritten. | Boolean |
serverFolder (Read and Write) | The name of a server folder to which you want to publish the service. The default folder is the root folder of the server. The folder will be created if it does not already exist. | String |
serverType (Read Only) | The server type as specified when the MapServiceDraft was created from the CreateSharingDraft function. The only possible value returned from serverType for a MapServiceDraft is STANDALONE_SERVER. A serverType of STANDALONE_SERVER indicates support for creating a map service for ArcGIS Server. | String |
serviceName (Read and Write) | The name of the map service. This is the name people will see and use to identify the service. The name can only contain alphanumeric characters and underscores. No spaces or special characters are allowed. The name cannot be more than 120 characters. | String |
summary (Read and Write) | The summary of the map service draft. | String |
tags (Read and Write) | The tags of the map service draft. Tags can be separated by commas or semicolons. | String |
targetServer (Read and Write) | The server to which the map will be published. The server can be specified using either of the following formats:
For more information, see Connect to a GIS server. Tip:The targetServer can also be used in the in_server parameter in the Upload Service Definition tool. The code samples below demonstrate this. | String |
useLimitations (Read and Write) | The use limitations of the map service draft. | String |
Method Overview
Method | Explanation |
exportToSDDraft (out_sddraft) | Converts a MapServiceDraft to a service definition draft (.sddraft) file. |
Methods
exportToSDDraft (out_sddraft)
Parameter | Explanation | Data Type |
out_sddraft | The path and file name for the output service definition draft (.sddraft) file. | String |
Once the MapServiceDraft is configured, it can be saved as a service definition draft (.sddraft) file. It can then be staged and shared to ArcGIS Server using the Stage Service and Upload Service Definition tools.
Code sample
The following script creates a map service definition draft (.sddraft) file for a map and sets metadata properties. The map service is published to a folder in a stand-alone ArcGIS Server.
import arcpy
import os
# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapServiceDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)
# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
# Create MapServiceDraft and set metadata and server folder properties
target_server_connection = r"C:\Project\gisserver.ags.esri.com (publisher).ags"
sddraft = arcpy.sharing.CreateSharingDraft("STANDALONE_SERVER", "MAP_SERVICE", service_name, m)
sddraft.targetServer = target_server_connection
sddraft.credits = "These are credits"
sddraft.description = "This is description"
sddraft.summary = "This is summary"
sddraft.tags = "tag1, tag2"
sddraft.useLimitations = "These are use limitations"
sddraft.serverFolder = "MyServerFolder"
# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)
# Stage Service
print("Start Staging")
arcpy.StageService_server(sddraft_output_filename, sd_output_filename)
# Publish to server
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, target_server_connection)
print("Finish Publishing")
The following script overwrites a map service. If the service name already exists, the service will be overwritten. Otherwise, a new service will be created.
import arcpy
import os
# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapServiceDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)
# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
# Create MapServiceDraft and set overwrite property
target_server_connection = r"C:\Project\gisserver.ags.esri.com (publisher).ags"
sddraft = arcpy.sharing.CreateSharingDraft("STANDALONE_SERVER", "MAP_SERVICE", service_name, m)
sddraft.targetServer = target_server_connection
sddraft.overwriteExistingService = True
# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)
# Stage Service
print("Start Staging")
arcpy.StageService_server(sddraft_output_filename, sd_output_filename)
# Publish to server
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, target_server_connection)
print("Finish Publishing")
The following script publishes a map service that references registered data. The data store must be already registered on the server for the data to be referenced.
import arcpy
import os
# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapServiceDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)
# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
# Create MapServiceDraft and set copyDataToServer property to false to reference registered data
target_server_connection = r"C:\Project\gisserver.ags.esri.com (publisher).ags"
sddraft = arcpy.sharing.CreateSharingDraft("STANDALONE_SERVER", "MAP_SERVICE", service_name, m)
sddraft.targetServer = target_server_connection
sddraft.copyDataToServer = False
# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)
# Stage Service
print("Start Staging")
arcpy.StageService_server(sddraft_output_filename, sd_output_filename)
# Publish to server
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, target_server_connection)
print("Finish Publishing")
The following script publishes a cached map service by calling the Manage Map Server Cache Tiles tool to create map service cache tiles.
import arcpy
import os
import xml.dom.minidom as DOM
# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapServiceDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)
# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
# Create MapServiceDraft
target_server_connection = r"C:\Project\gisserver.ags.esri.com (publisher).ags"
sddraft = arcpy.sharing.CreateSharingDraft("STANDALONE_SERVER", "MAP_SERVICE", service_name, m)
sddraft.targetServer = target_server_connection
# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)
"""Modify the .sddraft to enable caching"""
# Read the file
doc = DOM.parse(sddraft_output_filename)
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 = "true"
# Write to a new .sddraft file
sddraft_mod_xml = service_name + '_mod_xml' + '.sddraft'
sddraft_mod_xml_file = os.path.join(outdir, sddraft_mod_xml)
f = open(sddraft_mod_xml_file, 'w')
doc.writexml(f)
f.close()
try:
# Stage Service
print("Start Staging")
arcpy.StageService_server(sddraft_mod_xml_file, sd_output_filename)
warnings = arcpy.GetMessages(1)
print(warnings)
# Publish to server
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, target_server_connection)
print("Finish Publishing")
# Manage Map server Cache Tiles
# For cache, use multiple scales separated by semicolon (;)
# For example, "591657527.591555;295828763.795777"
arcpy.server.ManageMapServerCacheTiles(target_server_connection + os.sep + service_name + ".MapServer", "591657527.591555",
"RECREATE_ALL_TILES")
except Exception as stage_exception:
print("Analyzer errors encountered - {}".format(str(stage_exception)))
except arcpy.ExecuteError:
print(arcpy.GetMessages(2))
The following script creates a map service definition draft (.sddraft) file for a map. It then enables feature access on the map service and uses an existing cache to draw the service by modifying the service definition draft file using the xml.dom.minidom standard Python library. The modified service definition file is then published to ArcGIS Server.
import arcpy
import os
import xml.dom.minidom as DOM
# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapServiceDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)
# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
# Create MapServiceDraft
target_server_connection = r"C:\Project\gisserver.ags.esri.com (publisher).ags"
sddraft = arcpy.sharing.CreateSharingDraft("STANDALONE_SERVER", "MAP_SERVICE", service_name, m)
sddraft.targetServer = target_server_connection
# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)
"""Modify the .sddraft file to keep existing cache and enable feature access"""
# Read the file
doc = DOM.parse(sddraft_output_filename)
# Find all elements named TypeName
# This is where the extensions are defined
typeNames = doc.getElementsByTagName('TypeName')
for typeName in typeNames:
# Get the TypeName to enable
if typeName.firstChild.data == "FeatureServer":
extension = typeName.parentNode
for extElement in extension.childNodes:
# Enable feature access
if extElement.tagName == 'Enabled':
extElement.firstChild.data = 'true'
# 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"
# Enable feature access capabilities
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,Query,Data"
# Use existing cache
configProps = doc.getElementsByTagName('KeepExistingMapCache')[0]
configProps.firstChild.data = "true"
# Write to a new .sddraft file
sddraft_mod_xml = service_name + '_mod_xml' + '.sddraft'
sddraft_mod_xml_file = os.path.join(outdir, sddraft_mod_xml)
f = open(sddraft_mod_xml_file, 'w')
doc.writexml(f)
f.close()
# Stage Service
print("Start Staging")
arcpy.StageService_server(sddraft_mod_xml_file, sd_output_filename)
# Publish to server
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, target_server_connection)
print("Finish Publishing")
The following script creates an offline service definition and publishes it as a map service.
import arcpy
import os
# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapServiceDraftExample"
sddraft_filename = service_name + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)
sd_filename = service_name + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)
# Reference map to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
# Create MapServiceDraft and set offline property
# The targetServer property is not needed when the offline property is set to True
sddraft = arcpy.sharing.CreateSharingDraft("STANDALONE_SERVER", "MAP_SERVICE", service_name, m)
sddraft.offline = True
# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)
# Stage Service
print("Start Staging")
arcpy.StageService_server(sddraft_output_filename, sd_output_filename)
# Publish to server
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, r"C:\Project\gisserver.ags.esri.com (publisher).ags")
print("Finish Publishing")