Select to view content in your preferred language

Enabling editing for bulk published feature services

5648
19
Jump to solution
09-22-2021 01:04 PM
tigerwoulds
Frequent Contributor

We are running ArcGIS Enterprise 10.8.1. I followed this doc here to bulk publish around 50 feature services: Publish layers in bulk from a user-managed data store—Portal for ArcGIS | Documentation for ArcGIS E...

As the doc states, editing is not enabled by default. Is there a way (either through Portal/Server Manager or using Python) to go into the service properties and enable editing?

0 Kudos
19 Replies
LongDinh
Frequent Contributor

I forgot parenthesises in my print statement. It is currently printing the method object and not the returned value. It should be:

print (response.json())

 

That means the request was successful, however, in ESRI's REST service implementation, the response from the service will return a message in JSON format. You will likely see an error property in the returned JSON.

For other status codes, you can look at this.

tigerwoulds
Frequent Contributor

It worked like a charm, no errors. Thank you very much! 

Next goal is to apply this workflow to over 100 services in a folder on Server Manager so I can make the same edits to every service within that folder. Thank you again for your help thus far. 

tigerwoulds
Frequent Contributor

Hi @LongDinh 

For some reason, my script is throwing an error when submitting the POST. I am building the JSON file programmatically (since I have 100's of services), but my code sees the JSON file as invalid. 

 

{'status': 'error', 'messages': ["A JSONObject text must begin with '{' at character 1

 

  • The JSON file is does start with the {
  • I have validated it using an online editor
  • I can copy the JSON from the file and submit it through the MapServer/edit endpoint and it is successful.  Any ideas why I cant POST the JSON file?

 

 

0 Kudos
LongDinh
Frequent Contributor

Hi @tigerwoulds ,

The variable json_file is a path and not a JSON object hence the input parameter throws a 'does not begin with {' error.

I think your payload on line 100 should be:

payload = {
 'f':'json',
 'service': service_json,
 'token': token
}
0 Kudos
tigerwoulds
Frequent Contributor

Yes good catch, I missed that. Unfortunately I still get the same error

0 Kudos
LongDinh
Frequent Contributor

Try converting the service_json to a json string like:

payload = {
   'f': 'json',
   'service': json.dumps(service_json),
   'token': token
}

Hopefully it throws a different error. 

0 Kudos
tigerwoulds
Frequent Contributor

@LongDinh unfortunately, same issue BUT I was able to figure this out using a slightly different method from this example. I converted this to python 3 and replaced the httplib/urllib pieces with the functions from the 'request' library for python 3 and everything is worked as expected. Including the payload as you described initially was key to get this working. 

I can now loop through a folder on my GIS Server and update properties/capabilities for all services in the folder. 

Big thank you for your help again. 

LongDinh
Frequent Contributor

Awesome work! Glad to hear you reached a solution 🙂

0 Kudos
MichaelSnook
Frequent Contributor

@tigerwoulds ..I am looking to do the exact same thing but I'm getting a bit lost on the upgrade.  Can you share your working Python3 script by chance?  Thanks!

0 Kudos
DrewDowling
Frequent Contributor

This seems to still be an issue in 2025, you can't use the ArcGIS python API to modify referenced feature services, or at least I couldn't get it working.

Here some code I wrote to use the ArcGIS Server admin rest endpoint instead. It updates the capability of all feature services in a folder to add Extract to the default Query capability. Hope it helps someone.

 

from arcgis import GIS
import requests
import json


domain = 'gis.domain.org'
folder = 'MyServerFolder'
# login to GIS
gis = GIS(url="https://gis.domain.org/portal/home", profile='sangis_portal_aiteadmin')
token = gis._con.token

# Get a list of services from ArcGIS Server
# from a specific folder
gis_servers = gis.admin.servers.list()
print(gis_servers)
# Assuming a single server for simplicity
server1 = gis_servers[0]
damoa_services = server1.services.list(folder=folder)

for service in damoa_services:
    # Get the service definition
    service_def = requests.get(f'{service.url}?f=json&token={token}').json()
    service_name = service_def['serviceName']
    # Loop through the service extensions to find the FeatureServer extension
    i=0
    for ect in service_def['extensions']:
        if ect['typeName'] == 'FeatureServer':
            print("Enabling Feature Access capabilities...")
            print(f"original capabilities: {service_def['extensions'][i]['capabilities']}")
            # Update capabilities by editing the service definition
            service_def['extensions'][i]['capabilities'] = "Query,Extract"
            print(f"Updated capabilities: {service_def['extensions'][i]['capabilities']}")
            # Construct the URL for editing the service definition
            # This URL is specific to ArcGIS Server REST API
            edit_service_url = f"https://{domain}/arcgis/admin/services/{folder}/{service_name}.MapServer/edit"
            try:
                payload = {
                    'f': 'json',
                    'service':json.dumps(service_def),
                    'token':token
                    }
                # Make the POST request to update the service definition
                response = requests.post(url=edit_service_url, data=payload)
                # Check if the request was successful
                # This doesn't work, 200 is returned even if the update fails
                # Check the responce conteent instead
                if response.status_code == 200:
                    print("Capabilities updated successfully.")
                else:
                    print(f"Failed to update capabilities: {response.text}")
            except requests.exceptions.RequestException as e:
                raise e
            i=0
            break
        else:
              i += 1

 

0 Kudos