0

When publishing ArcGIS Python ToolBox, it still uses the Desktop Output folder.

The code below is coming from the toolbox.

class LandSimilarity(TargetingTool):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "Land Similarity"
        self.description = ""
        self.canRunInBackground = False
        self.parameters = [
            parameter("Input raster", "in_raster", "Raster Layer",
                      multiValue=True),
            parameter("Input point layer", "in_point", "Feature Layer"),
            parameter("Output extent", "out_extent", "Feature Layer",
                      parameterType='Optional'),
            parameter("R executable", "r_exe", "File"),
            parameter("Output Mahalanobis raster", "out_raster_mnobis",
                      'Raster Layer', direction='Output'),
            parameter("Output MESS raster", "out_raster_mess", 'Raster Layer',
                      direction='Output')
        ]

    def getParameterInfo(self):
        """Define parameter definitions"""
        self.parameters[1].filter.list = ["Point"]  # Geometry type filter
        return self.parameters

   ....
   def execute(self, parameters, messages):
        """ Execute functions to process input raster.
            Args:
                parameters: Parameters from the tool.
                messages: Internal validation messages
            Returns: Land suitability raster.
        """
        try:
            r_exe_path = parameters[3].valueAsText
            out_mnobis_ras = parameters[4].valueAsText.replace("\\",
                                                               "/")  # Get mahalanobis output
            out_mess_ras = parameters[5].valueAsText.replace("\\",
                                                             "/")  # Get mess output
            ras_temp_path = ntpath.dirname(
                out_mnobis_ras)  # Get path without file name
            ras_temp_path += "/Temp/"
            # Create temporary directory if it doesn't exist
            if not os.path.exists(ras_temp_path):
                os.makedirs(ras_temp_path)
            # Copy point layer to temporary directory
            in_fc_pt = parameters[1].valueAsText.replace("\\", "/")
            if os.path.isfile(in_fc_pt):
                in_fc_pt = self.copyDataset(ras_temp_path, in_fc_pt,
                                            in_fc_pt)  # Copy dataset from source to destination
            else:
                in_fc_pt = super(LandSimilarity, self).getLayerDataSource(
                    parameters[1])  # Get point layer data source
                in_fc_pt = self.copyDataset(ras_temp_path, in_fc_pt, in_fc_pt)

            # raster sample creation
            if parameters[2].value:
                in_fc = super(LandSimilarity, self).getInputFc(parameters[2])[
                    "in_fc"]
                extent = arcpy.Describe(
                    in_fc).extent  # Get feature class extent
                self.createValueSample(parameters, in_fc_pt, ras_temp_path,
                                       in_fc,
                                       extent)  # Create raster cell value sample
            else:
                self.createValueSample(parameters, in_fc_pt, ras_temp_path,
                                       in_fc=None,
                                       extent=None)  # Create raster cell value sample
            self.deleteTempFile(parameters,
                                ras_temp_path)  # Delete temporary files
            arcpy.AddMessage("Joining {0} to {1} \n".format(in_fc_pt,
                                                            ras_temp_path + "temp.dbf"))
            arcpy.JoinField_management(in_fc_pt, "FID",
                                       ras_temp_path + "temp.dbf", "OID",
                                       "")  # Join tables
            out_csv = ras_temp_path + "temp.csv"
            self.writeToCSV(in_fc_pt,
                            out_csv)  # Write feature class table to CSV file
            arcpy.management.Delete(in_fc_pt)  # Delete vector
            self.createRScript(parameters, ras_temp_path)  # Create R script
            self.runCommand(r_exe_path, ras_temp_path)  # Run R command
            self.asciiToRasterConversion(parameters,
                                         ras_temp_path)  # ASCII to raster conversion
            shutil.rmtree(ras_temp_path)  # Delete directory

            # Get raster and load to the current mxd
            out_ras = ""
            if arcpy.Exists(out_mnobis_ras) and arcpy.Exists(out_mess_ras):
                out_ras = [out_mnobis_ras, out_mess_ras]
            else:
                if arcpy.Exists(out_mnobis_ras):
                    out_ras = out_mnobis_ras
                elif arcpy.Exists(out_mess_ras):
                    out_ras = out_mess_ras
            super(LandSimilarity, self).loadOutput(
                out_ras)  # Load output to current MXD
            arcpy.RefreshCatalog(
                ntpath.dirname(out_mnobis_ras))  # Refresh folder
            return
        except Exception as ex:

            arcpy.AddMessage('ERROR: {0} \n'.format(ex))

