[GIS] Checking if ArcGIS extension has already been checked out manually in ArcPy

arcgis-license-managerarcpyerror-000824error-010096

I've written a python script 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" dialog).

There doesn't seem to be any way of testing whether the extension is already checked out out using arcpy.CheckExtension as that returns Available regardless of whether a license is already checked out or not (assuming there is a license available).

My code can check out the extension and then check it back in easily enough which is fine if the code is running outside of ArcGIS. However, this causes an issue in ArcGIS if a user has already checked the extension out manually via the "Customize->Extensions" dialog as they will suddenly start getting the "ERROR 000824: The tool is not licensed" or "ERROR 010096: There is no Spatial Analyst license currently available or enabled." errors when trying to use other Spatial Analyst tools/functions (as my code has checked the extension back in).

A further complication that may confuse the user is that when they open the "Customize->Extensions" dialog 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 dialog. E.g see screenshot below

enter image description here

My work around was to test using a simple spatial analyst tool (Int(1)) in a try:except: clause (see below), but that's just ugly.

from arcpy.sa import Int

def sa_is_licensed():
    try:
        Int(1)
        return True
    except (ExecuteError, RuntimeError) as e:
        # "ERROR 000824: The tool is not licensed"
        # "ERROR 010096:  There is no Spatial Analyst license currently available or enabled."
        if 'ERROR 000824' in e.message or 'ERROR 010096' in e.message:
            if arcpy.CheckExtension('Spatial') == 'Available' and arcpy.CheckOutExtension('Spatial')=='CheckedOut':
               return False
            else:raise
        else:raise

already_licensed = sa_is_licensed()

# My big long script...

if not already_licensed: arcpy.CheckInExtension('Spatial')

Are there any better ways to check from ArcPy if an ArcGIS extension has already been checked out?

Best Answer

This can be done with python, but not using arcpy as far as I know. If you use comtypes you can have some degree of access to ArcObjects. By accessing the AoInitialize class, you can check on licenses/extensions that are checked out by supplying an extension code.

Here is some sample code:

import comtypes

# load olb
esriSys = r'C:\Program Files (x86)\ArcGIS\Desktop10.3\com\esriSystem.olb'
comtypes.client.GetModule(esriSys)
import comtypes.gen.esriSystem as esriSystem


def NewObj(COMClass, COMInterface):
    """Creates a new comtypes POINTER object where\n\
    MyClass is the class to be instantiated,\n\
    MyInterface is the interface to be assigned"""
    from comtypes.client import CreateObject
    try:
        ptr = CreateObject(COMClass, interface=COMInterface)
        return ptr
    except:
        return None

# now call AoInitialize
pInit = NewObj(esriSystem.AoInitialize,
                esriSystem.IAoInitialize)

# 10 is spatial analyst
licenseAvailable = pInit.IsExtensionCheckedOut(10)
if licenseAvailable:
    print 'license is checked out'
else:
    print 'license not checked out'

And here is an example inside ArcMap (I have taken the Snippets module and modified it a bit and saved it as a package called "arcobjects"). Also, I did not mean to make this confusing, but my variable name is misleading...It should have been called licenseCheckedOut, as that is the actual property being used, not checking for availability (which you can do in arcpy).

usage with license checked out:

enter image description here

And once the extension is checked back in:

enter image description here