CreateMapSDDraft (arcpy.mapping)

Summary

Converts Map Document (.mxd) files to Service Definition Draft (.sddraft) files.

Discussion

CreateMapSDDraft is the first step to automating the publishing of a Map Document to a GIS Server using ArcPy. The output created from the CreateMapSDDraft is a Service Definition Draft (.sddraft) file. A Service Definition Draft is the combination of a Map Document, information about the server, and a set of service properties.

Information about the server includes the server connection or server type being published to, the type of service being published, metadata for the service (Item info), and data references (whether or not data is being copied to the server).

Service properties include whether the service supports caching and, if so, the cache settings. Also included are any additional capabilities of the service, such as Feature access or OGC capabilities, along with an appropriate property set for the chosen capability. This method initially uses a set of default service properties. Users can edit these properties using standard third-party XML editors. Moreover, users can automate the modification of these properties using third-party XML libraries such as the xml.dom.minidom standard Python library. See the Modify SDDraft examples below.

NoteNote:

A draft service definition does not contain data. A draft service alone cannot be used to publish a service.

Similar to the AnalyzeForSD function, CreateMapSDDraft also returns a Python dictionary containing errors and other potential issues that you should address prior to creating your Service Definition file. For more information about the types of errors, warnings and information messages, and how to access them, see AnalyzeForSD.

A Service Definition Draft can be authored without knowing the specific server connection information. In this case, the connection_file_path parameter may be omitted; however, the server_type must be provided. A server connection can be provided later when the Service Definition Draft is published using the Upload Service Definition tool.

The Service Definition Draft can then be converted to a fully consolidated Service Definition (.sd) file using the Stage Service tool. Staging compiles all the necessary information needed to successfully publish the GIS resource. If your data is not registered with the server, the data will be added when the Service Definition Draft is staged. Finally, the Service Definition file can be uploaded and published as a GIS service to a specified GIS server using the Upload Service Definition tool. This step takes the Service Definition file, copies it onto the server, extracts required information, and publishes the GIS resource. For more information, see the overview of the Publishing toolset.

Once the .sddraft file has been staged and uploaded to the server, the tools within the Caching toolset can be used to create the tiling scheme for services that have caching enabled, such as the Create Map Server Cache tool. Moreover, the tools within the Caching toolset can be used to modify caching and tiling properties for services that have caching enabled. For example, the Manage Map Server Cache Scales tool can be used to add new scales or delete existing scales from a cache. Modify SDDraft example 6 demonstrates this. The tiling scheme can also be modified by editing the .sddraft file using third-party XML libraries such as the xml.dom.minidom standard Python library. However, due to the complexity of the tiling scheme XML structure, it is recommended to use the Caching toolset whenever possible.

When publishing hosted services to ArcGIS Online or Portal for ArcGIS, sign in information is obtained from the File > Sign In dialog box on the ArcGIS for Desktop main menu. Moreover, the Sign In To Portal tool can be used to specify sign in information for some security configurations for Portal for ArcGIS. For more information on hosted services and signing in to ArcGIS Online or Portal for ArcGIS, see the following topics:

NoteNote:

The ArcGIS for Server Administrator API also allows you to script common actions you do with your server. For example, stop and start services, edit properties of services, such as the maximum number of instances, grant and revoke user permissions on services, and so on.

You can also create Service Definition Draft files for geoprocessing, image, and geocoding services. See the following related functions:

Syntax

CreateMapSDDraft (map_document, out_sddraft, service_name, {server_type}, {connection_file_path}, {copy_data_to_server}, {folder_name}, {summary}, {tags})
ParameterExplanationData Type
map_document

A variable that references a MapDocument object.

MapDocument
out_sddraft

A string that represents the path and file name for the output Service Definition Draft (.sddraft) file.

String
service_name

A string that represents the name of the 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 in length.

String
server_type

A string representing the server type. If a connection_file_path parameter is not supplied, then a server_type must be provided. If a connection_file_path parameter is supplied, then the server_type is taken from the connection file. In this case, you can choose FROM_CONNECTION_FILE or skip the parameter entirely.

  • ARCGIS_SERVERArcGIS for Server server type
  • FROM_CONNECTION_FILEGet the server_type as specified in the connection_file_path parameter
  • MY_HOSTED_SERVICESMy Hosted Services server type for ArcGIS Online or Portal for ArcGIS

