AnsweredAssumed Answered

Can arcpy publish / update web scene layer with associated feature layer (and service definition layer) ?

Question asked by FrancisBase on Jul 12, 2020
Latest reply on Jul 13, 2020 by FrancisBase

So after many attempts of trying with arcpy what is straightforward to do with ArcGIS Pro GUI:

share a 3D Scene's Feature Layer (containing 3DObjects or Multipatch) as an AGOL scene layer with associated feature layer (and of course service definition) would like to know what are the current workflows.

In the GUI is simply right click in the contents pane, in the feature layer > share > as web layer (it generates the correspondent feature, scene and service definition)

Have tried this although either with arcpy.mp.ArcGISProject(str_prjflPath).listMaps()[0].getWebLayerSharingDraft  and with the deprecated arcpy.mp.CreateWebLayerSDDraft it only publishes Feature Layers (and not the associated scene layer, as the ArcGIS Pro "Share to Web Layer" does):

Basically adapted the last part of the code here: Automate overwrite web layer, feature class with upload of service definition, and the special use case of publishing a feature layer with associated scene layer.

 

import arcpy
import os, sys

### Start setting variables
# Set the path to the project
prjPath = r"D:\testing#2\tests2.aprx"

# Update the following variables to match:
# Feature service/SD name in arcgis.com, user/password of the owner account
sd_fs_name = "MyPublicMap"
portal = "http://www.arcgis.com" # Can also reference a local portal
user = "username"
password = "password"

# Set sharing options
shrOrg = False
shrEveryone = False
shrGroups = ""

### End setting variables

# Local paths to create temporary content
relPath = os.path.dirname(prjPath)
sddraft = os.path.join(relPath, "WebUpdate.sddraft")
sd = os.path.join(relPath, "WebUpdate.sd")

# Create a new SDDraft and stage to SD
print("Creating SD file")
arcpy.env.overwriteOutput = True
prj = arcpy.mp.ArcGISProject(prjPath)
mp = prj.listMaps()[1]
arcpy.mp.CreateWebLayerSDDraft(mp, sddraft, sd_fs_name, 'MY_HOSTED_SERVICES',
'FEATURE_ACCESS','', True, True)
arcpy.StageService_server(sddraft, sd)
arcpy.UploadServiceDefinition_server(
in_sd_file=sd,
in_server="My Hosted Services",
#in_service_name #already specified in service definition
#in_cluster
#in_folder_type #already specified in service definition
#in_folder #already specified in service definition
in_startupType='STARTED',
#sharing configurations overriding default (only owner level access)
in_override='OVERRIDE_DEFINITION', #default False
in_my_contents='SHARE_ONLINE', #default 'SHARE_ONLINE' make it accessible from All My Content
in_public='PRIVATE', #default PRIVATE do not make it shared with everyone
in_organization='NO_SHARE_ORGANIZATION', #default 'NO_SHARE_ORGANIZATION'
in_groups='' #default '', for multiple use string list of groups for example
)

 

Now using the more recent getWebLayerSharingDraft method of arcgis pro map object.

Functionality:

  1. Create an ArcGIS Pro map python object with arcpy.mp.ArcGISProject('<str_path_aproject>').
  2. Create the desired arcgis pro map layers list object using .listMaps() method of arcgis pro project python object, and .listLayers method of arcgispro map python object.
  3. Arcpy Sign in to either AGOL or ArcGIS Enterprise Portal (access and credentials)
  4. Create a sharing draft python object and set service properties.
  5. Create a Service definition draft (.sddraft file) using .exportToSDDraft('<str_filename>). method of sharing draft object.
  6. Create a service definition (.sd file) with arcpy's .StageService_server() method representing the Stage tool which analyses drafts for suitability and sources of potential performance issues.
  7. Finally, upload the service definition to AGOL or ArcGIS Enterprise portal as a GIS service with arcpy's .UploadServiceDefinition_server() method representing the Upload Service Definition tool.
    Independently of asynchronous tasks like upload service being done which can be made in multiprocessing as recomendation algorithm waits for objects to complete e.g. upload service for continue basics.

If possible use this as reference:

def share_weblayer(
                    str_prjflPath,
                    str_servicename
                    ):
    #import libs
    import arcpy
    import os
    import shutil
    import sys
    from arcgis.gis import GIS
    #
    #variables
    str_servicename=str_servicename.replace('-','')
   
    #i) Create an ArcGIS Pro map python object with arcpy.mp.ArcGISProject('<str_path_aproject>').
    aprj_working = arcpy.mp.ArcGISProject(str_prjflPath)
    #
    #ii) Create the desired arcgis pro map layers list object using .listMaps() .listLayers methods repectively of arcgispro project and of map objects.
    lst_amaps = aprj_working.listMaps()
    amap_working=lst_amaps[0]
    lst_alyrs=amap_working.listLayers()
    #
    #iii) Arcpy Sign in to either AGOL or ArcGIS Enterprise Portal (access and credentials) if necessary
    str_portal="https://www.arcgis.com"
    str_user="user"
    str_password="password"
    arcpy.SignInToPortal(str_portal, str_user, str_password)
    #
    #iv) Create a sharing draft featuresharingdraft arcpy object
    sdraft_working=amap_working.getWebLayerSharingDraft(
                                                            #server_type
                                                            server_type="HOSTING_SERVER",
                                                            #service_type
                                                            service_type="FEATURE",
                                                            #service_name
                                                            service_name=str_servicename,
                                                            #layers_and_tables=None defaults #filter the Layers and Tables to show
                                                            #note that only the 'MapView' layers and tables that belong to default geodatabase are available
                                                            layers_and_tables=lst_alyrs
    )
    #set properties of FeatureSharingDraft class instance (and also representing a type)
    sdraft_working.allowExporting=False
    sdraft_working.credits = "user"
    sdraft_working.description = "My Description"
    sdraft_working.offline = True
    sdraft_working.overwriteExistingService =True
    sdraft_working.portalFolder = "example"
    sdraft_working.serverType="HOSTING_SERVER"
    sdraft_working.serviceName=str_servicename
    sdraft_working.summary = "My Summary"
    sdraft_working.tags = "My Tags"
    sdraft_working.useLimitations = "My Use Limitations"
    #
    #v) Create a Service definition draft (.sddraft file)
    str_dir=os.path.join(os.path.dirname(str_prjflPath),'folder_output')
    str_sddraftflname=str_servicename+".sddraft"
    str_sddraftfullpath=os.path.join(str_dir,str_sddraftflname)
    if not os.path.isdir(str_dir):
        os.makedirs(str_dir)
    elif os.path.isfile(str_sddraftfullpath):
        os.remove(str_sddraftfullpath)
    sdraft_working.exportToSDDraft(str_sddraftfullpath)
    #
    #vi) Create a service definition (.sd file)
    str_sdflname=str_servicename+".sd"
    str_sdfullpath=os.path.join(str_dir,str_sdflname)
    if os.path.isfile(str_sdfullpath):
        os.remove(str_sdfullpath)
    arcpy.StageService_server(str_sddraftfullpath, str_sdfullpath)
    #
    #vii) Finally, upload the service definition to AGOL or ArcGIS Enterprise portal
    #report the asynchcronous task (eventually use threads, or even better multiprocessing for this)
    display("Uploading Service Definition...")
    arcpy.UploadServiceDefinition_server(
                                            in_sd_file=str_sdfullpath,
                                            in_server="My Hosted Services",
                                            #in_service_name #already specified in service definition
                                            #in_cluster
                                            #in_folder_type #already specified in service definition
                                            #in_folder #already specified in service definition
                                            in_startupType='STARTED',
                                            #sharing configurations overriding default (only owner level access)
                                            in_override='OVERRIDE_DEFINITION', #default False
                                            in_my_contents='SHARE_ONLINE', #default 'SHARE_ONLINE' make it accessible from All My Content
                                            in_public='PRIVATE',           #default PRIVATE do not make it shared with everyone
                                            in_organization='NO_SHARE_ORGANIZATION', #default 'NO_SHARE_ORGANIZATION'
                                            in_groups=''                   #default '', for multiple use string list of groups for example
    )
    print("SUCCESS: Uploaded service definition.")

share_weblayer(
                str_prjflPath=r"path_to_aprxfile",
                str_servicename=r'example_service'
                )

So if anyone knows how to do it ideas are welcome in advance.

Outcomes