Select to view content in your preferred language

Python differences between Pro and Notebook Server

221
1
Tuesday
MatthiasBoucher
Occasional Contributor

Hello

I am facing differences and unexpected behaviors when running Python scripts in ArcGIS Notebook Server,  whereas everything is fine in local (through my IDE or with ArcGIS Pro). Context : I have several windows scheduled tasks triggering Python scripts that I am currently migrating to Notebook. I am working with an ArcGIS Portal 10.9.1.

Exemple of unexpected behavior : a simple arcpy.Append_management

append_res = arcpy.Append_management(
      inputs=gdb_fc_full_path,
      target=dest_full_path,
      schema_type="NO_TEST"
)
if append_res and append_res.maxSeverity > 0:
      messages = append_res.getAllMessages()
      for message_type, message_code, message_string in messages:
            print(f"{message_type} : {message_code} - {message_string}")

The piece of code above works fine in local. But in Notebook, on a specific feature class, it triggers the following Exception :

AttributeError: 'Result' object has no attribute 'getAllMessages'

Which means that the Append_management ended without crash, but when analyzing the warnings and errors it contains, the Result object is incomplete, as I cannot call the getAllMessages method. Any hints on why such behavior ?

 

Another example would be calling the arcpy.ReconcileVersions_management function. In local, it works successfully, or with conflicts, depending on the version. But in Notebook, one some versions, it just crashes, or timeouts. Note that I am using in both cases a sde connection file with the same privileges.

I am looking for workarounds in both cases.
 
Thank you
GIS developer
1 Reply
HaydenWelch
MVP Regular Contributor

That is very odd behavior...I'm not sure exactly what your environment is, but I'm gonna try and investigate exactly what a Result object is and how it's created to see if there's anything within arcpy itself that could cause this:

 

The Result object is a subclass of _BaseArcObject and ResultMixin. Those classes define __init__ while Result does not. The only interfaces defined in Result are the attributes (properties) and methods:

HaydenWelch_0-1758135676661.png

In your case, the properties seem to be normally accessible, so is there anything further down the chain that could end up dropping method creation?

The passthrough_attribute function is just a wrapper around property() that builds the properties for the class. Which is odd since those are stored alongside methods...So there could be some malformed result object that failed to create a property while building the class, then failed to build the methods defined after those property function calls. 

The ResultMixin defers initialization to _BaseArcObject which builds a new arc_object using the args and kwargs passed by the implementation:

...
    def __init__(self, *args, **kwargs):
        """Wrapper for ArcGIS scripting Arc Objects --
           Create a new object instance if no reference is passed in."""
        from arcpy import gp
        super(_BaseArcObject, self).__init__()
        self._arc_object = gp._gp.CreateObject(self.__class__.__name__,
                    *((arg._arc_object if hasattr(arg, '_arc_object') else arg)
                        for arg in args))
        for attr, value in list(kwargs.items()):
            setattr(self._arc_object, attr, value)
        self._go()
    def _go(self):
        if getattr(self, '__passthrough_to_ao__', False):
            self.__class__ = type(self.__class__.__name__, (self.__class__, _ArcobjectPassthrough), self.__dict__)
...

 

we can ignore the _go method since it does nothing for Result since there is no __passthrough_to_ao__ attribute defined (Row seems to be the only class that uses this).

So when the system creates a result object, it first creates the mixin, then the _base object, then the Result attributes. Your AttributeError names the Result class as well, so we know that we got something that has been defined as Result.

 

Would you mind sharing the output of a dir() call on the Result?

from arcpy import Result, Append_management

append_res = Append_management(
      inputs='gdb_fc_full_path',
      target='dest_full_path',
      schema_type="NO_TEST"
)

print(dir(append_res)) # inspect the runtime attributes of Result
if append_res and append_res.maxSeverity > 0:
      messages = append_res.getAllMessages()
      for message_type, message_code, message_string in messages:
            print(f"{message_type} : {message_code} - {message_string}")

 

That should make it clear what properties and methods actually exist at runtime.

0 Kudos