LegacyLegacy:

Starting at ArcGIS 10.2.1 for Desktop, SPATIAL_DATA_SERVER is not a supported server_type. For more information, see What's new in ArcGIS 10.2.1 for Server.

(The default value is ARCGIS_SERVER)

String
connection_file_path

A string that represents the path and file name to the ArcGIS for Server connection file (.ags).

When the server_type is set to MY_HOSTED_SERVICES, connection_file_path is not required.

String
copy_data_to_server

A Boolean that indicates whether the data referenced in the map document will be copied to the server or not. The copy_data_to_server parameter is only used if the server_type is ARCGIS_SERVER and the connection_file_path isn't specified. If the connection_file_path is specified, then the server's registered data stores are used. For example, if the data in the map_document is registered with the server, then copy_data_to_server will always be False. Conversely, if the data in the map_document is not registered with the server, then copy_data_to_server will always be True.

When the server_type is set to MY_HOSTED_SERVICES, copy_data_to_server will always be True. My Hosted Maps services always copy data to the server.

(The default value is False)

Boolean
folder_name

A string that represents a folder name to which you want to publish the service definition. If the folder does not currently exist, it will be created. The default folder is the server root level.

(The default value is None)

String
summary

A string that represents the Item Description Summary.

By default, the Summary from the ArcMap Map Properties dialog box or Catalog window Item Description dialog box for the map_document will be used. Use this parameter to override the user interface summary, or to provide a summary if one does not exist. The summary provided here will not be persisted in the map document.

(The default value is None)

String
tags

A string that represents the Item Description Tags.

By default, the Tags from the ArcMap Map Properties dialog box or Catalog window Item Description dialog box for the map_document will be used. Use this parameter to override the user interface tags, or to provide tags if they do not exist. The tags provided here will not be persisted in the map document.

(The default value is None)

String
Return Value
Data TypeExplanation
Dictionary

Returns a Python Dictionary of information messages, warnings, and errors.

Code Sample

CreateMapSDDraft example 1

The following script demonstrates the complete publishing of map services using arcpy.mapping workflow. Automating the publishing of map services can be accomplished by using a combination of arcpy.mapping functions and the geoprocessing tools in the Publishing toolset. The workflow begins with a map document that you want to publish. First, use the arcpy.mapping function CreateMapSDDraft to create a service definition draft. Note that the Item Description, Summary, and Tags for the input map document are overwritten using the summary and tags parameters. Next, you should analyze the service definition draft for issues that could prevent you from publishing successfully. After analyzing the service definition draft and addressing serious issues, it is time to stage the service definition. Staging takes the service definition draft and consolidates all the information needed to publish the service into a complete service definition. Use the Stage Service geoprocessing tool to stage the service definition. Finally, use the Upload Service Definition geoprocessing tool to upload the service definition to the server and publish the map service.

import arcpy

# define local variables
wrkspc = 'C:/Project/'
mapDoc = arcpy.mapping.MapDocument(wrkspc + 'counties.mxd')
con = 'GIS Servers/arcgis on MyServer_6080 (publisher).ags' 
service = 'Counties'
sddraft = wrkspc + service + '.sddraft'
sd = wrkspc + service + '.sd'
summary = 'Population Density by County'
tags = 'county, counties, population, density, census'

# create service definition draft
analysis = arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER', 
                                          con, True, None, summary, tags)

# stage and upload the service if the sddraft analysis did not contain errors
if analysis['errors'] == {}:
    # Execute StageService
    arcpy.StageService_server(sddraft, sd)
    # Execute UploadServiceDefinition
    arcpy.UploadServiceDefinition_server(sd, con)
else: 
    # if the sddraft analysis contained errors, display them
    print analysis['errors']
CreateMapSDDraft example 2

The following sample script creates a Service Definition Draft (.sddraft) file from a Map Document (.mxd). It then prints the Python Dictionary of errors, warnings, and information, which is returned from the CreateMapSDDraft function. The analysis information contained in the Python dictionary helps to identify potential performance bottlenecks and map errors that you may need to address before you can create a Service Definition (.sd) file. This script also demonstrates how to create a Service Definition Draft without specifying the server connection information.

import arcpy

mapDoc = arcpy.mapping.MapDocument('C:/Project/counties.mxd') 
service = 'Counties'
sddraft = 'C:/Project/' + service + '.sddraft'
        
