Update feature in feature service using rest

5824
5
Jump to solution
06-22-2017 05:54 AM
ModyBuchbinder
Esri Regular Contributor

Hello all

I am trying to use python to update a feature in a feature service.

In simple chrome my url is:

http://modyb-pc:6080/arcgis/rest/services/featureAccess/FeatureServer/0/applyEdits 

and my json in the update is:

[ {
"attributes" : {
"OBJECTID" : 1,
"CITYNAME" : "aaa"
}
} ]

(no adds).

This URL uses post only.

How do I call it from Python.

I have here: Using Python to Write Features to a Feature Service | Esri Australia Technical Blog  example of Add but the update is not the same 

Thanks

0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Alum

I have also been experimenting with the REST API ApplyEdits function.  In my case, it is with AGOL, so you will need to modify the URLs in the example.  Updates are sent as a list of dictionaries.  Here's a code sample.

import urllib, urllib2, json, sys, collections

# get a token - this is for AGOL, modify for portal/server
username = 'xxx'
password = 'yyy'

referer = "http://www.arcgis.com/"
tokenurl = "https://www.arcgis.com/sharing/rest/generateToken"

query_dict = { 'username': username, 'password': password, 'referer': referer }
query_string = urllib.urlencode(query_dict)
token = json.loads(urllib.urlopen(tokenurl + "?f=json", query_string).read())
if "token" not in token:
    print(token['error'])
    sys.exit(1)

#  items to update, based on OBJECTID
# OBJECTID, POINT_X, POINT_Y, City
to_update = [
    [ 11, -16683056.055, 8668941.2456, 'Anchorage' ],
    [ 12, -16188891.9816, 8873309.4627000019, 'Glennallen' ],
    [ 13, -16682516.0441, 8661113.2519000024, 'Anchorage' ]
    ]

updates = [] # this will be a list of dictionaries
for item in to_update
    dict = {
        'geometry' : {
            'x' : item[1],
            'y' : item[2]},
        'attributes' : {
            'OBJECTID' : item[0],
            'City' : item[3]
            }
        }
    updates.append(dict)

# modify URL for your needs
URL = "https://services2.arcgis.com/<directory>/arcgis/rest/services/<layer>/FeatureServer/0/applyEdits"

query_dict = {
    "updates" : updates,
    "f": "json",
    "token": token['token']
    }

jsonResponse = urllib.urlopen(URL, urllib.urlencode(query_dict))
response = json.loads(jsonResponse.read(),
                      object_pairs_hook=collections.OrderedDict)

print json.dumps(response, indent=4, sort_keys=False) # formatted json of response
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

If you do not need to update geometry, you can delete lines 28-30 and modify the to_update list and indexing.

For additions, the query_dict would contain the "adds" parameter which is a list of dictionaries similar to the "updates" parameter. Features to be added should include the geometry.

Additional documentation on ApplyEdits

#arcgis online rest api

View solution in original post

5 Replies
JoshuaBixby
MVP Esteemed Contributor

If you are going to be working with ArcGIS Server, or Portal, data from Python; have you thought about using GitHub - Esri/ArcREST: python package for REST API (AGS, AGOL, webmap JSON, etc..)  or GitHub - Esri/arcgis-python-api: Documentation and samples for ArcGIS Python API  ?  Both of these packages abstract the messiness of Python -> HTTP -> REST from the user, and make it where we, as users, don't have to roll our own HTTP.

BlakeTerhune
MVP Regular Contributor

In addition to the ArcREST scripts, I also found the ArcGIS Server Administration Toolkit - 10.1+ helpful; although the code on GitHub is probably more up to date.

RandyBurton
MVP Alum

I have also been experimenting with the REST API ApplyEdits function.  In my case, it is with AGOL, so you will need to modify the URLs in the example.  Updates are sent as a list of dictionaries.  Here's a code sample.

import urllib, urllib2, json, sys, collections

# get a token - this is for AGOL, modify for portal/server
username = 'xxx'
password = 'yyy'

referer = "http://www.arcgis.com/"
tokenurl = "https://www.arcgis.com/sharing/rest/generateToken"

query_dict = { 'username': username, 'password': password, 'referer': referer }
query_string = urllib.urlencode(query_dict)
token = json.loads(urllib.urlopen(tokenurl + "?f=json", query_string).read())
if "token" not in token:
    print(token['error'])
    sys.exit(1)

#  items to update, based on OBJECTID
# OBJECTID, POINT_X, POINT_Y, City
to_update = [
    [ 11, -16683056.055, 8668941.2456, 'Anchorage' ],
    [ 12, -16188891.9816, 8873309.4627000019, 'Glennallen' ],
    [ 13, -16682516.0441, 8661113.2519000024, 'Anchorage' ]
    ]

updates = [] # this will be a list of dictionaries
for item in to_update
    dict = {
        'geometry' : {
            'x' : item[1],
            'y' : item[2]},
        'attributes' : {
            'OBJECTID' : item[0],
            'City' : item[3]
            }
        }
    updates.append(dict)

# modify URL for your needs
URL = "https://services2.arcgis.com/<directory>/arcgis/rest/services/<layer>/FeatureServer/0/applyEdits"

query_dict = {
    "updates" : updates,
    "f": "json",
    "token": token['token']
    }

jsonResponse = urllib.urlopen(URL, urllib.urlencode(query_dict))
response = json.loads(jsonResponse.read(),
                      object_pairs_hook=collections.OrderedDict)

print json.dumps(response, indent=4, sort_keys=False) # formatted json of response
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

If you do not need to update geometry, you can delete lines 28-30 and modify the to_update list and indexing.

For additions, the query_dict would contain the "adds" parameter which is a list of dictionaries similar to the "updates" parameter. Features to be added should include the geometry.

Additional documentation on ApplyEdits

#arcgis online rest api

ModyBuchbinder
Esri Regular Contributor

Hi Randy

Works great. I can easily change text attributes with English strings.

When I try to update Hebrew strings I get garbage in the feature class. In REST (in chrome) I can update Hebrew string without any problem.

I tried to encode/decode and do a few more tricks in python but nothing works.

 Any idea?

0 Kudos
RandyBurton
MVP Alum

I don't have any experience using Python‌ or the ArcGIS REST API‌ with languages‌ other than English.  I suggest you start a new question and include an example of the problem.

Edit:  However, this link on StackOverflow looked interesting: decoding and encoding Hebrew string in Python

0 Kudos