Configuring VS Code for ArcPy/ArcGIS Pro development

I have been using Esri’s ArcGIS Pro and its companion Python package, ArcPy, more and more often as of late, and have really been enjoying developing with Python. For the unfamiliar, ArcGIS is geographic information system (GIS) software, primarily used to visualize and analyze geographic data. Python is commonly used to automate these analysis tasks within the software, and ArcPy exposes programmatic access to many features of ArcGIS. However, the way Esri delivers the ArcPy is a bit atypical in my experience, especially if you’re more familiar with open source Python implementations. ArcGIS Pro ships with a built-in Python interpreter that has the ArcPy site package baked in, containing a massive collection of Python modules. The ArcGIS Pro Python interpreter also includes Conda as the package manager and can be used via the standard terminal commands, but Esri also provides a cool GUI to manage Conda environments and dependencies.

The default tools that ship with ArcGIS Pro’s Python tools are limited, but that is to be expected. IDLE is of course available, and a Python CLI is installed as well; it integrates nicely with Windows Terminal and is also available from within ArcGIS Pro

IDLE – the default IDE installed with ArcGIS & Python
ArcGIS Pro cloned Python environment in Windows Terminal
ArcGIS Pro’s Python Window

Like three quarters of developers out there, I use Visual Studio Code in some capacity, so I wanted to be able to do all the necessary ArcGIS Pro Python coding and debugging from within my preferred development environment. Unfortunately, Esri leaves a lot to be desired looking at their documentation for using ArcPy within popular IDEs and editors like VS Code… I did some digging around the interwebs, reading a lot about ArcPy and ArcGIS Pro development, and put together a local development environment and configuration which works well for me over the course of several months of experimentation. My requirements for ArcGIS/ArcPy development tooling were pretty straight forward:

  • Integration with VS Code, including:
    • Linting & IntelliSense code completion working
    • Debugging, including being able to hit breakpoints
    • ArcGIS Pro’s Python package manager can remain the default for dependencies
  • No requirement to paste boilerplate or other “hacky” code to make things work as desired (I’ll clarify this in the last section).

After some trial and error, I was able to get everything configured to my liking. I do want to note here that my tutorial below is not the “correct” or “best” way to configure VS Code for ArcPy developement, it’s just what works the best for me, and I’m sharing here in case it’s useful for anyone else πŸ™‚

The first, and perhaps the most important, step is to set the location of the ArcGIS Python interpreter. This effectively “enables” ArcPy within VS Code. That is located here: %LocalAppData%\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\ however, Esri actually recommends not using this default Python environment, and instead using a cloned environment. This will allow packages to be add/removed without risk of breaking any tools or dependencies in the default environment.

My various Python environments, cloned from the default “arcgis-py3” environment

I initially went down the path of setting the value of “Conda Path” in VS Code > Settigns > Python to the location of ArcGIS Pro’s Conda installation. However, I observed some errors in the terminal indicating things may not actually be configured correctly. Before continuing, it may be helpful to take a look at my post on the Esri Community forums for more details; a user there, BrianWilson7, provided some great guidance on integrating Conda into VS Code. However I ultimately found a simpler solution that better fit my use case with not directly using Conda, which I will document below.

The first step is to set the Default Interpreter Path; on my machine the cloned ArcGIS Python environments were located here: %LocalAppData%\ESRI\conda\envs\ but they may also be found in the “Program Files” folder. See this doc from Esri for additional information about how to use the installed Python interpreter.

Setting the Python Default Interpreter path in the Python extension – this is the folder that contains a “python.exe” file.

The integrated VS Code terminal uses PowerShell by default, and after setting the default Python interpreter, I observed that on launch PowerShell was trying to execute a command to activate a Conda environment, but Conda was throwing an error:

I was able to resolve this by deleting this file, which contained an auto-generated default PowerShell profile from Conda: %HomePath%\Documents\WindowsPowerShell\profile.ps1. My personal preference, however, is to use the Windows Command Prompt as the default terminal shell, not PowerShell. (btw, if you ever get confused with “terminal” and “shell” in VS code, remember that the terminal is the text input/output environment, and the shell is the program with which the user interacts with the computer – there can be multiple shells in a terminal.) To make the Windows Command Prompt the default shell in the VS Code terminal, expand the menu on the “+” button in the upper right title bar of the integrated terminal, and then select “Command Prompt” when the VS Code command palette is opened with the available shell options.

Using the Windows Command Prompt over PowerShell as the default shell is a personal preference of mine for two main reasons: 1) I use VS Code Insiders to check out new features, but it’s also my dedicated Python development environment, meaning it is configured solely for Python programming and I don’t need to worry about supporting other languages/frameworks/environments, and 2) I find Windows CMD prompt to be better suited for the work I do with Python – PowerShell was just not needed. I do also have VS Code stable installed, and it is configured for all other types of development I do, mostly front end/JavaScript and back end/C#; PowerShell is my preferred default shell in this configuration.