analysis = arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER')

for key in ('messages', 'warnings', 'errors'):
  print "----" + key.upper() + "---"
  vars = analysis[key]
  for ((message, code), layerlist) in vars.iteritems():
    print "    ", message, " (CODE %i)" % code
    print "       applies to:",
    for layer in layerlist:
        print layer.name,
    print
CreateMapSDDraft example 3

The following sample script creates a Service Definition Draft (.sddraft) file from a Map Document (.mxd) for My Hosted Services. If the service definition draft contains no analysis errors, it is staged using the Stage Service geoprocessing tool. Then the Upload Service Definition geoprocessing tool is used to upload the service definition to ArcGIS Online or Portal for ArcGIS. ArcGIS Online sign in information is obtained from the File > Sign In dialog box on the ArcGIS for Desktop main menu.

import arcpy

mapDoc = arcpy.mapping.MapDocument('C:/Project/counties.mxd') 
service = 'Counties'
sddraft = 'C:/Project/{}.sddraft'.format(service)
sd = 'C:/Project/{}.sd'.format(service)

# create service definition draft
analysis = arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'MY_HOSTED_SERVICES')

# stage and upload the service if the sddraft analysis did not contain errors
if analysis['errors'] == {}:
    # create service definition
    arcpy.StageService_server(sddraft, sd)
    # publish to My Hosted Services
    arcpy.UploadServiceDefinition_server(sd, 'My Hosted Services')
else: 
    # if the sddraft analysis contained errors, display them
    print analysis['errors']
Modify SDDraft example 1

The following script modifies the Item Information Description element using the xml.dom.minidom standard Python library. The modified Service Definition Draft (.sddraft) file is then saved to a new file. Finally, the new .sddraft file is analyzed for errors using the AnalyzeForSD function.

import arcpy
import xml.dom.minidom as DOM 
# the new description
newDesc = 'US Counties Map'
xml = r"C:\Project\Counties.sddraft"
doc = DOM.parse(xml)
# find the Item Information Description element 
descriptions = doc.getElementsByTagName('Description')
for desc in descriptions:
    if desc.parentNode.tagName == 'ItemInfo':
        # modify the Description
        if desc.hasChildNodes():
            desc.firstChild.data = newDesc
        else:
            txt = doc.createTextNode(newDesc)
            desc.appendChild(txt)
# output to a new sddraft
outXml = r"C:\Project\Output\CountiesForWeb.sddraft"     
f = open(outXml, 'w')     
doc.writexml( f )     
f.close() 

# analyze the new sddraft for errors
analysis = arcpy.mapping.AnalyzeForSD(outXml)
for key in ('messages', 'warnings', 'errors'):
    print "----" + key.upper() + "---"
    vars = analysis[key]
    for ((message, code), layerlist) in vars.iteritems():
        print "    ", message, " (CODE %i)" % code
        print "       applies to:",
        for layer in layerlist:
            print layer.name,
        print
Modify SDDraft example 2

The following script modifies the Staging Settings TextAntialiasingMode element using the xml.dom.minidom standard Python library. The modified Service Definition Draft (.sddraft) file is then saved to a new file. Finally, the new .sddraft file is analyzed for errors using the AnalyzeForSD function.

import arcpy
import xml.dom.minidom as DOM 
# the new TextAntiAliasingMode value
newTextAntialiasingMode = 'Normal'
xml = r"C:\Project\Counties.sddraft"
doc = DOM.parse(xml)
keys = doc.getElementsByTagName('Key')
for key in keys:
    if key.hasChildNodes():
        if key.firstChild.data == 'textAntialiasingMode':
	    # modify the TextAntiAliasingMode value
	    key.nextSibling.firstChild.data = newTextAntialiasingMode
			
# output to a new sddraft
outXml = r"C:\Project\Output\CountiesForWeb.sddraft"     
f = open(outXml, 'w')     
doc.writexml( f )     
f.close()

# analyze the new sddraft for errors
analysis = arcpy.mapping.AnalyzeForSD(outXml)
for key in ('messages', 'warnings', 'errors'):
    print "----" + key.upper() + "---"
    vars = analysis[key]
    for ((message, code), layerlist) in vars.iteritems():
        print "    ", message, " (CODE %i)" % code
        print "       applies to:",
        for layer in layerlist:
            print layer.name,
        print
