I want to make an HTTP GET request to AGOL, but I want to route the request through a Python function.
Since I can't host the Python function on AGOL (more info here), I'd like to use AWS-Lambda instead.
HTTP GET request
➔ AWS Lambda Python function
➔ AGOL
What would it take to configure AWS Lambda so that it can serve as a middle tier between the HTTP GET request and AGOL?
2 Answers 2
Here's a sample AWS Lambda setup from a colleague:
- Create an AWS account (free).
- In AWS Lambda, create a new function.
- Enter a
function name
andRuntime
➔Python 3.7
- Enter a
- Write the function.
- This sample script receives an
ASSET_ID
value from a URL, processes it with Python, and sends additional requests to AGOL. It returns a JSON dictionary.
- This sample script receives an
from urllib.parse import urlencode
from urllib.request import Request, urlopen
import json
# Get a security token to append to all requests
def GetToken():
username = '<my username>'
password = '<my password>'
url = 'https://www.arcgis.com/sharing/rest/generateToken'
post_fields = {'username': username,'password':password,'expiration':'60','client':'referer','referer':'http://www.arcgis.com','f':'json' }
request = Request(url, urlencode(post_fields).encode())
out = urlopen(request).read().decode()
resp_dict = json.loads(out)
# print (resp_dict['token'])
return resp_dict['token']
# Query a feature service with a where clause returning all fields. Function returns a json dictionary
def queryFeatureService(url,token,where):
post_fields = {'token': token,'where':where,'outfields':'*','returngeometry':'false','f':'json' }
request = Request(url, urlencode(post_fields).encode())
out = urlopen(request).read().decode()
resp_dict = json.loads(out)
return resp_dict
# Get the zone value from the matching Active Transportation feature
def GetZone(jsonFeatures,zoneField):
for feature in jsonFeatures['features']:
# print (feature['attributes']['ZONE_'])
return feature['attributes'][zoneField]
# Query with ASSET_ID, returning the workorder record with a new "ZONE_" field added from the matching Transportation layer
# 'lambda_handler' is the main function for Lambda. Code starts here when called
def lambda_handler(event, context):
urlWorkorders = 'https://services.arcgis.com/Akv3yjcvcvmR0q1R/ArcGIS/rest/services/<my AGOL account name>/FeatureServer/0/query'
urlActiveTransportationPoints = 'https://services.arcgis.com/Akv3yjcvcvmR0q1R/ArcGIS/rest/services/Active_Transportation_Points/FeatureServer/0/query'
token = GetToken()
ASSET_ID = event["queryStringParameters"]['asset_id']
jsonWorkorder = queryFeatureService(urlWorkorders, token,"ASSET_ID = '" + ASSET_ID + "'")
# JSON for the new "ZONE_" field, appends to return Workorder JSON object to give it this missing field
fldZone = {'name':'ZONE_','type':'esriFieldTypeString','alias':'ZONE_','sqlType':'sqlTypeOther','length':15,'domain':None,'defaultValue':None}
jsonWorkorder['fields'].append(fldZone)
# Query the Active Transportation points with the same ASSET_ID
jsonActiveTransportation = queryFeatureService(urlActiveTransportationPoints,token,"ASSET_ID = '" + ASSET_ID + "'")
# Get the ZONE_ value
zone = GetZone(jsonActiveTransportation,'ZONE_')
# Set the ZONE_ value in the ZONE_ field that was added to workorders
jsonWorkorder['features'][0]['attributes']['ZONE_'] = zone
# return (jsonWorkorder)
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Headers' : '*'
},
'body': json.dumps(jsonWorkorder)
}
- Choose
Add Trigger
➔API Gateway
- Choose
Create a new API
,REST API
,Security
➔Open
- Open
API Gateway
:workorder-API hyperlink
Actions
➔Create method
➔GET
➔ configure as follows:- Click
Method Request
header link ➔ expandQuery String Parameters
- Add query string
"asset_id"
Conclusion:
It's a pretty interesting solution that could be useful for people who have similar requirements.
- I have more detailed instructions with screen captures in a PDF. If anyone wants it, just ask.
- I have a related question here: Query an ArcGIS Online FC via an HTTP request
A note about security:
The AWS Lambda function specifies/stores the AGOL username and password. This freaked me out at first.
However, since the username and password are server-side, they are never exposed to the client user.
In theory, we could write this same function as an AJAX call in JavaScript, but we would need to embed the credentials in the web code, making it unsecure, so that's why a server-side function is needed.
Additionally, we could alter the Lambda function to pass an AGOL-registered app's clientID and Secret for more granular access control—which would not have my username and password embedded in the function.
More info here: ArcGIS Web AppBuilder (Developer Edition). See the "Provide an app ID for Web AppBuilder" section (not just limited to just WAB, but for any app that needs a ClientID and Secret).
Thanks for your answer above but do you need to install any specific libraries or other tools to get it to run in AWS?
-
I got help from a developer I know. So he'd have to answer that question.User1974– User19742021年01月04日 01:20:29 +00:00Commented Jan 4, 2021 at 1:20
Explore related questions
See similar questions with these tags.