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
Solved! Go to Solution.
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.
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.
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.
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.
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?
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