ArcGIS Online REST calls with Content-type of application/json?

5992
1
01-08-2015 10:18 PM
VishApte
Esri Contributor

Hi All,

I have a query regarding ArcGIS Online REST API. We have few AGOL feature services that will be maintained using addFeatures, updateFeatures, deleteFeatures, query and createReplica operations. Feature services are private so token will be passed as parameter using generateToken API.

Most of these REST methods accept parameters and response can be a JSON if format parameter is set to json.

However, REST API does not seem to accept content-type of application/json in the header of the REST request with parameters passed as json object. Using some trial python script below, I discovered only way to pass parameters to REST calls such as generateToken is using application/x-www-form-urlencoded as Content-type.

Same is applicable to response of the REST call. It is always text/plain and not application/json. Is this intended? Using application/json in request and response is much more programming friendly rather than form parameters or plain text response.

Cheers,

Vish

#-------------------------------------------------------------------------------

import json

import urllib, urllib2, urlparse

import os, sys

import traceback

def get_response_form(url, query='', get_json=True, exit_on_error = False):

    encoded = urllib.urlencode(query)

    request = urllib2.Request(url)

    request.add_header('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8')

    if get_json:

        response = urllib2.urlopen(request, encoded)

        responseString = response.read()

        json_response = json.loads(responseString)

        if 'error' in json_response:

            if (exit_on_error == True):

                exit()

            else:

                return json_response

        else:

            return json_response

    return urllib2.urlopen(request).read()

def get_response_json(url, query='', get_json=True, exit_on_error = False):

    request = urllib2.Request(url, data=None)

    request.add_header('Content-Type', 'application/json')

    if get_json:

        response = urllib2.urlopen(request, json.dumps(query))

        responseString = response.read()

        json_response = json.loads(responseString)

        if 'error' in json_response:

            if (exit_on_error == True):

                exit()

            else:

                return json_response

        else:

            return json_response

    return urllib2.urlopen(request, json.dumps(query)).read()

def loginAGOL(AGOLTokenURL, username, password, expirationTime, refererURL):

    print "Generating token using Content-type as application/x-www-form-urlencoded..."

    JSONgenerateTokenRequest = {'username': username, 'password': password, 'expiration': expirationTime, 'client': 'referer', 'referer': refererURL, 'f': 'json'}

    token = ''

    try:

        response = get_response_form(AGOLTokenURL, JSONgenerateTokenRequest)

        if('token' in response.keys()):

            token = response['token']

            print "Generated Token '%s'" %(token)

        else:

            print "Failed to generate token: %s" %(response)

    except Exception, ex:

        error = traceback.format_exc()

        print "Failed to generate token using application/x-www-form-urlencoded: %s." %(error)

    print "Generating token with same parameters using Content-type as application/json..."

    try:

        response = get_response_json(AGOLTokenURL, JSONgenerateTokenRequest)

        if('token' in response.keys()):

            token = response['token']

            print "Generated Token '%s'" %(token)

        else:

            print "Failed to generate token: %s" %(response)

    except Exception, ex:

        error = traceback.format_exc()

        print "Failed to generate token using application/json: %s." %(error)

    return token

def main():

    if len(sys.argv) == 4:

        username = str(sys.argv[1])

        password = str(sys.argv[2])

        expiry = int((sys.argv[3]))

        URLAGOLToken = r"https://www.arcgis.com/sharing/rest/generateToken"

        token = loginAGOL(URLAGOLToken, username, password, expiry, "www.arcgis.com")

    else:

        print "Invalid number of parameters."

        print "Usage: %s <ArcGIS Online username> <ArcGIS Online user password> <expiration time in minutes>" %(os.path.basename(sys.argv[0]))

    sys.exit()

if __name__ == '__main__':

    main()

#-------------------------------------------------------------------------------

Tags (3)
0 Kudos
1 Reply
HeikoHeijenga
Esri Contributor

I don't see how things would be easier if content-type would be set correctly, how would the following snippet look like if it was?

data = urllib.urlencode({'username': username, 'password': password, 'expiration': expirationTime, 'client': 'referer', 'referer': refererURL, 'f': 'json'})
req = urllib.urlopen('https://www.arcgis.com/sharing/rest/generateToken', data)
json.loads(req.read())
0 Kudos