How to refer to layers from Python in an ArcGIS Server 10.1 Geoprocessing service?

2356
7
Jump to solution
03-27-2013 10:37 AM
markcheyne
Occasional Contributor
Last year when getting started with 10.0 GP services I asked http://forums.arcgis.com/threads/49556-how-to-access-map-document-layers-in-a-python-script-tool.

Now this year I'm getting started with 10.1 and its "publish a Result" scheme, and the script from last year doesn't work when published as a service.

The script tool references ArcSDE layers by their TOC name:

layername = "Flowlines" result = arcpy.SelectLayerByLocation_management(layername, "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION")


When I run it in ArcMap 10.1, it works fine if said layers exist in the map document open at the time I execute the tool. With a successful Result, I publish the service. Then I execute the service and get an error like:

result = arcpy.SelectLayerByLocation_management(layername, "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION") File "f:\program files\arcgis\server\arcpy\arcpy\management.py", line 6559, in SelectLayerByLocation raise e ExecuteError: Failed to execute. Parameters are not valid. ERROR 000368: Invalid input data.

I read http://resources.arcgis.com/en/help/main/10.1/#/Authoring_geoprocessing_tasks_with_Python_scripts/00... which seems to suggest that the Analyze step should have recognized my use of an ArcSDE layer by name and (presumably) spool it up in the service by the same name, but then why am I joyless?

Thanks, I know this is remedial.....   😉
0 Kudos
1 Solution

Accepted Solutions
KevinHibma
Esri Regular Contributor
Real quick shot in the dark.... try this...

inpoint = arcpy.Point(arcpy.GetParameter(0), arcpy.GetParameter(1)) inpointgeo = arcpy.PointGeometry(inpoint) bufferradius = arcpy.GetParameter(2) snapoption = arcpy.GetParameter(3)  lyrFlow = "Flowlines" lyrWater = "Waterbodies"  if snapoption.upper() == "FL":  layername = lyrFlow  else:  layername = lyrWater   result = arcpy.SelectLayerByLocation_management(layername, "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION")


Explanation - if theres 0 layers, during analyze/publish we didn't identify any data (layers) that need to be included. So that's for sure the issue. I'm thinking that because of the IF statement we didn't find the layers. But thats a hunch. If that doesn't work, I'm 99% sure this will:


 if snapoption.upper() == "FL":  result = arcpy.SelectLayerByLocation_management("Flowlines", "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION") else:  result = arcpy.SelectLayerByLocation_management("Waterbodies", "WITHIN_A_DISTANCE", inpointgeo, bufferradius,  "NEW_SELECTION") 

View solution in original post

0 Kudos
7 Replies
KevinHibma
Esri Regular Contributor
You have it correctly. It's just a name match.
If you have "Flowlines" in your ToC, and you use that exactly in your script: "Flowlines" - when publishing, we create a layer. You obviously have it correct because you can run the tool in ArcMap.

My guess is 1 of 2 things have gone wrong. Either the layer wasn't created properly in the service, or Server doesn't have access to your database to open the layer.
If you do the same workflow but use a featureclass from a fGDB and do the name match in your script - does this work?
If it does, I suspect it'll be a 64bit Server not having the proper client libraries to connect to the database "problem".

If it isn't the connection problem, it might be a bug. If you haven't installed SP1, can you? I know we fixed a couple publishing things regarding python and publishing in 10.1 SP1.
0 Kudos
markcheyne
Occasional Contributor
thanks for your help, K.

on the subject of testing with an FGDB, tricky as our admins have disabled data upload as a way to force us to use ArcSDE layers in our services. So first I want to ask:

does the fact that map services referring to the same ArcSDE layers publish and function correctly provide any hint on the 'client libraries' question?

We have AGS 10.1 SP1, and our ArcSDE db is Oracle 11g.
0 Kudos
KevinHibma
Esri Regular Contributor
If you have a map service running off the same oracle data which you're trying to use in your GP service, then right: you can connect and there aren't any problems there. Nothing special comparing GP and MapServices for connecting to the database.

So, that leaves a little more advanced troubleshooting.
You'll either need to have ArcMap on the Server, or be able to access the servers file system from an ArcMap machine.
If you can't do any of this, you'll have to copy a folder over from Server to the ArcMap machine.

On the server, navigate here:
C:\arcgisserver\directories\arcgissystem\arcgisinput\<service name>.GPServer\extracted\v101
(copy or connect to this folder so ArcMap has access)

