MapImageSharingDraft

Summary

The MapImageSharingDraft class allows you to configure map image layer properties and create a service definition draft (.sddraft) file, which can then be shared to ArcGIS Enterprise.

Discussion

To create the MapImageSharingDraft class object, use the map class function getWebLayerSharingDraft and set the service_type parameter to MAP_IMAGE. The MapImageSharingDraft class object can then be configured by setting service level properties. Use the federatedServerUrl property to specify the federated server to which the web layer is published. After the MapImageSharingDraft class object has been 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 Enterprise using the Stage Service and Upload Service Definition tools. For more information, see Introduction to arcpy.sharing.

Code samples are available for the following:

Properties

PropertyExplanationData Type
copyDataToServer
(Read and Write)

A Boolean that indicates whether the data in your map is copied to the server. A value of True will copy all of the data in your map—including data that is registered with your federated server. A value of False will only copy data that is not registered with your federated server—data registered with your federated server will be referenced by the service.

Boolean
credits
(Read and Write)

A string that represents the credits.

String
description
(Read and Write)

A string that represents the description.

String
federatedServerUrl
(Read and Write)

A string representing the URL to the ArcGIS Enterprise portal federated server.

Tip:

The federated server URL can also be used in the in_server parameter in the Upload Service Definition tool. The code samples below demonstrate this.

String
offline
(Read and Write)

A Boolean that determines whether to use a portal connection. If offline is set to False, you must be signed in to a portal as well as provide an ArcGIS Enterprise portal federated server URL to the federatedServerUrl property to create a service definition draft (.sddraft) file using the exportToSDDraft function. If offline is set to True, a service definition draft file can be created without being signed in to a portal and without populating the federatedServerUrl property.

Boolean
overwriteExistingService
(Read and Write)

A Boolean that determines whether to overwrite an existing web layer.

Boolean
portalFolder
(Read and Write)

A string that represents the name of an existing portal folder to which you want to publish the web layer. The default folder is your root folder in My Content.

String
serverFolder
(Read and Write)

A string that represents the name of a server folder to which you want to publish the service. The default folder is the root folder of the federated server.

String
serverType
(Read Only)

Returns a string representing the server type as specified when the sharing draft was created from the getWebLayerSharingDraft function from the map class. The only possible value returned from serverType for a MapImageSharingDraft is FEDERATED_SERVER. A serverType of FEDERATED_SERVER indicates support for sharing to an ArcGIS Enterprise portal federated server.

String
serviceName
(Read and Write)

A string that represents the name of the web layer. 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)

A string that represents the summary.

String
tags
(Read and Write)

A string that represents the tags. Multiple tags can be added or separated by a comma or semicolon.

String
useLimitations
(Read and Write)

A string that represents the use limitations.

String

Method Overview

MethodExplanation
exportToSDDraft (out_sddraft)

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

Methods

exportToSDDraft (out_sddraft)
ParameterExplanationData Type
out_sddraft

A string that represents the path and file name for the output service definition draft (.sddraft) file.

String

Once the MapImageSharingDraft has been configured, it can be saved as a service definition draft (.sddraft) file. It can then be staged and shared to the ArcGIS Enterprise portal federated server using the Stage Service and Upload Service Definition tools.

Code sample

Publish a map image layer

The following script creates a map image layer service definition draft (.sddraft) file for a map and sets metadata properties. The map image layer is published to a folder in ArcGIS Enterprise. Portal information is obtained from the SignInToPortal function.

import arcpy
import os

# Sign in to portal
arcpy.SignInToPortal("https://www.portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
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 MapImageSharingDraft and set metadata, portal folder, and server folder properties
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.esri.com/server"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url
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.portalFolder = "my folder name"
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)

# Share to portal
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url)

print("Finish Publishing")
Overwrite a map image layer

The following script overwrites a map image layer. If the service name already exists, the service will be overwritten. Otherwise, a new service will be created.

import arcpy
import os

