A Python Web Tool is unable to access a hosted feature service

569
6
03-13-2020 03:07 AM
andk
by
New Contributor

I have created a simple script tool that should get one parameter (a feature class) and print some unique values from a single field. The Python code looks like this:

import arcpy

def get_species(observationFeatureClass, field, query):
    with arcpy.da.SearchCursor(observationFeatureClass, [field], query) as species:
        return sorted({s[0] for s in species})

ofc = arcpy.GetParameterAsText(0)
fld = "gatunek"
qry = "kategoria = 'inwazyjna'"

for i, s in enumerate(get_species(ofc, fld, qry), start=1):
    arcpy.AddMessage(f"Gatunek nr {i}: {s}")‍‍‍‍‍‍‍‍‍‍‍‍

If I run this tool straight from the ArcGIS Pro, providing a hosted feature service as a parameter, everything works well. But, when I publish the result as a Web Tool on our portal, it is unable to access the service and it returns: "RuntimeError: cannot open <Hosted Feature Service URL here>".

Previously, we had a problem with accessing protected resources from a custom print service and it was resolved by applying a patch, but this tool fails regardless of the service permissions.

We work with ArcGIS Pro 2.5 and ArcGIS Enterprise 10.7.

Tags (1)
0 Kudos
6 Replies
JeffK
by MVP Regular Contributor
MVP Regular Contributor

Maybe check out the portal logs and see what is happening- About portal logs—Portal for ArcGIS (10.8) | Documentation for ArcGIS Enterprise 

0 Kudos
andk
by
New Contributor

I forgot to mention that I've set up Portal's log level to 'info', but there is no information about the execution of my tool. I've also checked Srever's log messages and there is only the error that I've mensioned above.

ArcGIS Server log

Update:

I thought setting up a log level on a Portal affects also a federated server... My bad.

Now I have set the server's log level to "debug" and I figured out that the job is submitted with a valid access token but then the request to the service is anonymous:

DEBUG	13 mar 2020, 13:11:13	A request was made for service 'Hosted/<service name>.MapServer' but it did not have adequate credentials.	Admin
DEBUG	13 mar 2020, 13:11:13	Exception in authorize Token Required	Server
DEBUG	13 mar 2020, 13:11:13	Computed privilege for user = ACCESS	Admin
FINE	13 mar 2020, 13:11:13	HTTP Referer: Not Available	Server
INFO	13 mar 2020, 13:11:13	Request user: Anonymous user, Service: Hosted/<service name>/FeatureServer	Rest
DEBUG	13 mar 2020, 13:11:13	ARCGIS_PORTAL_TOKEN Authentication, Token is not available in the request, request is treated as anonymous	Server‍‍‍‍‍‍‍‍‍‍‍‍

So my question is: How to set the authentication in my script tool to pass currently logged user's token to external requests?

0 Kudos
JeffK
by MVP Regular Contributor
MVP Regular Contributor

I think the process would be for the requestor to hit the token generator for your organizations portal and get their token.  It won't get the currently logged in user on the server side, if I am understanding you correctly.  If the requestor token request is successful, they can make the request to your processing service by appending the token onto the end of the request url.  There are a few examples of getting a token floating around, this is how I do it.  svc would be your service name.

import requests

# ---------------------------------------------------------------------------
def getToken(port, expiration, server):
    try:
       # Create dictionary of credentials
       query_dict = {
                    'username': username,
                    'password': password,
                    'expiration': 60,
                    'client': 'requestip'
                }

       url = "https://{}:{}/arcgis/admin/generateToken?f=json".format(server, port)
       token = requests.post(url, query_dict).json()

       # If token cannot be generated
       if "token" not in token:
           raise ValueError('Did not return a token: {}'.format(token))
       else:
           return token['token']

       except requests.exceptions as e:
           raise Exception("Could not connect to machine {} on port {}\n{}".format(server, port, e))

       except RuntimeError:
           logger.info('Runtime Error: {}'.format(traceback))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The return token will get appended to the request url string like this:

service_url = "{}/services/{}?token={}&f=json".format(url, svc, token)‍

result = requests.post(service_url).json()

‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Hope this helps and maybe someone more versed in this area can assist.

0 Kudos
andk
by
New Contributor

Yes, but the tool is to be published on the portal. Users will run it against various feature services (from the portal's analysis tab in the web map view). They should be able to choose a feature class from the portal's resources. The tool cannot require providing credentials every time when someone wants to use it.

Documentation says: "Most Python script tools that execute successfully on your computer will publish and execute successfully as a web tool—you do not have to modify your script in any way." (source).

Maybe I have missed something, but in ArcGIS Pro I am logged in to the portal and I am able to simply run arcpy.da.SearchCursor(<service url>, ...) either from the python console or as a script tool. Authenticaton is handled in the background. The same tool, published and executed from the portal's interface, has a problem with accessing resources selected by an authenticated user.

0 Kudos
JeffK
by MVP Regular Contributor
MVP Regular Contributor

Ah gotcha.  Wasn't quite sure how you were hitting the service and saw 'web' in the title so I thought of webmap/http access, which if the service is not publicly shared, the user gains access to the service through requesting/providing tokens every time they use the tool. 

I interpret that documentation statement as referring to only the tools code. There is still a lot of other things that needs to be done in order for the tools to be used.

... Is it set up as a secured service?  Was it shared with a group of authorized users?  Halfway down: Connect to secure services—Portal for ArcGIS | Documentation for ArcGIS Enterprise

0 Kudos
andk
by
New Contributor

Yes, it is secured. Both, the tool and the feature service are owned by me. I have full access to them. I am publishing and running this tool with the same account. Unfortunately, even if I allow public access to the feature service, the error keeps occuring.

0 Kudos