Inside you'll find a file called <service name>.rlt
This rlt (result) is what we build and use to host the required bits of the gp service - in your case the layer(s).
If you drag that into your map, it'll place an entry in the ToC and the Results window.
Expand the task name (in the Toc) and you'll see a layer. This will be presumably broken. Right click > properties and check the source of this layer.
>It'll be pointing to 1 of 2 places, either a location to a connection file similar to where it was published from
>or a .sde connection file in the deployed input directory. (without knowing all details, I suspect this is the place it should be pointing).
If the layer points to the deployed folder, now find the .SDE connection file and check its connection properties. Are they ok? Can you connect with it?

I dont believe any of the above has provided you a solution, but it'll narrow down whats gone wrong.
As for the .rlt, and the folders/files around it: everything is relative paths, so thats why I say connect to it and look, or copy the whole folder over. (I hope this part makes sense).

Let me know what you turn up.
0 Kudos
markcheyne
Occasional Contributor
K - I hope you are still out there as I get back to this problem two months later!

our admins have mapped the AGS arcgisinput folder for me, so I can see the <service name>.GPServer\extracted\v101\ folder and its contained <service name>.rlt.

I dragged it to an empty ArcMap session's data frame, and it added a Result to the Results window, but did not add anything to the TOC. Presumably that's the source of my problem, but the question is why?

Here is a snippet of my script where it branches based on an input parameter to decide which of two layers to grab. This works when the tool is run in ArcMap and the two layers are present in the TOC with names to match the script...

inpoint = arcpy.Point(arcpy.GetParameter(0), arcpy.GetParameter(1))
inpointgeo = arcpy.PointGeometry(inpoint)
bufferradius = arcpy.GetParameter(2)
snapoption = arcpy.GetParameter(3)

if snapoption.upper() == "FL":
 layername = "Flowlines"
else:
 layername = "Waterbodies"

result = arcpy.SelectLayerByLocation_management(layername, "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION")


When I run this service, it fails on that last line:

Unable to complete operation.
Error executing tool.: Traceback (most recent call last): File "E:\AGS_Services_Dev\arcgissystem\arcgisinput\WD_eLT\SnapPointToHydro.GPServer\extracted\v101\all_environments\SnapPointToHydro.py", line 79, in <module> result = arcpy.SelectLayerByLocation_management(layername, "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION") File "f:\program files\arcgis\server\arcpy\arcpy\management.py", line 6559, in SelectLayerByLocation raise e ExecuteError: Failed to execute. Parameters are not valid. ERROR 000368: Invalid input data. Failed to execute (SelectLayerByLocation). Failed to execute (SnapPointToHydro). Failed to execute (SnapPointToHydro).

Thanks again, MC
0 Kudos
KevinHibma
Esri Regular Contributor
Real quick shot in the dark.... try this...

inpoint = arcpy.Point(arcpy.GetParameter(0), arcpy.GetParameter(1)) inpointgeo = arcpy.PointGeometry(inpoint) bufferradius = arcpy.GetParameter(2) snapoption = arcpy.GetParameter(3)  lyrFlow = "Flowlines" lyrWater = "Waterbodies"  if snapoption.upper() == "FL":  layername = lyrFlow  else:  layername = lyrWater   result = arcpy.SelectLayerByLocation_management(layername, "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION")


Explanation - if theres 0 layers, during analyze/publish we didn't identify any data (layers) that need to be included. So that's for sure the issue. I'm thinking that because of the IF statement we didn't find the layers. But thats a hunch. If that doesn't work, I'm 99% sure this will:


 if snapoption.upper() == "FL":  result = arcpy.SelectLayerByLocation_management("Flowlines", "WITHIN_A_DISTANCE", inpointgeo, bufferradius, "NEW_SELECTION") else:  result = arcpy.SelectLayerByLocation_management("Waterbodies", "WITHIN_A_DISTANCE", inpointgeo, bufferradius,  "NEW_SELECTION") 
0 Kudos
markcheyne
Occasional Contributor
after my previous post I already tried your first suggestion without luck.

then I went to lunch in a huff, dreamed up your second option over some chicken curry, came back to try it and...

sweet success!

so: dear readers, the take home lesson is not to get too fancy providing layer parameters to GP tools, try to use a string literal matching a TOC layer name when calling a GP tool.

K: where do I mail the beer?

😉
0 Kudos
KevinHibma
Esri Regular Contributor
Curry is an answer to a lot of problems...so is beer 🙂

Yeah... the parsing can be fairly restrictive, and thanks to cases like this that you and others have posted on the forums, or via submitted bugs, we've relaxed a lot of the parsing and find more data in 10.2 (next release). I appreciate you sticking with the process and providing feedback here. It's been helpful to us as we can make the software more usable. I think it might be me who owes the beers :).

thanks, Mark.
0 Kudos