Modify SDDraft example 3

The following sample script creates a Service Definition Draft (.sddraft) file from a Map Document (.mxd). It then enables WMSServer capabilities and sets the Title property by modifying the .sddraft file using the xml.dom.minidom standard Python library. The modified .sddraft file is then saved to a new file. Finally, the new .sddraft file is analyzed for errors using the AnalyzeForSD function.

import arcpy
import xml.dom.minidom as DOM 

# Reference map document for CreateSDDraft function.
mapDoc = arcpy.mapping.MapDocument('C:/project/counties.mxd') 
# Create service and sddraft variables for CreateSDDraft function.
service = 'Counties'
sddraft = 'C:/Project/' + service + r'.sddraft'
  
# Create sddraft.
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER')

# These are the properties we will change in the sddraft xml.
soe = 'WMSServer'
soeProperty = 'title'
soePropertyValue = 'USACounties'

# Read the sddraft xml.
doc = DOM.parse(sddraft)
# 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 whose properties we want to modify.
    if typeName.firstChild.data == soe:
        extension = typeName.parentNode
        for extElement in extension.childNodes:
            # Enabled SOE.
            if extElement.tagName == 'Enabled':
                extElement.firstChild.data = 'true'
            # Modify SOE property. We have to drill down to the relevant property.
            if extElement.tagName == 'Props':
                for propArray in extElement.childNodes:
                    for propSet in propArray.childNodes:
                        for prop in propSet.childNodes:
                            if prop.tagName == "Key":
                                if prop.firstChild.data == soeProperty:
                                    if prop.nextSibling.hasChildNodes():
                                        prop.nextSibling.firstChild.data = soePropertyValue
                                    else:
                                        txt = doc.createTextNode(soePropertyValue)
                                        prop.nextSibling.appendChild(txt)
                                        
# Output to a new sddraft.
outXml = "C:/Project/Output/CountiesForWeb.sddraft"     
f = open(outXml, 'w')     
doc.writexml( f )     
f.close()       

# Analyze the new sddraft for errors.
analysis = arcpy.mapping.AnalyzeForSD(outXml)
for key in ('messages', 'warnings', 'errors'):
    print "----" + key.upper() + "---"
    vars = analysis[key]
    for ((message, code), layerlist) in vars.iteritems():
        print "    ", message, " (CODE %i)" % code
        print "       applies to:",
        for layer in layerlist:
            print layer.name,
        print
Modify SDDraft example 4

The following sample script creates a Service Definition Draft (.sddraft) file from a Map Document (.mxd). It then disables KmlServer capabilities by modifying the .sddraft file using the xml.dom.minidom standard Python library. The modified .sddraft file is then saved to a new file. Finally, the new .sddraft file is analyzed for errors using the AnalyzeForSD function.

import arcpy
import xml.dom.minidom as DOM 

# Reference map document for CreateSDDraft function.
mapDoc = arcpy.mapping.MapDocument('C:/project/counties.mxd')
# Create service and sddraft variables for CreateSDDraft function.
service = 'Counties'
sddraft = 'C:/Project/' + service + '.sddraft'
 
# Create sddraft.
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER')

# The Server Object Extension (SOE) to disable.
soe = 'KmlServer'

# Read the sddraft xml.
doc = DOM.parse(sddraft)
# 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 we want to disable.
    if typeName.firstChild.data == soe:
        extension = typeName.parentNode
        for extElement in extension.childNodes:
            # Disabled SOE.
            if extElement.tagName == 'Enabled':
                extElement.firstChild.data = 'false'
                                        
# Output to a new sddraft.
outXml = "C:/Project/Output/CountiesForWeb.sddraft"     
f = open(outXml, 'w')     
doc.writexml( f )     
f.close()       

# Analyze the new sddraft for errors.
analysis = arcpy.mapping.AnalyzeForSD(outXml)
for key in ('messages', 'warnings', 'errors'):
    print "----" + key.upper() + "---"
    vars = analysis[key]
    for ((message, code), layerlist) in vars.iteritems():
        print "    ", message, " (CODE %i)" % code
        print "       applies to:",
        for layer in layerlist:
            print layer.name,
        print
Modify SDDraft example 5

