I'm writing a python add-in that uses a Spatial Analyst function and hence requires the Spatial Analyst extension to be enabled. I would like to be able to check out the extension only if it hasn't already been manually checked out by the user (i.e. via the "Customize->Extensions" menu).
My code can check out the extension and then check it back in easily enough. However, this causes an issue if a user has already checked the extension out manually via the "Customize->Extensions" menu as they will suddenly start getting the "ERROR 000824: The tool is not licensed" error when trying to use other Spatial Analyst tools/functions (as my add-in has checked the extension back in).
A further complication that will confuse the user is that when they open the "Customize->Extensions" menu to check if the SA extension is checked out, the tick will still be in the extensions check box as checking the extension in via code does not update the GUI. E.g see screenshot below
There doesn't seem to be any way of testing whether the extension is already checked out out, i.e the return values for arcpy.CheckExtension are only Available, Unavailable, NotLicensed or Failed.
My work around is to wrap the use of the spatial analyst tool in a try:except: clause (see below), but it's ugly and is not useful for larger scripts that use more SA tools (SA objects/functions especially) as I have to code the syntax of the tools twice.
try: result = Sample(rasters,features,table) except ExecuteError as e: if 'ERROR 000824' in e.message: # "ERROR 000824: The tool is not licensed" if arcpy.CheckExtension('Spatial') == 'Available' and arcpy.CheckOutExtension('Spatial')=='CheckedOut': result = Sample(rasters,features,table) arcpy.CheckInExtension('Spatial') else: pythonaddins.MessageBox('Spatial Analyst license not available', 'Error', 0) return else:raise
Q: Is there a better way of only checking an extension out if it is not already checked out...?
Solved! Go to Solution.
To wrap things up, there doesn't seem to be a way of doing this in arcpy (ArcGIS Idea - Add 'AlreadyInitalized' to arcpy.CheckExtension function. ). So I use a try: except: clause in a context manager to do this now:
class SAExtension(object): def __init__(self): self.name = 'Spatial' from arcpy.sa import Int try: Int(1) except: self.checkedout = False else: self.checkedout = True def __enter__(self): if arcpy.CheckExtension(self.name) == "Available": arcpy.CheckOutExtension(self.name) else: raise ValueError("%s license isn't available" % self.name) def __exit__(self, *args): if not self.checkedout: arcpy.CheckInExtension(self.name) with SAExtension: #do some raster analysis
To wrap things up, there doesn't seem to be a way of doing this in arcpy (ArcGIS Idea - Add 'AlreadyInitalized' to arcpy.CheckExtension function. ). So I use a try: except: clause in a context manager to do this now:
class SAExtension(object): def __init__(self): self.name = 'Spatial' from arcpy.sa import Int try: Int(1) except: self.checkedout = False else: self.checkedout = True def __enter__(self): if arcpy.CheckExtension(self.name) == "Available": arcpy.CheckOutExtension(self.name) else: raise ValueError("%s license isn't available" % self.name) def __exit__(self, *args): if not self.checkedout: arcpy.CheckInExtension(self.name) with SAExtension: #do some raster analysis
Good catch Luke