Windows CMD is now the default shell in the VS Code integrated terminal.

After I set my default shell, Windows CMD will start up inside the VS Code terminal on each launch. That’s all that is needed – when a Python source code file is opened in VS Code, the Python environment that I set as the default will be used. ArcPy can be imported in code and all classes & methods are accessible for inspection in VS Code. All packages installed for this environment via ArcGIS Pro’s Python Package Manager can also be imported in code and used during execution.

The default Python environment can be changed in the currently open workspace in couple different ways: selecting it on the bottom status bar, or by opening the VS Code command palette (Ctrl + Shift + P) and searching for “Python: Select Interpreter.”

Now that everything is wired up, the next step is to test debugging of a Python script. While still in the Conda environment’s shell, noted by the (arcgispro-py3-clone-3.0.2) prefix in front of the directory prompt, open a working .py file, set a break point, and press F5 to debug. Select the “Python File…” option.

The Python Debug console should start up, the script will begin to execute, and the breakpoint will be hit. In the screenshot below you can see the all the modules within the ArcPy package are visible, and VS Code IntelliSense works as expected when writing ArcPy code.

IntelliSense in working with ArcPy

I typically prefer to create one or more debug profiles within a project; I find it makes frequent starts & stops of the code while testing a little easier. To create a debug profile, click the Debug button on the left to open the debug panel and then click “create a launch.json file.” Alternatively, select Run > Add Configuration from the menu bar.

Select the “Python: Current File” template, and then a new “launch.json” file inside a “.vscode” folder at the root of your project. Inside, an launch configuration for Python will be automatically stubbed out.

This config file is meant to be user-editable, and there are many additional options so be sure to refer to the VS Code docs on debugging to learn more. I changed the name of my profile for demonstration purposes, as this is how each individual configuration is identified in the drop down menu on the debug controls:

This should be sufficient for standalone script development with ArcPy, but I still wanted a little bit tighter integration with ArcGIS Pro and VS Code when it comes to debugging Python toolboxes. Unfortunately, at this time, there does not appear to be the ability for VS Code to attach to and debug a running ArcGISPro.exe Python process as PyCham and Visual Studio do. While that is a really nice feature to have, it is possible to structure the code in a way that it can be executed in both ArcGIS Pro as tools in toolboxes, and as a standalone script for testing and debugging purposes.

At the beginning of this post I mentioned that I didn’t want to have to rely on pasting in or commenting/un-commenting boilerplate code or using some other hacky methods when switching between running the code in Pro and VS Code. To tighten this integration, I structured my Pro toolbox code in a way that allows it to be run from Pro or VS Code, unmodified. This is accomplished by breaking each tool that is part of a .pyt Python Toolbox into its own separate class, in a separate .py file. The tool.py file only defines the tool’s class – there is no code to instantiate the class or do anything else, so if the file is run, the script will just exist immediately without doing anything. This is the desired behavior when running the Python toolbox in ArcGIS Pro.

When actively developing/testing/debugging a particular tool, I need deep debugging control, not having to reply on printing information to the output message window. In order to debug my tool in VS Code, I added a hook to the .py file that will check for a specific parameter I will pass in when starting the script, “DEBUG.” The code snippet below is added to the bottom of the tool.py file:

if sys.argv[-1] == "DEBUG":
    # add your debug code here
    pass

Passing in that “DEBUG” argument is done via the debug configuration set in launch.json. An “args” property can be added, which contains an array of the arguments that should be passed in when the debugging session start. Since my tool has a one user input parameter (a name), I also include that in the args array.

{
    "configurations": [
        {
            "name": "Debug MyTool.py",
            "type": "python",
            "request": "launch",
            "program": "${fileDirname}\\MyTool.py",
            "console": "integratedTerminal",
            "args": ["foo", "bar", "DEBUG"]
        }
    ]
}

Any number of parameters can be passed in here, and you may find that having multiple debug configurations with different arguments is useful. The only requirement is that the last argument be “DEUBG” so that the condition is met, and custom debug code can be added.

I hope this helps other ArcPy developers out there. I welcome any comments, suggestions, corrections, or other feedback on this tutorial. I am not an expert Python developer, but since I wasn’t able to find a whole lot of information or comprehensive tutorials on configuring VS Code for ArcPy, I would like this post to be accurate and a valuable reference for other VS Code & ArcGIS users.

2 thoughts on “Configuring VS Code for ArcPy/ArcGIS Pro development

  1. It would be nice if we could force proenv to run before vsc tries to activate the env when just running the script from the RUN button.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s