A Beginner’s Guide to the ArcGIS Python API

Introduction

If you work with spatial data in Esri‘s ecosystem, chances are you have heard about the ArcGIS Python API. It is one of the most powerful tools available to GIS professionals who want to automate workflows, manage geospatial content, and perform spatial analysis without clicking through a GUI every time.

This guide is written for beginners: people who understand Python at a basic level and have some familiarity with GIS concepts but have never used the ArcGIS Python API before. By the end, you will know what the API is, how to set it up, and how to start using it for real tasks.


What Is the ArcGIS Python API?

The ArcGIS Python API is a Python library developed and maintained by Esri. It allows you to interact programmatically with ArcGIS Online, ArcGIS Enterprise, and ArcGIS Living Atlas of the World. Think of it as a bridge between your Python environment and Esri’s entire platform.

With the API, you can:

  • Connect to ArcGIS Online or Enterprise portals
  • Search, create, update, and delete content items
  • Publish and manage hosted feature layers and web maps
  • Perform spatial analysis using Esri’s hosted tools
  • Automate repetitive administrative tasks
  • Visualize maps directly inside Jupyter Notebooks
  • Work with feature data as Pandas-compatible data structures

The library is officially known as arcgis on PyPI, and its documentation is hosted at developers.arcgis.com.


Setting Up Your Environment

Prerequisites

Before installing the library, make sure you have:

  • Python 3.x installed (Python 3.9 or later is recommended)
  • A working ArcGIS Online account or access to an ArcGIS Enterprise portal
  • Conda or pip for package management

Installing via Conda (Recommended)

Esri recommends using Conda because the API has several dependencies that are easier to manage in a Conda environment.

conda create -n arcgis_env python=3.9
conda activate arcgis_env
conda install -c esri arcgis

Installing via pip

pip install arcgis

Note that pip installation may require you to install some spatial dependencies like GDAL separately, depending on your operating system.

Verifying the Installation

Open a Python shell or Jupyter Notebook and run:

import arcgis
print(arcgis.__version__)

If you see a version number without errors, the installation was successful.


Connecting to a GIS

The entry point for almost everything you do with the ArcGIS Python API is the GIS object. It represents a connection to either ArcGIS Online or an ArcGIS Enterprise portal.

Anonymous Connection (No Login)

from arcgis.gis import GIS

gis = GIS()
print("Connected anonymously to ArcGIS Online")

This gives you read-only access to public content.

Authenticated Connection

from arcgis.gis import GIS

gis = GIS("https://www.arcgis.com", "your_username", "your_password")
print(f"Logged in as: {gis.properties.user.username}")

Connecting to ArcGIS Enterprise

from arcgis.gis import GIS

gis = GIS("https://your-portal.example.com/portal", "username", "password")

Using the Active Portal in ArcGIS Pro

If you are working inside ArcGIS Pro and want to use the currently signed-in user’s credentials:

from arcgis.gis import GIS

gis = GIS("pro")

Searching for Content

One of the most common tasks is searching for items in your portal or on ArcGIS Online.

# Search for public feature layers related to parks
results = gis.content.search("parks", item_type="Feature Layer", max_items=10)

for item in results:
    print(f"{item.title} | {item.type} | {item.id}")

Filtering Your Search

You can refine searches by owner, tags, or a combination:

# Search for items owned by a specific user
my_items = gis.content.search(query="owner:your_username", max_items=50)

for item in my_items:
    print(item.title)

Working with Items

Every piece of content in an ArcGIS portal (a web map, a feature layer, a CSV, a dashboard) is represented as an Item object.

Getting an Item by ID

item = gis.content.get("your_item_id_here")
print(item.title)
print(item.type)
print(item.url)

Viewing Item Metadata

print(item.description)
print(item.tags)
print(item.snippet)
print(item.created)  # Unix timestamp

Displaying a Web Map in a Notebook

from arcgis.mapping import WebMap

webmap_item = gis.content.get("your_webmap_id")
webmap = WebMap(webmap_item)
webmap

When run inside a Jupyter Notebook, this renders an interactive map directly in the output cell.


Working with Feature Layers

Feature layers are the backbone of most GIS workflows. The API makes it easy to access, query, and edit them.

Accessing a Feature Layer

from arcgis.features import FeatureLayer

# Get the item first
item = gis.content.get("your_feature_layer_item_id")

# Access the first layer in the service
layer = item.layers[0]
print(layer.properties.name)

Querying Features

# Query all features
feature_set = layer.query(where="1=1", out_fields="*")

# Convert to a Pandas DataFrame
df = feature_set.sdf
print(df.head())

The .sdf property (Spatially Enabled DataFrame) is one of the most useful features of the API. It combines Pandas DataFrame functionality with spatial awareness, letting you perform attribute operations and spatial operations in the same object.

Filtering with a WHERE Clause

# Query features with a specific condition
result = layer.query(where="population > 100000", out_fields=["city_name", "population"])
df = result.sdf
print(df)

Querying with a Spatial Filter

from arcgis.geometry import Envelope

