MapServiceDraft

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

PropertyExplanationData 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:

  • The full path to an ArcGIS Server connection file (.ags).
  • An ArcGIS Server URL. Use this option when you have a publisher or administrator connection to ArcGIS Server in the ArcGIS Pro project and you are opening the project in the script or running the script in ArcGIS Pro.

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

MethodExplanation
exportToSDDraft (out_sddraft)

Converts a MapServiceDraft to a service definition draft (.sddraft) file.

Methods

exportToSDDraft (out_sddraft)
ParameterExplanationData 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

Publish a map service

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")
Overwrite a map service

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")
Publish a map service that references registered data

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")
Publish a cached map service

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))
Publish a map service that draws from existing cache

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")
Create and publish an offline service definition

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")