How to publish a feature service to ArcGIS Online from an mxd USING PYTHON?

23525
44
Jump to solution
03-25-2013 07:06 PM
BenoitMetzger
New Contributor II
Hi All,

I would like to automate publishing feature services - from an mxd using Python to my AG Online account.

I did this successfully manually using the menu: Share as -> Service, Publish a service - Feature Access Capabilities etc...

Using Python, I managed to publish the service definition file on AG Online using:
arcpy.mapping.CreateMapSDDraft()
arcpy.mapping.AnalyzeForSD()
arcpy.StageService_server()
arcpy.UploadServiceDefinition_server()

But I could not find a way to publish a feature service to AG Online! I must be missing something. Any help would be really appreciated.

Thanks in advance!
Tags (2)
1 Solution

Accepted Solutions
JeffMoulds
Esri Contributor
The following code will publish a hosted feature service. Change the following:

- Line 5, the workspace
- Line 11, the name you want to give the service
- Line 58, the username and password to your AGO account

import arcpy import xml.dom.minidom as DOM  import os  workspace = 'C:/Temp/hosted publishing/'  # Reference map document for CreateSDDraft function. mapDoc = arcpy.mapping.MapDocument(r'C:\Temp\betty4.mxd') # Create service and sddraft variables for CreateSDDraft function. sddraft = workspace + 'HostedMS.sddraft' service = 'FeatureService' arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'MY_HOSTED_SERVICES', summary="test", tags='test') con = 'My Hosted Services' sd = workspace + service + '.sd'  doc = DOM.parse(sddraft)  # Read the sddraft xml. doc = DOM.parse(sddraft) # Change service from map service to feature service typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames:     # Get the TypeName we want to disable.     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":                 # turn on caching                 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":                 # turn on caching                 keyValue.nextSibling.firstChild.data = "Query,Create,Update,Delete,Uploads,Editing"  outXml = workspace + 'HostedMSNew.sddraft'  f = open(outXml, 'w')      doc.writexml( f )      f.close() analysis = arcpy.mapping.AnalyzeForSD(outXml) #print analysis #arcpy.SignOutFromPortal_server() arcpy.SignInToPortal_server("username","password","http://www.arcgis.com/") arcpy.StageService_server(outXml, sd) arcpy.UploadServiceDefinition_server(sd, con)

View solution in original post

44 Replies
JeffMoulds
Esri Contributor
The following code will publish a hosted feature service. Change the following:

- Line 5, the workspace
- Line 11, the name you want to give the service
- Line 58, the username and password to your AGO account

import arcpy import xml.dom.minidom as DOM  import os  workspace = 'C:/Temp/hosted publishing/'  # Reference map document for CreateSDDraft function. mapDoc = arcpy.mapping.MapDocument(r'C:\Temp\betty4.mxd') # Create service and sddraft variables for CreateSDDraft function. sddraft = workspace + 'HostedMS.sddraft' service = 'FeatureService' arcpy.mapping.CreateMapSDDraft(mapDoc, sddraft, service, 'MY_HOSTED_SERVICES', summary="test", tags='test') con = 'My Hosted Services' sd = workspace + service + '.sd'  doc = DOM.parse(sddraft)  # Read the sddraft xml. doc = DOM.parse(sddraft) # Change service from map service to feature service typeNames = doc.getElementsByTagName('TypeName') for typeName in typeNames:     # Get the TypeName we want to disable.     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":                 # turn on caching                 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":                 # turn on caching                 keyValue.nextSibling.firstChild.data = "Query,Create,Update,Delete,Uploads,Editing"  outXml = workspace + 'HostedMSNew.sddraft'  f = open(outXml, 'w')      doc.writexml( f )      f.close() analysis = arcpy.mapping.AnalyzeForSD(outXml) #print analysis #arcpy.SignOutFromPortal_server() arcpy.SignInToPortal_server("username","password","http://www.arcgis.com/") arcpy.StageService_server(outXml, sd) arcpy.UploadServiceDefinition_server(sd, con)
GISDepartment9
New Contributor III