# Sign in to portal
arcpy.SignInToPortal("https://www.portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
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 MapImageSharingDraft and set overwrite property
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.esri.com/server"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url
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)

# Share to portal
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url)

print("Finish Publishing")
Publish a map image layer with an associated feature layer

The following script creates a map image layer service definition draft (.sddraft) file. It then enables feature access on the map image layer by modifying the service definition draft file using the xml.dom.minidom standard Python library. The modified service definition file is then published to an ArcGIS Enterprise portal federated server. The data store must be already registered on the server for the data to be referenced.

import arcpy
import os
import xml.dom.minidom as DOM

# Sign in to portal
arcpy.SignInToPortal("https://www.portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
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 MapImageSharingDraft and set copyDataToServer property to False to reference registered data
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.esri.com/server"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url
sddraft.copyDataToServer = False

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

"""Modify the .sddraft file to enable feature access"""
# Read the file
doc = DOM.parse(sddraft_output_filename)

# Find all elements named TypeName
# This is where the addition layers and capabilities 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'

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

# Share to portal
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url)

print("Finish Publishing")
Analyze and register a data store

The following script creates a service definition draft (.sddraft) file for a map image layer that references registered data. The service definition draft file is analyzed during staging. If analyzer 24011 is returned warning that the data source is not registered with the server, the data store is registered using the AddDataStoreItem function.

import arcpy
import os

arcpy.env.overwriteOutput = True

# Sign in to portal
arcpy.SignInToPortal("https://www.portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
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 MapImageSharingDraft and set copyDataToServer property to False to reference registered data
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.esri.com/server"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
sddraft.federatedServerUrl = federated_server_url
sddraft.copyDataToServer = False

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

# Stage the service and analyze the .sddraft file for registered data store 
# Continue publishing only if data store is registered
print("Start Staging")
stage_service = True
while stage_service:
    arcpy.StageService_server(sddraft_output_filename, sd_output_filename)
    # Get analyzer warnings to check if data store is registered
    warnings = arcpy.GetMessages(1)
    print(warnings)
    # If data store is not registered
    if "24011" in warnings:
        # Register data store
        db_conn = r"C:\Project\db_conn.sde"
        register_msg = arcpy.AddDataStoreItem(federated_server_url, "DATABASE", "datastore_name", db_conn)
        print("Registered datastore: {0}".format(register_msg))
        # Stage the service again
        stage_service = True
    else:
        stage_service = False

# Share to portal
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url)

print("Finish Publishing")
Set a time zone and configure pooling

The following script creates a map image layer service definition draft (.sddraft) file. It then sets a time zone for layers with date fields and configures service instance settings by modifying the service definition draft file using the xml.etree.ElementTree and xml.dom.minidom standard Python libraries. The modified service definition file is then published to an ArcGIS Enterprise portal federated server. The data store must be already registered on the server for the data to be referenced.

import arcpy
import os
import xml.dom.minidom as DOM
import codecs
import xml.etree.ElementTree as ET

def enable_extensions(sddraftPath, soe):
"""Function to enable extensions"""
    # Read the .sddraft file
    doc = DOM.parse(sddraftPath)

    # Find all elements named TypeName
    # This is where the additional layers and capabilities are defined
    typeNames = doc.getElementsByTagName('TypeName')
    for typeName in typeNames:
        # Get the TypeName to enable
        if typeName.firstChild.data == soe:
            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(sddraftPath, 'w')
    doc.writexml(f)
    f.close()

# soe = extension for which properties have to be added
def enable_configproperties(sddraftPath, soe, property_set):
"""Function to configure extension properties"""
    # Read the file
    doc = DOM.parse(sddraftPath)

    # Find all elements named TypeName
    # This is where the extensions are defined
    typeNames = doc.getElementsByTagName('TypeName')
    for typeName in typeNames:
        # Get the TypeName we want to enable
        if typeName.firstChild.data == soe:
            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()

