I am seeking to understand my options for sending long JSON objects in a request to a Geoprocessing Service.

In particular, I am looking for some example code to illustrate how to include two long JSON objects (one a polygon geometry as a coordinate string, the other a table as rows of ASCII text with the first row being the column headings) into a POST request to my Geoprocessing Service, and then hints as to how best to read them as parameters in the Python script that I've published as my Geoprocessing Service.

At http://help.arcgis.com/en/arcgisserver/10.0/apis/rest/gettingstarted.html it says:

When using the REST API, you will normally use an HTML GET method in a form. When you use GET, the entire request is encoded in the URL. This is the preferred method to use whenever possible. However, in this mode, a URL is limited to as few as 1024 characters depending on the browser. Thus, if you have a long JSON object to include in the request, you will need to use POST.

A second option, when using certain Geometry Service and Geoprocessing Service operations, is to continue to use GET and to specify a URL to the input JSON object contained in a file on a public server.

I'm familiar with using a GET method when the parameters can all fit into a URL that I can paste into a browser.

I'm also comfortable with the idea of using GET to specify a URL to input JSON objects that are contained in files on a public server. However, I am prevented from using this method this because my client does not want files placed on a public server.

That leaves me with having two long JSON objects to include in the request and having to use POST which is a method beyond my current level of understanding.

Is any example code readily available?


It's fairly easy with urllib2. Say you've got a gigantic url like this:


All you need to do is take the query (everything after the ?) and jam it in the data argument to urlopen.

import urllib2
import urlparse

return_data = urllib2.urlopen(url).read()

url_parts = urlparse.urlsplit(url)
base_url = urlparse.urlunsplit(url_parts[:3] + (None, None))
return_data = urllib2.urlopen(base_url, url_parts.query).read()

Then there's Requests, which is not in the standard library but it is really, really nice and intuitive to use.

  • +1 for Requests - it's brilliant. For comparison, to use post through the requests library, use r = requests.post("url", data={"data":"dictionary"}).text
    – om_henners
    Feb 5 '12 at 2:25

My question was a bit vague and so was not directly addressed by Jason, whose answer nevertheless prompted some excellent learnings between myself and the Perl developer who is POSTing the data_string below to my Geoprocessing Service via the REST API. In Python I set the parameter as text, manipulate it into GeoJSON via a few string replacements and can then covert GeoJSON to a polygon geometry using AsShape. The developer will soon supply GeoJSON from Perl so that the string replacements can be dropped from the Python script.

import arcpy

data_string = '{"points":[{"x":151.31566327431005,"y":-26.518409926261},{"x":151.31339754451005,"y":-26.52422947878},{"x":151.31425052515,"y":-26.526280562223},{"x":151.31627635413997,"y":-26.527830775396},{"x":151.31731592428002,"y":-26.530096433901}]}'
data_string = data_string.replace("points","coordinates")
data_string = data_string.replace('"coordinates"','"type": "Polygon","coordinates"')
data_string = data_string.replace('{"x":','[')
data_string = data_string.replace('"y":','')
data_string = data_string.replace('[[','[[[')
data_string = data_string.replace('},','],')
data_string = data_string.replace('}]}',']]]}')
polygon = arcpy.AsShape(data_string)

arcpy.Append_management([polygon], "C:\\temp\\test.gdb\\PolyFromJSON", "NO_TEST")

The relevant part of the request URL (submitted from a Perl script) that the above responds is of the form below.

http://<server>/ArcGIS/rest/services/OEMS/test/GPServer/test/execute?geometry={"points":[{"x":151.31566327431005,"y":-26.518409926261},{"x":151.31339754451005,"y":-26.52422947878},{"x":151.31425052515,"y":-26.526280562223}, ... <thousands more coordinate pairs> ...,{"x":151.31627635413997,"y":-26.527830775396},{"x":151.31731592428002,"y":-26.530096433901}]}&f=pjson
  • Your final request looks more like a get than a post to me. You might eventually run in to an issue with request string being too long.
    – isamson
    Dec 11 '17 at 20:03
  • @isamson I did this too long ago to recall the details and it was a joint piece of work so I may or may not have reported it accurately. In any event I am not in a position to be able to check the details.
    – PolyGeo
    Dec 11 '17 at 21:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.