Relative Module Imports in an ArcGIS Python Toolbox

The idea of ArcGIS Python toolboxes really appeals to me. I really like them. As is frequently the case in life, the devil is in the details. Python Toolboxes have plenty of interesting personality quirks. Among these is relative module imports when creating Python Toolboxes for ArcGIS Pro.

Here is the situation. On my team, we have standardized on a project template, and I really like the way it keeps all the resources organized. Part of the project structure is for the ArcGIS Pro Project to be located in the arcgis directory, and all Python code to be in a module with the same name as the project inside a directory called src.

- projet_name
  - arcgis
    - project_name.aprx
    - project_name.tbx
    - project_name.pyt
  - notebooks
  - src
    - project_name
      - __init__.py

While there are a lot more directories in this structure, this outline should help you understand the important strucural components we use for this discussion. I included the notebooks directory in here to simply illustrate the code contained in the src directory is not only used in the *.pyt file. It is used in multiple places in the project. Hence, our need to import packages and modules from the src directory.

Although somewhat of a hack...ok fine, a very non-Pythonic hack, this does enable us to keep our projects much more organized. We simply apppend to the sys.path list before importing our local modules.

import os
import sys

sys.path.append(os.path.abspath('../src'))

import project_name

This enables us to keep the Python Toolbox with the ArcGIS Pro Project, project_name.aprx, and also have access to all our code at the same time. Hopefully this painfully discovered hack makes your life easier, and saves you the time we spent figuring it out!