pythonrestpostgeocodingarcgis-server

Using the POST Method for Batch Geocoding with ArcGIS Server REST API?


I'm trying to hit my geocoding server's REST API:

[https://locator.stanford.edu/arcgis/rest/services/geocode/USA_StreetAddress/GeocodeServer] (ArcGIS Server 10.6.1)

...using the POST method (which, BTW, could use an example or two, there only seems to be this VERY brief "note" on WHEN to use POST, not HOW: https://developers.arcgis.com/rest/geocode/api-reference/geocoding-geocode-addresses.htm#ESRI_SECTION1_351DE4FD98FE44958C8194EC5A7BEF7D).

I'm trying to use requests.post(), and I think I've managed to get the token accepted, etc..., but I keep getting a 400 error.

Based upon previous experience, this means something about the formatting of the data is bad, but I've cut-&-pasted directly from the Esri support site, this test pair.

# import the requests library
import requests

# Multiple address records
addresses={ 
 "records": [
 {
 "attributes": {
 "OBJECTID": 1,
 "Street": "380 New York St.",
 "City": "Redlands",
 "Region": "CA",
 "ZIP": "92373"
 }
 },
 {
 "attributes": {
 "OBJECTID": 2,
 "Street": "1 World Way",
 "City": "Los Angeles",
 "Region": "CA",
 "ZIP": "90045"
 }
 }
 ]
}

# Parameters
# Geocoder endpoint
URL = 'https://locator.stanford.edu/arcgis/rest/services/geocode/USA_StreetAddress/GeocodeServer/geocodeAddresses?'
# token from locator.stanford.edu/arcgis/tokens
mytoken = <GeneratedToken>
# output spatial reference id 
outsrid = 4326
# output format
format = 'pjson'
# params data to be sent to api 
params ={'outSR':outsrid,'f':format,'token':mytoken}

# Use POST to batch geocode
r = requests.post(url=URL, data=addresses, params=params)

print(r.json())
print(r.text)

Here's what I consistently get:

{'error': {'code': 400, 'message': 'Unable to complete operation.', 'details': []}}

Solution

  • I had to play around with this for longer than I'd like to admit, but the trick (I guess) is to use the correct request header and convert the raw addresses to a JSON string using json.dumps().

    import requests
    import json
    
    url = 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/Locators/SanDiego/GeocodeServer/geocodeAddresses'
    headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
    addresses = json.dumps({ 'records': [{ 'attributes': { 'OBJECTID': 1, 'SingleLine': '2920 Zoo Dr' }}] })
    
    r = requests.post(url, headers = headers, data = { 'addresses': addresses, 'f':'json'})
    
    print(r.text)