Below is how to the toolbox looks like. enter image description here It brings the following error message.

Submitted.
Executing...
Executing (Land Similarity): LandSimilarity E:\arcgisserver\directories\arcgissystem\arcgisuploads\services\targeting_tools\LandSimilarity.GPServer\if7853d60-27e6-40b8-a101-283848da59ea\uganda_rainfall_2011_Jan_to_Dec.tif "Feature Set" "Feature Set" "C:\Program Files\R\R-3.4.0\bin\R.exe" D:\CIAT\data\man D:\CIAT\data\mess
Start Time: Sat Dec 09 07:22:17 2017
Executing (Land Similarity): LandSimilarity E:\arcgisserver\directories\arcgissystem\arcgisuploads\services\targeting_tools\LandSimilarity.GPServer\if7853d60-27e6-40b8-a101-283848da59ea\uganda_rainfall_2011_Jan_to_Dec.tif "Feature Set" "Feature Set" "C:\Program Files\R\R-3.4.0\bin\R.exe" D:\CIAT\data\man D:\CIAT\data\mess
Start Time: Sat Dec 09 07:22:17 2017
Running script LandSimilarity...
ERROR: [Error 3] The system cannot find the path specified: u'D:/'
Completed script LandSimilarity...
Succeeded at Sat Dec 09 07:22:20 2017 (Elapsed Time: 2.79 seconds)
Succeeded at Sat Dec 09 07:22:20 2017 (Elapsed Time: 3.35 seconds)
Invalid return value: D:\CIAT\data\man
Failed.

However, the Output Parameter is properly detected as shown below. Please note that there are two Raster Layer Outputs and a Map Services is created for the service. enter image description here

The toolbox runs fine in Desktop as shown in the result below. enter image description here How could I make it publish the Raster Layer and remove the Desktop Output Parameters. Which are:

D:\CIAT\data\man D:\CIAT\data\mess
  • You cannot use local drives as output locations. Use scratchworkspace or scratchfolder as outlined in the documentation. desktop.arcgis.com/en/arcmap/latest/analyze/sharing-workflows/… and server.arcgis.com/en/server/latest/publish-services/linux/… – Ben S Nadler Dec 10 '17 at 4:39
  • I didn't set those local output paths. What confused me is, I only used those paths for the execution I did on ArcGIS desktop and I don't know how it took those parameters to the server. The server output path is set correctly and it is not editable. – wondim Dec 10 '17 at 10:04
  • Your output path is defined somewhere in your acript whether you did it or it is using defaults. You need to change it in the script, not the service interface. Also put the relevant portion of the code in the question. – Ben S Nadler Dec 10 '17 at 15:11
  • The output path is not hard coded. It comes from the toolbox interface. I have added part of the toolbox code. – wondim Dec 10 '17 at 17:36
  • Your outpath and everything else is a derivative of your ras_temp_path, which is defined by your input parameter. So while not hard coded, it is still pointing to a local resource. This is wrong and will not work on the server. Define temp and output folders per the documentation using os.path.join( arcpy.env.scratchFolder, *) – Ben S Nadler Dec 10 '17 at 18:37
1

You cannot use local drives as output locations. Use scratchworkspace or scratchfolder as outlined in the documentation. sharing-workflows and publish GP services

You will need to do a few things:

  • the outpath and everything else in the script is a derivative of your ras_temp_path, which is defined by your input parameter. So while not hard coded, all the working directories are still pointing to a local resource. This is will not work on the server. Define temp and output folders per the documentation using os.path.join( arcpy.env.scratchFolder, *)
  • The output parameter needs to be parameterType Derived. Users should not be able to define an output location, only the name, in which case parameters 4 and 5 will be string, and you will use os.path.join to define the actual output variable using the env.scratchFolder and outputName.
  • For a GP service you probably want to zip up both outputs into a single zipped folder and have one output for the users to download/unpack. This will improve the transfer speed.
  • The outputs needs to be set like this:

    arcpy.SetParameterAsText(4, final_ouput_path_in_the_server)

    This enables the server to return an output to the client.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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