Select to view content in your preferred language

Python differences between Pro and Notebook Server

525
3
Jump to solution
09-16-2025 05:09 PM
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 Solution

Accepted Solutions
MatthiasBoucher
Occasional Contributor

I pursued my investigations, and I think the problem is with my ArcGIS Server which is too old. My script works on Pro 3.3, but once published, whether as a Notebook or as a GPServer, crashes. I thought the "Result" object of the arcpy API had the same structure, but no (cf this archive doc : https://pro.arcgis.com/en/pro-app/2.9/arcpy/classes/result.htm) , the getAllMessages function appeared recently. So the problem had nothing to do with the Append nor the ReconcileVersions. I'll close the thread.

GIS developer

View solution in original post

0 Kudos
3 Replies
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
MatthiasBoucher
Occasional Contributor

Hello Hayden

Thank you for the analysis.  In the meantime, I've been able to solve the root cause of the append error, which was due to an invalid spatial index. However the arcpy question remains, and I've been able to reproduce it with another use case this time : a ReconcileVersions instead of an Append. Here is the code :

import arcpy

arcpy.AddMessage("START")
try:
arcpy_res = arcpy.ReconcileVersions_management(
# ***
)
except arcpy.ExecuteError as exer:
arcpy.AddError(f"Arcpy error: {exer}")
except Exception as ex:
arcpy.AddError(f"Python error: {ex}")

if arcpy_res:
arcpy.AddMessage(f"arcpy_res.maxSeverity: {arcpy_res.maxSeverity}")
if arcpy_res.maxSeverity == 0:
arcpy.AddMessage("Success")
else:
arcpy.AddMessage(f"arcpy_res: {arcpy_res}")
arcpy.AddMessage(dir(arcpy_res))
messages = arcpy_res.getAllMessages()
for message_type, message_code, message_string in messages:
arcpy.AddMessage(f"{message_type} : {message_code} - {message_string}")
arcpy.AddMessage("END")

And here are the logs you were asking for :

START
arcpy_res.maxSeverity: 1
arcpy_res: 
['__class__', '__cmp__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', '__weakref__', '_arc_object', '_go', '_repr_html_', 'cancel', 'getInput', 'getMapImageURL', 'getMessage', 'getMessages', 'getOutput', 'getSeverity', 'inputCount', 'maxSeverity', 'messageCount', 'outputCount', 'resultID', 'saveToFile', 'status']

 


 Then the crash is identical : 

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/tmp/ipykernel_379/3846124269.py in <module>
     29         arcpy.AddMessage(f"arcpy_res: {arcpy_res}")
     30         arcpy.AddMessage(dir(arcpy_res))
---> 31         messages = arcpy_res.getAllMessages()
     32         for message_type, message_code, message_string in messages:
     33             arcpy.AddMessage(f"{message_type} : {message_code} - {message_string}")

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

Thank you.

GIS developer
0 Kudos
MatthiasBoucher
Occasional Contributor

I pursued my investigations, and I think the problem is with my ArcGIS Server which is too old. My script works on Pro 3.3, but once published, whether as a Notebook or as a GPServer, crashes. I thought the "Result" object of the arcpy API had the same structure, but no (cf this archive doc : https://pro.arcgis.com/en/pro-app/2.9/arcpy/classes/result.htm) , the getAllMessages function appeared recently. So the problem had nothing to do with the Append nor the ReconcileVersions. I'll close the thread.

GIS developer
0 Kudos