Hi, trying to use arcpy to publish and overwrite a service that has the WMS capability enabled. Federated Server/Portal 10.8.1. Code below isn't my full code, but I think I've reduced it down to what is relevant. The problem is that when the final line runs that stages the service, it does an analyse and throws and error:
ERROR 001272: Analyzer errors were encountered ([{"code":"00297","message":"WMS layers must be shared with everyone","object":"MyServiceName"}]).
We used to have this working with 10.7 and with ArcMap's arcpy, but this is trying to use a Pro 2.7 map. Not sure how to set sharing public before the arcpy.UploadServiceDefinition_server. The service is already published and both the regular map service and WMS items are already shared public.
Solved! Go to Solution.
@JoeRogan , @TWickiSLU I think this issue has been resolved with the release of ArcGIS Pro 3.2. See the release notes and details of BUG-00159853.
Please correct me if I am wrong and this post is a slight different issue.
An enhancement was logged for this issue, noted below:
ENH-000142251: Include a sharing capability parameter in the StageService_server() function in Arcpy.
The workaround is to leverage the Python API or the REST API directly (via requests module) to update the service to enable WMS capabilities AFTER it has been published via ArcPy, using the edit() method on the Python API's service class, found here: https://developers.arcgis.com/python/api-reference/arcgis.gis.server.html#arcgis.gis.server.Service....
For this to be possible, the JSON dictionary of the edits must contain all properties for the service. The easiest way to do this initially is to make this change manually in the Server Manager on the server site, and capture the edit operation made to the service. The JSON will look something like this:
{
"serviceName": "20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png",
"type": "MapServer",
"description": "",
"capabilities": "Map,Query,Data",
"provider": "DMaps",
"clusterName": "default",
"minInstancesPerNode": 0,
"maxInstancesPerNode": 0,
"instancesPerContainer": "1",
"maxWaitTime": "60",
"maxStartupTime": 300,
"maxIdleTime": "1800",
"maxUsageTime": "600",
"loadBalancing": "ROUND_ROBIN",
"isolationLevel": "HIGH",
"configuredState": "STOPPED",
"recycleInterval": "24",
"recycleStartTime": "00:00",
"keepAliveInterval": 1800,
"private": false,
"isDefault": false,
"maxUploadFileSize": 0,
"allowedUploadFileTypes": "",
"properties": {
"maxDomainCodeCount": "25000",
"cacheDir": "C:\\arcgis\\arcgisserver\\directories\\arcgiscache",
"maxImageWidth": "4096",
"maxRecordCount": "2000",
"antialiasingMode": "Fast",
"enableDynamicLayers": true,
"dynamicDataWorkspaces": [],
"isCached": false,
"virtualOutputDir": "/rest/directories/arcgisoutput",
"exportTilesAllowed": "false",
"maxImageHeight": "4096",
"cacheOnDemand": false,
"minScale": "9027.9774109999998",
"schemaLockingEnabled": true,
"useLocalCacheDir": true,
"outputDir": "C:\\arcgis\\arcgisserver\\directories\\arcgisoutput",
"maxScale": "4513.9887049999998",
"filePath": "C:\\arcgis\\arcgisserver\\directories\\arcgissystem\\arcgisinput\\20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png.MapServer\\extracted\\p20\\Updated_20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png.msd",
"supportedImageReturnTypes": "URL",
"maxSampleSize": "100000",
"clientCachingAllowed": true,
"userName": "siteadmin",
"textAntialiasingMode": "Force",
"maxExportTilesCount": "100000",
"ignoreCache": false,
"maxBufferCount": "100",
"disableIdentifyRelates": false,
"portalURL": "https://site.int/portal/",
"dateFieldsTimezoneID": "",
"dateFieldsRespectsDayLightSavingTime": false,
"tilingScheme": 3,
"maxLOD": "",
"minLOD": "",
"resampling": false
},
"portalProperties": {
"isHosted": false,
"portalItems": [
{
"itemID": "2654fcc55e2442ff8dab2ac8be9b44be",
"type": "MapServer"
}
]
},
"extensions": [
{
"typeName": "ValidationServer",
"capabilities": "",
"enabled": false
},
{
"typeName": "WCSServer",
"capabilities": null,
"properties": {
"name": "20210520_Pembina_127_14302_Athabasca River Right _South_ Slope_B206_2cm_png",
"role": "",
"title": "20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png",
"defaultVersion": "2.0.1",
"abstract": "",
"keywords": "",
"fees": "",
"accessConstraints": "None",
"responsiblePerson": "",
"responsiblePosition": "",
"onlineResource": "https://site.int/server/services/20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png/MapServer/WCSServer",
"providerName": "",
"phone": "",
"fax": "",
"contactInstructions": "",
"email": "",
"address": "",
"city": "",
"province": "",
"zipcode": "",
"providerWebsite": "",
"serviceHour": "",
"country": "",
"customGetCapabilities": false,
"pathToCustomGetCapabilitiesFiles": "",
"maxImageHeight": "",
"maxImageWidth": "",
"SupportEOProfile": false
},
"enabled": false
},
{
"typeName": "WFSServer",
"capabilities": null,
"properties": {
"name": "20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png",
"appSchemaURI": "https://site.int/server/services/20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png/MapServer/WFSServer",
"role": "",
"appSchemaPrefix": "20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png",
"pathToStoredQueryFile": "",
"enableTransactions": false,
"title": "",
"abstract": "",
"keyword": "",
"fees": "",
"serviceType": "",
"serviceTypeVersion": "",
"deliveryPoint": "",
"accessConstraints": "",
"individualName": "",
"positionName": "",
"providerName": "",
"onlineResource": "https://site.int/server/services/20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png/MapServer/WFSServer",
"facsimile": "",
"phone": "",
"electronicMailAddress": "",
"contactInstructions": "",
"hourOfService": "",
"providerSite": "",
"administrativeArea": "",
"city": "",
"postalCode": "",
"country": "",
"pathToCustomGetCapabilitiesFiles": "",
"customGetCapabilities": false,
"transactionsWithoutLocks": false,
"enableDefMaxFeatures": false,
"defMaxFeaturesValue": "",
"axisOrderWFS10": "longlat",
"axisOrderWFS11": "longlat",
"axisOrderWFS20": "longlat"
},
"enabled": false
},
{
"typeName": "NAServer",
"capabilities": null,
"properties": {
"nALayerDir": "C:\\arcgis\\arcgisserver\\directories\\arcgisoutput",
"defaultOutputGeometryPrecision": "",
"defaultOutputGeometryPrecisionUnits": "esriMeters",
"saveLayerOnServerWhenError": false,
"saveLayerOnServerWhenDebugging": false,
"allowSaveLayerOnServer": true,
"ignoreNetworkLocationFields": false,
"usePortalTravelModes": false,
"licensedForAutomaticRerouting": false,
"route_MaxBarriers": "",
"route_MaxStops": "",
"route_MaxFeaturesInLineBarriers": "",
"route_MaxFeaturesInPolygonBarriers": "",
"route_AllowTimeWindows": "true",
"route_ForceHierarchyBeyondDistance": "",
"route_ForceHierarchyBeyondDistanceUnits": "esriMeters",
"oDCostMatrix_MaxBarriers": "",
"oDCostMatrix_MaxOrigins": "",
"oDCostMatrix_MaxDestinations": "",
"oDCostMatrix_MaxDestinationsToFind": "",
"oDCostMatrix_MaxFeaturesInLineBarriers": "",
"oDCostMatrix_MaxFeaturesInPolygonBarriers": "",
"oDCostMatrix_ForceHierarchyBeyondDistance": "",
"oDCostMatrix_ForceHierarchyBeyondDistanceUnits": "esriMeters",
"locationAllocation_MaxFacilities": "",
"locationAllocation_MaxFeaturesInPolygonBarriers": "",
"locationAllocation_MaxFeaturesInLineBarriers": "",
"locationAllocation_MaxBarriers": "",
"locationAllocation_MaxDemandPoints": "",
"locationAllocation_ForceHierarchyBeyondDistance": "",
"locationAllocation_ForceHierarchyBeyondDistanceUnits": "esriMeters",
"serviceArea_MaxBarriers": "",
"serviceArea_MaxBreakValue_Time": "",
"serviceArea_MaxBreakValue_TimeUnits": "esriTimeUnitsMinutes",
"serviceArea_MaxBreakValue_Length": "",
"serviceArea_MaxBreakValue_LengthUnits": "esriMeters",
"serviceArea_MaxBreakValue_Other": "",
"serviceArea_MaxFacilities": "",
"serviceArea_MaxFeaturesInPolygonBarriers": "",
"serviceArea_MaxFeaturesInLineBarriers": "",
"serviceArea_ForceHierarchyBeyondDistance": "",
"serviceArea_ForceHierarchyBeyondDistanceUnits": "esriMeters",
"serviceArea_ForceHierarchyBeyondTime": "",
"serviceArea_ForceHierarchyBeyondTimeUnits": "esriTimeUnitsSeconds",
"serviceArea_ForceHierarchyBeyondOther": "",
"vRP_MaxFeaturesInPolygonBarriers": "",
"vRP_MaxRoutes": "",
"vRP_MaxFeaturesInLineBarriers": "",
"vRP_MaxOrders": "",
"vRP_MaxBarriers": "",
"vRP_ForceHierarchyBeyondDistance": "",
"vRP_ForceHierarchyBeyondDistanceUnits": "esriMeters",
"closestFacility_MaxIncidents": "",
"closestFacility_MaxBarriers": "",
"closestFacility_MaxFacilities": "",
"closestFacility_MaxFacilitiesToFind": "",
"closestFacility_MaxFeaturesInLineBarriers": "",
"closestFacility_MaxFeaturesInPolygonBarriers": "",
"closestFacility_ForceHierarchyBeyondDistance": "",
"closestFacility_ForceHierarchyBeyondDistanceUnits": "esriMeters"
},
"enabled": false
},
{
"typeName": "VersionManagementServer",
"capabilities": "Create,Delete,VersionInfos,LockInfos,PurgeLock,StartEditing,StopEditing,StartReading,StopReading,DeleteForwardEdits,Alter,Differences,Reconcile,Conflicts,InspectConflicts,Post,RestoreRows,Diagnostics",
"enabled": false
},
{
"typeName": "NetworkDiagramServer",
"capabilities": "",
"enabled": false
},
{
"typeName": "KmlServer",
"capabilities": "SingleImage,SeparateImages,Vectors",
"properties": {
"minRefreshPeriod": "30",
"compatibilityMode": "GoogleEarth",
"imageSize": "1024",
"dpi": "96",
"endPointURL": "",
"featureLimit": "1000000",
"useDefaultSnippets": false
},
"enabled": false
},
{
"typeName": "LRServer",
"capabilities": "",
"enabled": false
},
{
"typeName": "WMSServer",
"capabilities": "GetCapabilities,GetMap,GetLegendGraphic,GetSchemaExtension,GetFeatureInfo,GetStyles",
"properties": {
"name": "WMS",
"title": "20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png",
"abstract": "",
"keyword": "",
"fees": "",
"accessConstraints": "",
"contactPerson": "",
"contactPosition": "",
"onlineResource": "https://site.int/server/services/20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png/MapServer/WMSServer",
"contactOrganization": "",
"contactVoiceTelephone": "",
"contactFacsimileTelephone": "",
"contactElectronicMailAddress": "",
"address": "",
"city": "",
"stateOrProvince": "",
"postCode": "",
"country": "",
"addressType": "",
"pathToCustomGetCapabilitiesFiles": "",
"pathToCustomSLDFile": "",
"inheritLayerNames": false,
"customGetCapabilities": false,
"reaspect": false,
"listSupportedCRS": "",
"listCustomCRS": ""
},
"enabled": true
},
{
"typeName": "UtilityNetworkServer",
"capabilities": "Trace,ValidateNetworkTopology,DisableSubnetworkController,EnableSubnetworkController,UpdateSubnetwork,ExportSubnetwork,QueryNetworkMoments,UpdateIsConnected,EnableTopology,DisableTopology,SynthesizeAssociationGeometries",
"enabled": false
},
{
"typeName": "ParcelFabricServer",
"capabilities": "Build,Merge,Clip,CopyLinesToParcelType,DeleteParcels,ChangeParcelType,DuplicateParcels,AssignFeaturesToRecord,UpdateParcelHistory,CreateSeeds,AnalyzeByLeastSquaresAdjustment,ApplyLeastSquaresAdjustment",
"enabled": false
},
{
"typeName": "FeatureServer",
"capabilities": "Create,Query,Update,Delete,Uploads,Editing",
"properties": {
"zDefaultValue": "0",
"allowOthersToDelete": false,
"allowOthersToUpdate": false,
"allowOthersToQuery": true,
"enableZDefaults": false,
"realm": "",
"editorTrackingTimeInUTC": "true",
"editorTrackingTimeZoneID": "UTC",
"editorTrackingRespectsDayLightSavingTime": "false",
"enableOwnershipBasedAccessControl": false,
"allowGeometryUpdates": true,
"allowUpdateWithoutMValues": false,
"allowTrueCurvesUpdates": true,
"xssPreventionEnabled": true,
"includeTopologyLayer": false,
"syncEnabled": false,
"syncVersionCreationRule": "versionPerDownloadedMap",
"onlyAllowTrueCurveUpdatesByTrueCurveClients": true,
"syncBranchVersionCreationRule": "versionPerDownloadedMap"
},
"enabled": false
},
{
"typeName": "MaritimeChartService",
"capabilities": "",
"properties": {
"comments": "Not to be used for navigation.",
"controlFilesDirectory": "C:\\arcgisserver\\directories\\maritimeserver\\maritimechartservice\\",
"keywords": "S-57",
"workingDirectory": "C:\\arcgisserver\\directories\\maritimeserver\\maritimechartservice\\",
"author": "ArcGIS for Maritime Server",
"subject": "S-57 Web Services",
"datasetsDirectory": "C:\\arcgisserver\\directories\\maritimeserver\\maritimechartservice\\",
"title": "Maritime Chart Service",
"category": "S-57",
"supportsREST": "true",
"supportsSOAP": "false",
"supportsInterceptor": "false"
},
"enabled": false
}
],
"frameworkProperties": {},
"datasets": [],
"_ssl": true,
"enabled": true
}
This JSON dictionary is then passed to the edit() method, as in the Python script sample below, using the Python API:
from arcgis.gis import GIS
import json
# Login to the GIS
gis = GIS(url='https://site.int/portal/home/', username='login', password='pass', verify_cert = False)
# Access its servers
gis_servers = gis.admin.servers.list()
# Grab the first server (incase its a multi machine deployment)
server1 = gis_servers[0]
print(type(server1))
print(server1)
# Validate to confirm server is listening
gis.admin.servers.validate()
# Get folders on server
folders = server1.services.folders
print(folders)
# Confirm the service exists
serviceExists = server1.services.exists(folder_name='/', name='20210520_Pembina_127_14302_Athabasca_River_Right__South__Slope_B206_2cm_png', service_type='MapServer')
print(serviceExists)
# Get the service
service = server1.services.list(folder='/')
print(service[2])
# Edit the service
with open("serviceJSON.json") as json_file:
data = json.load(json_file)
service[2].edit(data)
print("Complete")
This will update the newly published map service to enable the WMS capabilities on it.
NOTE: Minor alterations of the script will be necessary given your scenario. Most importantly is the service pulled from the List() method on line 26. My specific service I was updated was the 3rd in the list, yours will differ.
Good luck 🙂
Tom
In addition to Tom's solution below, I implemented a slightly different approach which basically simulates the REST requests in Server Manager. Thanks Tom for logging this issue and enhancement!
# Turning on WMS capability starts here
# Generate a token for accessing the REST admin
token_response = requests.post(token_URL, data = {
"f": "json",
"client": "referer",
"referer": portal_URL,
"username": portal_pub_user,
"password": portal_pub_pass,
"expiration": 60
})
token = token_response.json()["token"]
# Request the service data
service_data_reponse = requests.post(service_admin_URL, data = {
"f": "json",
"token": token
})
service_data = service_data_reponse.json()
# Enable the WMS extension and add metadata in the service description
for extension in service_data["extensions"]:
if (extension["typeName"] == "WMSServer"):
extension["enabled"] = "true"
extension["properties"]["keyword"] = ""
# Edit the service with the new service data
edit_response = requests.post(service_admin_URL + "/edit", data = {
"f": "json",
"token": token,
"service": json.dumps(service_data),
"runAsync": "true"
})
# Wait 30 seconds for the service to restart before sharing
time.sleep(30)
# Find and share the new WMS item in Portal
egis = arcgis.GIS(url=portal_URL, username=portal_pub_user, password=portal_pub_pass, verify_cert=True)
wms_items = egis.content.search(query=service_name, item_type="WMS")
for wms_item in wms_items:
if (wms_item.owner == portal_pub_user):
wms_item.share(everyone=True, org=True)
In my case the "service_data" JSON output looks like this ("supportedExtensions" instead "extensions" because of a different version?):
{
"currentVersion":10.91,
"cimVersion":"2.9.0",
"serviceDescription":"Bibliotheken - Standort und Informationen.",
"mapName":"gis_citymaps",
"description":"Bibliotheken - Standort und Informationen.",
"copyrightText":"xxx",
"supportsDynamicLayers":true,
"layers":[
"xxx"
],
"tables":[
],
"spatialReference":"xxx",
"singleFusedMapCache":false,
"initialExtent":"xxx",
"fullExtent":"xxx",
"datesInUnknownTimezone":false,
"minScale":0,
"maxScale":0,
"units":"esriMeters",
"supportedImageFormatTypes":"PNG32,PNG24,PNG,JPG,DIB,TIFF,EMF,PS,PDF,GIF,SVG,SVGZ,BMP",
"documentInfo":"xxx",
"Title":"Map",
"Author":"",
"Comments":"",
"Subject":"",
"Category":"",
"AntialiasingMode":"None",
"TextAntialiasingMode":"Force",
"Version":"2.9.0",
"Keywords":"Bildung,POI",
"capabilities":"Map,Query,Data",
"supportedQueryFormats":"JSON, geoJSON, PBF",
"exportTilesAllowed":false,
"referenceScale":0.0,
"datumTransformations":[
"xxx"
],
"supportsDatumTransformation":true,
"floorAwareMapProperties":"xxx",
"archivingInfo":"xxx",
"supportsClipping":true,
"supportsSpatialFilter":true,
"supportsTimeRelation":true,
"supportsQueryDataElements":true,
"maxRecordCount":2000,
"maxImageHeight":4096,
"maxImageWidth":4096,
"supportedExtensions":"FeatureServer, WFSServer",
"resampling":false,
"serviceItemId":"ddfa469bf5024d728a5da7a0f6310768"
}
Therefore I adjustet the script like this:
import arcpy
import arcgis
import requests
import time
import json
portal_url = "https://xxx/portal"
token_url = "https://xxx/portal/sharing/rest/generateToken"
portal_pub_user = "xxx"
portal_pub_pass = "xxx"
service_url = "https://xxx/server/rest/services/OGD/hochschule/MapServer"
service_admin_url = "https://xxx/server/rest/services/OGD/hochschule/MapServer/admin"
# Generate a token for accessing the REST admin
token_response = requests.post(token_url, data = {
"f": "json",
"client": "referer",
"referer": portal_url,
"username": portal_pub_user,
"password": portal_pub_pass,
"expiration": 60
})
token = token_response.json()["token"]
# Request the service data
service_data_reponse = requests.post(service_url, data = {
"f": "json",
"token": token
})
service_data = service_data_reponse.json()
# Enable the WMS extension and add metadata in the service description
service_data["supportedExtensions"] = 'FeatureServer, WFSServer, WMSServer'
# Edit the service with the new service data
edit_response = requests.post(service_admin_url + "/edit", data = {
"f": "json",
"token": token,
"service": json.dumps(service_data),
"runAsync": "true"
})
# Wait 30 seconds for the service to restart before sharing
time.sleep(30)
# Find and share the new WMS item in Portal
egis = arcgis.GIS(url=portal_url, username=portal_pub_user, password=portal_pub_pass, verify_cert=True)
wms_items = egis.content.search(query="hochschule", item_type="WMS")
for wms_item in wms_items:
if (wms_item.owner == portal_pub_user):
wms_item.share(everyone=True, org=True)
The edit_response is valid (200) but WMS gets not activated ("supportedExtensions" still without WMSServer). Do you have any idea what I am doing wrong?
Kind regards,
Timo
Hi Joe,
how did you solve this problem? Did you use the suggested way via the Python API?
kind regards,
Timo
Ah sorry, I have only just seen your solution
My final solution without using "request" module. The entire script is found here: wickit7/arcgisportalmanagement: Scripts to publish ArcGIS services and webtools and scripts to migra...
import arcgis, time, json
## Input parameter (example -> later JSON)
portal_url = "https://xxx/portal"
federated_server_url = "https://xxx/server"
sign_in_user = "xxx"
pw = "xxx"
service_name = "hochschule"
server_folder = "OGD"
portal_folder = "Betrieb OGD"
enable_extensions = ["FeatureServer" ,"WMSServer", "WFSServer"]
share_everyone = True
share_org = False
metadata = {
"credits": "© xxx",
"description": "Playground places",
"summary": "Playground places used to test the publishing of a service",
"tags": "test",
"use_limitations": "xxx"
}
## Publish Service (arcpy.sharing)
# ...
## Use ArcGIS API for Python for further settings
# log in to portal
print('Connect to portal for using ArcGIS API for Python')
gis = arcgis.GIS(url=portal_url, username=sign_in_user, password=pw, verify_cert=False)
print(f"target portal: {gis}")
# get the index of the server where the service was published
gis_servers_properties = gis.admin.servers.properties
server_index = None
for ii, server_prop in enumerate(gis_servers_properties.servers): # assuming servers have same indexes as in target.admin.servers.list()
if server_prop.url == federated_server_url:
server_index = ii
break
# get the correct server
server = gis.admin.servers.list()[server_index]
print(f'Search service on server {server_prop.url}')
# get the service
service = None
for service in server.services.list(server_folder): # assuming there is only one service with that name in that server folder
if service.properties.serviceName == service_name:
break
# Retrieve the service information
service_data = service.properties
# enable the extensions
if enable_extensions:
print(f'Enable the service extensions: {enable_extensions}')
for extension in service_data["extensions"]:
if extension["typeName"] in enable_extensions:
if share_everyone != True and extension["typeName"] in ["WFSServer", "WMSServer", 'WCSServer']:
print(f'00297: {extension["typeName"]} layers must be shared with everyone')
extension["enabled"] = "true"
extension["properties"]["keyword"] = ""
# convert PropertyMap to json
service_data_json = json.dumps(dict(service_data))
# Edit the service
edit_respone = service.edit(service_data_json)
# Wait 30 seconds for the service to restart
time.sleep(30)
# Retrieve the updated service information
service_data = service.properties
# get the poral items of the published service
for portal_item in service_data["portalProperties"]["portalItems"]:
item_id = portal_item["itemID"]
items = gis.content.search(query=f"id:{item_id}")
if items:
item = items[0]
else:
print(f'Item not found with the specified itemID "{item_id}".')
# move the item to the portal folder
print(f'Move item "{item.title}" of type "{item.type}" to the folder "{portal_folder}"' )
item.move(portal_folder, gis.users.me.username)
# update item with metadata
item.update(metadata)
# share item
print(f'Share item public:"{share_everyone}", organisation:"{share_org}"' )
item.share(everyone=share_everyone, org=share_org)
@JoeRogan , @TWickiSLU I think this issue has been resolved with the release of ArcGIS Pro 3.2. See the release notes and details of BUG-00159853.
Please correct me if I am wrong and this post is a slight different issue.