The following sample script creates a Service Definition Draft (.sddraft) file for the ARCGIS_SERVER server_type from a Map Document (.mxd). It then enables caching on the service by modifying the .sddraft file using the xml.dom.minidom standard Python library. The modified .sddraft file is then saved to a new file. Finally, the new .sddraft file is analyzed for errors using the AnalyzeForSD function.

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

# define local variables
wrkspc = 'C:/Project/'
mapDoc = arcpy.mapping.MapDocument(wrkspc + 'counties.mxd')
con = 'GIS Servers\arcgis on MyServer_6080 (admin).ags' 
service = 'Counties'
sddraft = wrkspc + service + '.sddraft'
sd = os.path.join(wrkspc, "output", service + '.sd')

# create sddraft
if os.path.exists(sddraft): os.remove(sddraft)
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER')

# read sddraft xml
doc = DOM.parse(sddraft)

# turn on caching in the configuration properties
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":
                # turn on caching
                keyValue.nextSibling.firstChild.data = "true"
                
# output to a new sddraft
outXml = "C:\Project\Output\CountiesForWeb.sddraft"   
if os.path.exists(outXml): os.remove(outXml)
f = open(outXml, 'w')     
doc.writexml( f )     
f.close() 

# analyze new sddraft for errors
analysis = arcpy.mapping.AnalyzeForSD(outXml)

# print dictionary of messages, warnings and errors
for key in ('messages', 'warnings', 'errors'):
    print "----" + key.upper() + "---"
    vars = analysis[key]
    for ((message, code), layerlist) in vars.iteritems():
        print "    ", message, " (CODE %i)" % code
        print "       applies to:",
        for layer in layerlist:
            print layer.name,
        print

del f, doc, mapDoc
Modify SDDraft example 6

The following sample script creates a Service Definition Draft (.sddraft) file for the ARCGIS_SERVER server_type from a Map Document (.mxd). It then enables caching on the service by modifying the .sddraft file using the xml.dom.minidom standard Python library. The modified .sddraft file is then saved to a new file. Next, the new .sddraft file is analyzed for errors using the AnalyzeForSD function. After analyzing the service definition draft, it is time to stage the service definition. Use the Stage Service geoprocessing tool to stage the service definition. Then use the Upload Service Definition geoprocessing tool to upload the service definition to the server and publish the map service. Once the service has been published, the script then calls the Manage Map Server Cache Scales geoprocessing tool which updates the scale levels in an existing cached map or image service. Use this tool to add new scales or delete existing scales from a cache. Finally, the script calls the Manage Map Server Cache Tiles geoprocessing tool to create map service cache tiles.

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

# define local variables
wrkspc = 'C:/Project'
systemFolder = 'C:/Users/<username>/AppData/Roaming/ESRI/Desktop10.2/ArcCatalog'
server = 'arcgis on MyServer_6080 (publisher)'
service = 'Counties'

# build paths to data
mapDoc = arcpy.mapping.MapDocument(os.path.join(wrkspc, 'counties.mxd'))
connection = os.path.join(systemFolder, server + '.ags')
mapServer = os.path.join(systemFolder, server, service + '.MapServer')
sddraft = os.path.join(wrkspc, service + '.sddraft')
sd = os.path.join(wrkspc, 'output', service + '.sd')

# create sddraft
if os.path.exists(sddraft): os.remove(sddraft)
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'ARCGIS_SERVER')

# read sddraft xml
doc = DOM.parse(sddraft)

# turn on caching in the configuration properties
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":
                # turn on caching
                keyValue.nextSibling.firstChild.data = "true"
                
# output to a new sddraft
outXml = os.path.join(wrkspc, 'output', service + '.sddraft')   
if os.path.exists(outXml): os.remove(outXml)
f = open(outXml, 'w')     
doc.writexml( f )     
f.close() 

# analyze new sddraft for errors
analysis = arcpy.mapping.AnalyzeForSD(outXml)

# print dictionary of messages, warnings and errors
for key in ('messages', 'warnings', 'errors'):
    print "----" + key.upper() + "---"
    vars = analysis[key]
    for ((message, code), layerlist) in vars.iteritems():
        print "    ", message, " (CODE %i)" % code
        print "       applies to:",
        for layer in layerlist:
            print layer.name,
        print

