Publishing map to ArcGIS Server (10.6+) with Python - Conundrum!

3757
7
02-04-2019 03:28 PM
Arne_Gelfert
Occasional Contributor III

Hey all,

I'm caught in ESRI's library-name-change-and-circularly-referencing-documentation hell.

I have a number of MXD's that were the basis for a number ArcGIS map services in a 10.5.x standalone ArcGIS Server environment. I would like to publish these in a new federated ArcGIS Server environment (ArcGIS Enterprise).
How do I script that? Seems like that should be easy.

The older documentation suggests the following steps, which ring familiar... (CreateMapSDDraft—Help | ArcGIS Desktop )

arcpy.mapping.MapDocument( )
arcpy.mapping.CreateMapSDDraft( )
arcpy.StageService_server( )
arcpy.UploadServiceDefinition_server( )

But it turns out I don't have 'arcpy.mapping' module anymore.

AttributeError: module 'arcpy' has no attribute 'mapping'

Where did it go? It's been replaced with arc.mp. Huge semantic improvement!! But it's not like that's just a new name:

AttributeError: module 'arcpy.mp' has no attribute 'CreateMapSDDraft'

Well, publishing from MXD is no longer cool anyways. ESRI apparently wants you to live in the APRX world. So I "converted" an MXD to APRX to try another approach.


You'd think now you could use the following (CreateSharingDraft—Sharing module | ArcGIS Desktop 😞

CreateSharingDraft - function
"The CreateSharingDraft function creates a MapServiceDraft from a Map in an ArcGIS Pro project that can be configured and shared to ArcGIS Server."

service_draft = arcpy.sharing.CreateSharingDraft( )
service_draft.exportToSDDraft( )
arcpy.StageService_server( )
arcpy.UploadServiceDefinition_server( )

No! 

AttributeError: module 'arcpy.sharing' has no attribute 'CreateSharingDraft'
What the heck???
sharing_draft = m.getWebLayerSharingDraft( )
sharing_draft.exportToSDDraft( )
arcpy.StageService_server( )
arcpy.UploadServiceDefinition_server( )

Using these steps, the code fails at

sharing_draft = m.getWebLayerSharingDraft("FEDERATED_SERVER", "MAP_IMAGE", service)
sharing_draft.exportToSDDraft(sddraft_output_filename)

ValueError: MAP_IMAGE

Is it possible that I've missed the one page in the documentation that makes sense? Please let me know. All I want to do is iterate over some directories with MXD files and publish them as map services.

UPDATE: I had a hunch that with multiple ESRI associated Python installs, one might offer the old arc.mapping. So looks like ArcMap's old Py2.7 still has it. Didn't think about that earlier because I'm working almost exclusively in Jupyter Notebook. Whether this is of much help, I don't know. Can't imagine going back and forth between releases.

0 Kudos
7 Replies
Arne_Gelfert
Occasional Contributor III

Ok, so after working on this here post about recycling MXD for publishing with Pro, I've revisited the publishing script and found that the sample given here works on my end after all. Here is my slightly revised version.

import arcpy
import os

# Set output file names
outdir = r"C:\temp"
service = "MyServiceName"  # -- this in my case would be same/similar to name below called <This_is_the_name_of_maplayer>
sddraft_filename = service + ".sddraft"
sddraft_output_filename = os.path.join(outdir, sddraft_filename)

my_federated_server = "https://server.domain.com/webadaptor"

# Reference map to publish
aprx = arcpy.mp.ArcGISProject(<path_aprx_with_maps>)
m = aprx.listMaps(<This_is_the_name_of_maplayer>)[0]

# Create MapImageSharingDraft and set service properties
sharing_draft = m.getWebLayerSharingDraft("FEDERATED_SERVER", "MAP_IMAGE", service)
# The following will be good practice definitely
# But I ignored it for this test
#sharing_draft.federatedServerUrl = my_federated_server 
#sharing_draft.summary = "My Summary"
#sharing_draft.tags = "My Tags"
#sharing_draft.description = "My Description"
#sharing_draft.credits = "My Credits"
#sharing_draft.useLimitations = "My Use Limitations"

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

# Stage Service
sd_filename = service + ".sd"
sd_output_filename = os.path.join(outdir, sd_filename)
arcpy.StageService_server(sddraft_output_filename, sd_output_filename)

# Share to portal
print("Uploading Service Definition...")
arcpy.UploadServiceDefinition_server(sd_output_filename, my_federated_server )

print("Successfully Uploaded service.")‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
EarlMedina
Esri Regular Contributor

If you need to publish MXDs directly, then this documentation should still be valid: Example: Publish a map service from a map document (MXD)—ArcGIS Server Administration (Windows) | Ar... 

0 Kudos
Arne_Gelfert
Occasional Contributor III

Thanks, Earl.... if you saw my initial post you noticed I was trying to work with one version of arcpy, and mine only had arcpy.mp, which doesn't work quite the same way. I did get it to work in the older version running in Python 2.7. All in all, I was really trying an ArcGIS Pro centric approach. Getting used to working with APRX instead of MXD. Thanksa for chiming in though.

GNOMICAdmin
New Contributor III

Hi - I get an error on line 28 (exportToSDDraft) on my setup saying "missing target server" - there is no place to set the target server - we have both a  /server site and a /image federated with our portal. Can see why code above is confused - nothing is setting which server to publish too - ideas?

0 Kudos
StephenPatterson1
New Contributor II

I was just reviewing documentation for these same issues and noticed that the CreateSharingDraft(CreateSharingDraft—Sharing module | ArcGIS Desktop ) example shows how you set targetServer on the service draft object. Maybe that will help you out with that error. 

0 Kudos
GNOMICAdmin
New Contributor III

that example is for a standalone server - one that is not federated with Portal. So when I run that it complains that the target server is not a standalone server - which is correct - its federated with portal. And yet when I use the federated option above I get the missing target server error. So either way I get an error that something is missing.

So now I need to figure out what i'm missing 😞 

0 Kudos
GNOMICAdmin
New Contributor III

the missing link was to un-comment this line 

sharing_draft.federatedServerUrl = my_federated_server
0 Kudos