ArcGIS Desktop’s ArcPy package gives us the ability to publish a map service from a map document (MXD) inside Python. This can be very helpful for migrations, backups, and maintenance activities such as changing layers/symbology and overwriting the existing service. Wait a sec, there isn’t an option to overwrite when using the GP Tool in Python… or is there.

Publish a map service with Python

Before we overwrite a map service, let’s start with the basics of publishing an MXD to a new service with Python. The code here is based on Esri’s online help sample. This will require an existing ArcGIS Server connection file (.ags) created in ArcCatalog.

import arcpy, os
cwd = os.getcwd()
# Setup main variables
agsCon = cwd + os.sep + "AGS_Publish_Connection.ags"
agsDirectoryName = "ServiceDirectory"
agsServiceName = "ServiceName"
mapDoc = arcpy.mapping.MapDocument(cwd + os.sep + "helloWorld.mxd")

# Setup Service Details
sddraft = cwd + os.sep + agsServiceName + '.sddraft'
sd = cwd + os.sep + agsServiceName + '.sd'
# Create service definition draft
arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, agsServiceName, 'ARCGIS_SERVER', None, True, agsDirectoryName, None, None)
# Analyze the service definition draft
analysis = arcpy.mapping.AnalyzeForSD(sddraft)

# Stage and upload the service if the sddraft analysis did not contain errors
if sdAnalyze['errors'] == {}:
    # Execute StageService to create the service definition
    arcpy.StageService_server(sddraft, sd)
    # Execute UploadServiceDefinition to upload the service definition and publishes the service
    arcpy.UploadServiceDefinition_server(sd, agsCon)
    print "Service Published"
else: 
    # if the sddraft analysis contained errors, display them
    print analysis['errors']

Overwrite an existing service with Python

Once we have the map service published, a few tweaks can add the ability to overwrite. The trick here is to open the .sddraft file before we stage and upload the service. It’s inside this file where a specific element can be modified to allow for overwriting a service. Thankfully the sddraft file is really just an XML file rebranded with a different extension. A few online community members provide solutions by going the extra mile and use Python XML modules (minidom, ElementTree) to modify the XML data. This is a much more robust approach, especially if you want to modify other values of the XML/sddraft file. You can see an example of the XML module approach in the Helpful Links section at the end if interested.

In our example, we just want to overwrite an existing service so an XML module won’t be needed. We just need to replace the service type Esri constant esriServiceDefinitionType_New value inside the XML with the overwrite constant esriServiceDefinitionType_Replacement. We can leverage Python’s String replace() method as this constant is a unique value.

## Change the SDDraft to overwrite existing service
# Read the file
with open(sddraft, 'r') as file:
    filedata = file.read()
# Replace the target string
filedata = filedata.replace('esriServiceDefinitionType_New', 'esriServiceDefinitionType_Replacement')
# Write the file out again
with open(sddraft, 'w') as file:
    file.write(filedata)

The code above should be inserted into the main script after creating the sddraft file. You could also place it directly before creating the staging service (arcpy.StageService_server) as it is only needed if there are no errors during the analysis review. I should also mention that this isn’t offically supported - so remember to test, test, test.

Tips and Tricks

  • I was receiving some Python errors when running this script with Python 64-bit. The StageService_server (10.7) not liking the 64-bit version. Both 32-bit and 64-bit could be installed by ArcGIS (32-bit installed with ArcGIS, 64-bit installed with Background Geoprocessing). Everything did work fine when making sure to use Python 32-bit.

  • As previously mentioned, the sddraft file is really just an XML file. If you rename to XML, you can open in Excel/NPP to checkout some of the other interesting elements. If wanting to modify more values it’s recommended to use an XML module for greater support and functionality.

  • What about the SD file, is it an XML file too? Nope, the the .sd file is actually just a renamed .7z extension. If you have a copy of 7-zip (Open Source), you can rename to .7z and extract the contents of the SD to see what’s inside this file as well. This compressed file can also include data if it needs to pass it to the server which is why it can get pretty big.

Helpful Links