Hey Jeff,

Could you please share the code in a little nicer way to look at it?

I am very new to python and I am trying to step my way through the code but I cant seem to separate it our very well since its all in a line.

Thanks 

FredKellner2
New Contributor II

Is there a way get this code in actual lines of code rather than one enormously large single line of code? I'm guessing there is a browser SNAFU. But IE, FF and Chrome are all currently displaying your response as a single line of code.

MaryEllen_Perko
Occasional Contributor II
This worked great for me!  You saved me a bunch of time. Thanks.

Now, I'm just wondering if anyone knows how to set the sharing during publishing using python.  I can see references to it in the documentation for UploadServiceDefinition_server, but I cannot figure out the syntax when it is the only optional setting you need.  And, does it work in AGOL?

Thanks,
Mary Ellen
0 Kudos
BenoitMetzger
New Contributor II
Hi Jeff,

thanks for your help, I will give that a go... but from what i read it seems to be working 🙂

Mary Helen, not too sure if thsi is what you want... here is a line i wrote which worked a little while ago (it was sharing the service on AGOL from memory):
arcpy.UploadServiceDefinition_server("C:\\...", "My Hosted Services", '', '', "NEW", "folder", "STARTED","OVERRIDE_DEFINITION", "SHARE_ONLINE","PRIVATE", "NO_SHARE_ORGANIZATION", "")

Cheers.
0 Kudos
KaushalShah
New Contributor
Hi, I have manually created/published the ArcGIS online feature service from arcmap as a one time activity.
The data in the mxd will keep on changing and I have updated the data in the mxd.
Since the data is changing, each time I will have to update the already published feature service. Manually we can publishing the service and select overwrite existing service. The same I want to automatize through python script.

As the script for creating new feature service and also sharing the feature service was provided in the thread, can you please urgently help me by providing the python script for updating the data of the existing feature service. We do not have to change service definition of the already published feature service.

Urgent help would be appreciated.

Thanks and regards,
Kaushal Shah.
0 Kudos
KevinHibma
Esri Regular Contributor
Add the following 2 pieces into Jeff's code and it'll allow you to use UploadService (after staging of course) on an existing service (because it overwrites the service).

typeReplace = 'esriServiceDefinitionType_Replacement'
statePublished = 'esriSDState_Published'
           
myTagsType = doc.getElementsByTagName('Type')
for myTagType in myTagsType:
    if myTagType.parentNode.tagName == 'SVCManifest':
        if myTagType.hasChildNodes():
            myTagType.firstChild.data = typeReplace

myTagsState = doc.getElementsByTagName('State')
for myTagState in myTagsState:
    if myTagState.parentNode.tagName == 'SVCManifest':
        if myTagState.hasChildNodes():
            myTagState.firstChild.data = statePublished
0 Kudos
KaushalShah
New Contributor
Thanks a ton for the help. This helped me overwrite the existing feature service without deleting it manually. I am saved.

But here I believe that we had to add the new part of the code that you provided BEFORE the staging of the service definition and not after the line arcpy.StageService_server(outXml, sd). You mentioned otherwise. So the new code comes before the "outXml = workspace + 'HostedMSNew.sddraft' of the main code.

Can you also help me provide an insight on the map service being overwritten. If we have already created the Map using the original feature service, and then overwrite the existing feature service, will the previous maps work with the same shared url. Hope I am clear in my requirement.

Lots of Regards,
Kaushal Shah.
0 Kudos
TiagoRibeiro
Occasional Contributor
I've been following this thread, which has helped me a lot, so let me start with a big THANK YOU! I already have a script that updates my  feature service but... this needs the desktop installed to run right?
For example: If you publish this as gp task on ArcGIS for Server the upload part will throw this error:
ExecuteError: Failed to execute. Parameters are not valid.
ERROR 000732: Server: Dataset My Hosted Services does not exist or is not supported
Failed to execute (UploadServiceDefinition).

Is there a way around this or the way is to have ArcGIS For Desktop installed, and the "ArcGISConnection.exe" process running?
0 Kudos