# stage and upload the service if the sddraft analysis did not contain errors
if analysis['errors'] == {}:
    # Execute StageService
    if os.path.exists(sd): os.remove(sd)
    arcpy.StageService_server(outXml, sd)
    # Execute UploadServiceDefinition
    print "Uploading Service Definition..."
    arcpy.UploadServiceDefinition_server(sd, connection)
    # Print messaging from UploadServiceDefinition
    x = 0
    while x < arcpy.GetMessageCount():
        arcpy.AddReturnMessage(x)
        x = x + 1
else: 
    print "{} contained errors. StageService and UploadServiceDefinition aborted.".format(sddraft)
    exit()
    
print "Updating cache scales..."
scaleValues = "100000000;10000000;5000000;1000000;500000;250000;125000;64000;5250"
arcpy.ManageMapServerCacheScales_server(mapServer, scaleValues)

print "Creating tiles..."
arcpy.ManageMapServerCacheTiles_server(mapServer, "100000000", "RECREATE_ALL_TILES", "3")

print "Uploaded service and created tiles."
Modify SDDraft example 7

The following sample script shows how to update an existing feature service that is hosted on ArcGIS Online. For example, an organization may want to push updates to keep synchronized with the daily changes made by its ArcGIS for Desktop users. This sample script will demonstrate how to:

  • Turn a map document into an .sddraft file.
  • Modify the XML inside with the appropriate settings.
  • Analyze the .sddraft file for errors.
  • Stage the .sddraft file into an .sd (service definition) file.
  • Upload the service to ArcGIS Online. Note that this code shares the feature service with everyone on ArcGIS Online.

Update the variables with your path to the MXD file. The script will create temporary drafts in the same location in which the script is saved. ArcGIS Online sign in information is obtained from the File > Sign In dialog box on the ArcGIS for Desktop main menu.

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

arcpy.env.overwriteOutput = True

# Update these variables
# The tempPath variable is a relative path which is the same directory
# this script is saved to. You can modify this value to a path on your
# system to hold the temporary files.
serviceName = "importantPoints"
tempPath = sys.path[0]
path2MXD = r"C:\path2MXD\pts.mxd"

# All paths are built by joining names to the tempPath
SDdraft = os.path.join(tempPath, "tempdraft.sddraft")
newSDdraft = os.path.join(tempPath, "updatedDraft.sddraft")
SD = os.path.join(tempPath, serviceName + ".sd")

mxd = arcpy.mapping.MapDocument(path2MXD)
arcpy.mapping.CreateMapSDDraft(mxd, SDdraft, serviceName, "MY_HOSTED_SERVICES")

# Read the contents of the original SDDraft into an xml parser
doc = DOM.parse(SDdraft)

# The follow 5 code pieces modify the SDDraft from a new MapService
# with caching capabilities to a FeatureService with Query,Create,
# Update,Delete,Uploads,Editing capabilities. The first two code
# pieces handle overwriting an existing service. The last three pieces
# change Map to Feature Service, disable caching and set appropriate
# capabilities. You can customize the capabilities by removing items.
# Note you cannot disable Query from a Feature Service.
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"

# Change service type from map service to feature service
typeNames = doc.getElementsByTagName('TypeName')
for typeName in typeNames:
    if typeName.firstChild.data == "MapServer":
        typeName.firstChild.data = "FeatureServer"

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

# Turn on 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 = "Query,Create,Update,Delete,Uploads,Editing"

# Write the new draft to disk
f = open(newSDdraft, 'w')
doc.writexml( f )
f.close()

# Analyze the service
analysis = arcpy.mapping.AnalyzeForSD(newSDdraft)

if analysis['errors'] == {}:
    # Stage the service
    arcpy.StageService_server(newSDdraft, SD)

    # Upload the service. The OVERRIDE_DEFINITION parameter allows you to override the
    # sharing properties set in the service definition with new values. In this case,
    # the feature service will be shared to everyone on ArcGIS.com by specifying the
    # SHARE_ONLINE and PUBLIC parameters. Optionally you can share to specific groups
    # using the last parameter, in_groups.
    arcpy.UploadServiceDefinition_server(SD, "My Hosted Services", serviceName,
                                         "", "", "", "", "OVERRIDE_DEFINITION", "SHARE_ONLINE",
                                         "PUBLIC", "SHARE_ORGANIZATION", "")

    print "Uploaded and overwrote service"

else:
    # If the sddraft analysis contained errors, display them and quit.
    print analysis['errors']
3/3/2014