if __name__ == "__main__":
    # Sign in to portal
    arcpy.SignInToPortal("https://www.portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

    # Set output file names
    outdir = r"C:\Project\Output"
    service_name = "MapImageSharingDraftExample"
    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 MapImageSharingDraft and set copyDataToServer property to False to reference registered data
    server_type = "FEDERATED_SERVER"
    federated_server_url = "https://MyFederatedServer.esri.com/server"
    sddraft = m.getWebLayerSharingDraft(server_type, 'MAP_IMAGE', service_name)
    sddraft.federatedServerUrl = federated_server_url
    sddraft.copyDataToServer = False
    sddraft.exportToSDDraft(sddraft_output_filename)

    # Set time zone to UTC
    property_set = [{
        "key": "dateFieldsRespectsDayLightSavingTime",
        "value": "true"
    },
        {
            "key": "dateFieldsTimezoneID",
            "value": "UTC"
        }]
    enable_configproperties(sddraft_output_filename, soe="MapServer", property_set=property_set)

    # Enable extensions on map server
    enable_extensions(sddraft_output_filename, "FeatureServer")
    # enable_extensions(sddraft_output_filename, "VersionManagementServer")
    # enable_extensions(sddraft_output_filename, "LRServer")

    # Configure pooling options
    doc = DOM.parse(sddraft_output_filename)
    def_childnodes = doc.getElementsByTagName("Definition")[0].childNodes
    for def_node in def_childnodes:
        if def_node.nodeName == "Props":
            for node in def_node.childNodes[0].childNodes:
                # Change the provider to modify instance type
                # provider='DMaps' for shared or 'ArcObjects11' for dedicated
                if node.firstChild.firstChild.data == 'provider':
                    node.lastChild.firstChild.data = 'ArcObjects11'
                elif node.firstChild.firstChild.data == 'MinInstances':
                    node.lastChild.firstChild.data = '0'
                elif node.firstChild.firstChild.data == 'MaxInstances':
                    node.lastChild.firstChild.data = '2'

    # Write to the .sddraft file
    f = open(sddraft_output_filename, 'w')
    doc.writexml(f)
    f.close()

    print("Start Staging")
    arcpy.StageService_server(sddraft_output_filename, sd_output_filename)

    print("Start Uploading")
    arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url)

    print("Finish Publishing")
Publish a layer and table

The following script publishes a layer and table as a map image layer to an ArcGIS Enterprise portal.

import arcpy
import os

# Sign in to portal
arcpy.SignInToPortal("https://www.portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
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 layers to publish
aprx = arcpy.mp.ArcGISProject(r"C:\Project\World.aprx")
m = aprx.listMaps('World')[0]
selected_layer = m.listLayers()[0]
selected_table = m.listTables()[0]

# Create MapImageSharingDraft
server_type = "FEDERATED_SERVER"
federated_server_url = "https://MyFederatedServer.esri.com/server"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name, [selected_layer, selected_table])
sddraft.federatedServerUrl = federated_server_url

# Create Service Definition Draft file
sddraft.exportToSDDraft(sddraft_output_filename)

# Stage Service
print("Start Staging")
arcpy.StageService_server(sddraft_output_filename, sd_output_filename)

# Share to portal
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, federated_server_url)

print("Finish Publishing")
Create and publish an offline service definition

The following script creates an offline service definition and publishes it as a map image layer.

import arcpy
import os

# Set output file names
outdir = r"C:\Project\Output"
service_name = "MapImageSharingDraftExample"
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 MapImageSharingDraft and set offline property
server_type = "FEDERATED_SERVER"
sddraft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
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)

# Sign in to portal to upload and publish
arcpy.SignInToPortal("https://www.portal.domain.com/webadaptor", 
"MyUserName", "MyPassword")

# Share to portal
print("Start Uploading")
arcpy.UploadServiceDefinition_server(sd_output_filename, "https://MyFederatedServer.esri.com/server")

print("Finish Publishing")