# Define a bounding box
extent = Envelope({"xmin": -87.9, "ymin": 41.6, "xmax": -87.5, "ymax": 42.1,
                   "spatialReference": {"wkid": 4326}})

result = layer.query(geometry_filter=extent, geometry_type="esriGeometryEnvelope")

The Spatially Enabled DataFrame (SeDF)

The Spatially Enabled DataFrame (SeDF) is a powerful extension of the Pandas DataFrame. It adds a SHAPE column that holds geometry objects, enabling spatial operations directly within familiar Pandas syntax.

Creating an SeDF from a CSV

import pandas as pd
from arcgis.features import GeoAccessor

df = pd.read_csv("cities.csv")  # Must have latitude and longitude columns

# Convert to SeDF
sdf = pd.DataFrame.spatial.from_xy(df, x_column="longitude", y_column="latitude", sr=4326)
print(sdf.spatial.sr)  # Spatial reference

Plotting an SeDF

sdf.spatial.plot(map_widget=gis.map())

Exporting an SeDF to a Feature Layer

published_item = sdf.spatial.to_featurelayer("My New Layer", gis=gis, folder="My Folder")
print(published_item.url)

Publishing Content

The API makes it straightforward to publish new content to your portal.

Publishing a CSV as a Feature Layer

# Add the CSV as an item first
csv_item = gis.content.add({
    "title": "City Populations",
    "type": "CSV",
    "tags": "cities, population"
}, data="cities.csv")

# Publish it as a hosted feature layer
published = csv_item.publish({
    "type": "csv",
    "locationType": "coordinates",
    "latitudeFieldName": "latitude",
    "longitudeFieldName": "longitude"
})

print(f"Published: {published.title}")

Publishing a Shapefile

# Add the zipped shapefile
shp_item = gis.content.add({
    "title": "My Shapefile",
    "type": "Shapefile",
    "tags": "boundaries"
}, data="my_shapefile.zip")

# Publish
published = shp_item.publish()
print(published.url)

Spatial Analysis

The API exposes Esri’s hosted spatial analysis tools through the arcgis.features.analysis and arcgis.raster.analytics modules.

Running a Buffer Analysis

from arcgis.features.analysis import create_buffers

input_layer = gis.content.get("your_feature_layer_id").layers[0]

result = create_buffers(
    input_layer=input_layer,
    distances=[1],
    distance_unit="Miles",
    output_name="Buffered_Layer"
)

print(result)

Note that hosted analysis tools consume ArcGIS Online credits when run against cloud-hosted data. Always check your credit balance before running large analyses.


Managing Users and Groups (Admin Tasks)

For portal administrators, the API is especially valuable for automation.

Listing All Users in Your Organization

users = gis.users.search(max_users=500)
for user in users:
    print(f"{user.username} | {user.role} | {user.level}")

Creating a Group

new_group = gis.groups.create(
    title="Field Team GIS",
    tags="field, operations",
    description="Group for field team spatial data",
    access="org"
)
print(new_group.id)

Adding a User to a Group

group = gis.groups.get("your_group_id")
group.add_users(["username1", "username2"])

Visualizing Maps in Jupyter Notebooks

One of the most engaging features of the API is its built-in map widget for Jupyter Notebooks.

# Create a map centered on Chicago
my_map = gis.map("Chicago, IL", zoomlevel=11)
my_map

Adding a Layer to the Map

layer_item = gis.content.get("your_item_id")
my_map.add_layer(layer_item)

Changing the Basemap

my_map.basemap = "satellite"
# Other options: "streets", "topo", "dark-gray", "gray", "oceans", "osm"

Common Patterns and Best Practices

Always Handle Authentication Securely

Never hard-code passwords in your scripts. Use environment variables or a credentials file instead:

import os
from arcgis.gis import GIS

gis = GIS(
    "https://www.arcgis.com",
    os.environ["ARCGIS_USERNAME"],
    os.environ["ARCGIS_PASSWORD"]
)

Use try/except for Robust Scripts

try:
    item = gis.content.get("possibly_invalid_id")
    if item:
        print(item.title)
    else:
        print("Item not found.")
except Exception as e:
    print(f"Error: {e}")

Paginate Large Queries

The API enforces a default limit of 1000 features per query. For large datasets, use pagination:

offset = 0
batch_size = 1000
all_features = []

while True:
    batch = layer.query(where="1=1", result_offset=offset, result_record_count=batch_size)
    if not batch.features:
        break
    all_features.extend(batch.features)
    offset += batch_size

print(f"Total features retrieved: {len(all_features)}")

Useful Resources


Conclusion

The ArcGIS Python API opens up a wide range of capabilities for GIS professionals who want to move beyond point-and-click workflows. Whether you are automating content management, building data pipelines, running spatial analysis at scale, or just exploring your organization’s data programmatically, this library is built for it.

Start small: connect to your portal, search for a layer you know, query its features, and visualize them in a notebook. Once those basics feel natural, the rest of the API becomes much more approachable.

The most important thing is to build the habit of reaching for Python when a task feels repetitive. That instinct, combined with what you have learned in this guide, is where real GIS automation begins.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *