(Python 3.6) call a variable from a python toolbox file (.pyt)

214
4
Jump to solution
01-13-2022 04:46 PM
CCastro_GIS
New Contributor II

Hello everyone! I'd really appreciate it if someone could help me with this issue. 

I have a customized python toolbox file (.pyt) and what I need to do is, from another module (.py), call a variable stored inside a function in that toolbox. Here's a quick overview of the .pyt file:

Validation.pyt

>class Validation(object):

>> def getParameterInfo(self):

>> def execute(self, parameters, messages):

>>> def check_geometry_poly(inputfile):

         (...some code) error_count = x

I need to get the result from that error_count variable to use it in another script. I'm struggling with the fact that .pyt file doesn't seem to be callable like a normal .py module, where I would simply import Validation and call Validation.check_geometry_poly() to access the variable result. 

Any ideas?

Thank you in advance!

C Castro

0 Kudos
2 Solutions

Accepted Solutions
LongDinh
Occasional Contributor II

Hi @CCastro_GIS

You can load a pyt file as a module by using the importlib.machinery.SourceFileLoader() method. SourceFileLoader allows you to create a module-like object from a text file which can then be imported in your script.

So it would look something like:

# Lets load MyToolBox.pyt from Z:\MyToolBox.pyt

import importlib
import os

pytDir = r"Z:"
pytFile = "MyToolBox.pyt"
pytPath = os.path.join(pytDir, pytFile)

# Create module-like object
pytModule = importlibe.machinery.SourceFileLoad(
   "MyToolBox", pytPath 
)
# Import the file as a module called MyToolbox (similar to a 'import MyToolbox' statement)
MyToolBox = pytModule.load_module("MyToolBox")

# Access the module and print some of its class/methods
print (MyToolBox)
print (MyToolBox.Validation().check_geometry_poly)

 

View solution in original post

LongDinh
Occasional Contributor II

Hi @CCastro_GIS ,

You can use Python's Built-in vars() function or the Python Class object's Built-in __dict__ variable. Both return a dictionary/mapping object of all the stored attributes of the object.

If your object's variables are hard-coded into the Class object, the values will appear.

If they are stored via the arcpy.GetParameter within the class method, I suspect the attribute will not appear as it is encapsulated within the class method. You can probably assign the parameter to the class's self to make it appear after executing the method (ArcGIS Tool).

Something like the below should cover both scenarios (printing the stored variable in your Tool and printing the input parameter stored as a variable in your class at method call). 

class MyToolBox(ToolBox):
 def __init__(self):
    # Use the ArcGIS ToolBox Template (I can't remember how it goes...)
    self.tools = [MyTool]

class MyTool(Tool):
 def __init__(self):
    self.stored_variable_to_print = 'Hello world'

 def paramaters(self):
    self.dynamic_parameter = arcpy.Parameter("dynamicParameter" ...)
    self.parameters = [self.dynamic_parameter]
 def getParameters(self):
    # ...
    return self.parameters

 def executeMyTool(self):
    print (self.__dict__)
    self._executeMyTool_dynamic = arcpy.GetParameter(0)
    # See if self.parameters[0] has changed to the set value, 
    # and check _executeMyTool_dynamic variable
    print (self.__dict__)
    return

print (vars(MyTool))

 

 

View solution in original post

4 Replies
LongDinh
Occasional Contributor II

Hi @CCastro_GIS

You can load a pyt file as a module by using the importlib.machinery.SourceFileLoader() method. SourceFileLoader allows you to create a module-like object from a text file which can then be imported in your script.

So it would look something like:

# Lets load MyToolBox.pyt from Z:\MyToolBox.pyt

import importlib
import os

pytDir = r"Z:"
pytFile = "MyToolBox.pyt"
pytPath = os.path.join(pytDir, pytFile)

# Create module-like object
pytModule = importlibe.machinery.SourceFileLoad(
   "MyToolBox", pytPath 
)
# Import the file as a module called MyToolbox (similar to a 'import MyToolbox' statement)
MyToolBox = pytModule.load_module("MyToolBox")

# Access the module and print some of its class/methods
print (MyToolBox)
print (MyToolBox.Validation().check_geometry_poly)

 

CCastro_GIS
New Contributor II

Hi @LongDinh ! thank you very much for your answer. It's helped me to understand what I need to do. The only thing I am still struggling with is pulling the variable results after running the toolbox. Is there a way to write a line of code inside the Validation.pyt  script that would pull all variables I want out of the many functions inside it and then call the variables from this code alone?  

Thank you again and sorry for asking a question that is out of the scope of ArcGIS

0 Kudos
LongDinh
Occasional Contributor II

Hi @CCastro_GIS ,

You can use Python's Built-in vars() function or the Python Class object's Built-in __dict__ variable. Both return a dictionary/mapping object of all the stored attributes of the object.

If your object's variables are hard-coded into the Class object, the values will appear.

If they are stored via the arcpy.GetParameter within the class method, I suspect the attribute will not appear as it is encapsulated within the class method. You can probably assign the parameter to the class's self to make it appear after executing the method (ArcGIS Tool).

Something like the below should cover both scenarios (printing the stored variable in your Tool and printing the input parameter stored as a variable in your class at method call). 

class MyToolBox(ToolBox):
 def __init__(self):
    # Use the ArcGIS ToolBox Template (I can't remember how it goes...)
    self.tools = [MyTool]

class MyTool(Tool):
 def __init__(self):
    self.stored_variable_to_print = 'Hello world'

 def paramaters(self):
    self.dynamic_parameter = arcpy.Parameter("dynamicParameter" ...)
    self.parameters = [self.dynamic_parameter]
 def getParameters(self):
    # ...
    return self.parameters

 def executeMyTool(self):
    print (self.__dict__)
    self._executeMyTool_dynamic = arcpy.GetParameter(0)
    # See if self.parameters[0] has changed to the set value, 
    # and check _executeMyTool_dynamic variable
    print (self.__dict__)
    return

print (vars(MyTool))

 

 

CCastro_GIS
New Contributor II

Amazing! thank you very much for taking the time and effort to help me out. It's saved me a lot of struggle. Really appreciate it. 

Have a great week