askill
arcgis-python

arcgis-pythonSafety 90Repository

Comprehensive ArcGIS Python API expertise for ArcGIS Online and Enterprise. Use when writing Python code for Feature Layers, Web Maps, geocoding, routing, spatial analysis, raster operations, portal administration, content management, or any arcgis package operations. Covers authentication patterns, Spatially Enabled DataFrames, geometry operations, batch editing, publishing workflows, and performance optimization.

0 stars
1.2k downloads
Updated 2/8/2026

Package Files

Loading files...
SKILL.md

ArcGIS Python API

Authentication

from arcgis.gis import GIS

# ArcGIS Notebooks (always use this in hosted notebooks)
gis = GIS("home")

# OAuth (interactive apps)
gis = GIS("https://org.maps.arcgis.com", client_id="APP_ID")

# API Key (public content only)
gis = GIS(api_key="AAPK...")

# Username/password (scripts only — use environment variables)
import os
gis = GIS("https://org.maps.arcgis.com", os.environ["AGOL_USER"], os.environ["AGOL_PASS"])

Feature Layer Essentials

from arcgis.features import FeatureLayer, FeatureLayerCollection

# From URL
fl = FeatureLayer("https://services.arcgis.com/.../FeatureServer/0", gis=gis)

# From Item
item = gis.content.get("ITEM_ID")
flc = FeatureLayerCollection.fromitem(item)
fl = flc.layers[0]  # First layer
table = flc.tables[0]  # First table

# Layer properties
print(fl.properties.name, fl.properties.geometryType)
print([f["name"] for f in fl.properties.fields])

Query Patterns

# Basic query → Spatially Enabled DataFrame
sdf = fl.query(where="status='Active'", out_fields="name,status").sdf

# All records (small datasets <10k)
sdf = fl.query(where="1=1", return_all_records=True).sdf

# Pagination (large datasets) — SEE references/large-datasets.md
count = fl.query(return_count_only=True)

# Spatial query
from arcgis.geometry import Envelope
bbox = Envelope({"xmin": -78, "ymin": 35, "xmax": -77, "ymax": 36, "spatialReference": {"wkid": 4326}})
sdf = fl.query(geometry_filter=bbox, spatial_rel="intersects").sdf

# Return geometry or not
sdf = fl.query(return_geometry=False).sdf  # Faster for attribute-only queries

# Statistics
stats = fl.query(where="1=1", group_by_fields_for_statistics="region",
                 out_statistics=[{"statisticType": "count", "onStatisticField": "OBJECTID", "outStatisticFieldName": "total"}])

Edit Features

from arcgis.features import Feature
from arcgis.geometry import Point

# Add
new_features = [
    Feature(geometry=Point({"x": -77.0, "y": 38.9, "spatialReference": {"wkid": 4326}}),
            attributes={"name": "Site A", "status": "Active"})
]
result = fl.edit_features(adds=new_features)

# Update (must include OBJECTID)
updates = [Feature(attributes={"OBJECTID": 1, "status": "Closed"})]
result = fl.edit_features(updates=updates)

# Delete
fl.edit_features(deletes="1,2,3")  # By OID string
# Or by query
oids = fl.query(where="status='Inactive'", return_ids_only=True)["objectIds"]
if oids:
    fl.edit_features(deletes=",".join(map(str, oids)))

Batch Edits (Chunk for Reliability)

def chunked_edit(fl, features, operation="updates", chunk_size=200):
    """Batch edit with chunking to avoid timeouts."""
    results = []
    for i in range(0, len(features), chunk_size):
        chunk = features[i:i + chunk_size]
        result = fl.edit_features(**{operation: chunk})
        results.append(result)
        print(f"Processed {min(i + chunk_size, len(features))}/{len(features)}")
    return results

Spatially Enabled DataFrame (SEDF)

import pandas as pd
from arcgis.features import GeoAccessor, GeoSeriesAccessor

# Query to SEDF
sdf = fl.query().sdf

# DataFrame to SEDF
df = pd.DataFrame({"name": ["A", "B"], "lat": [38.9, 39.0], "lon": [-77.0, -77.1]})
sdf = pd.DataFrame.spatial.from_xy(df, "lon", "lat", sr=4326)

# From GeoJSON/Shapefile
sdf = pd.DataFrame.spatial.from_featureclass("path/to/data.shp")

# Export
sdf.spatial.to_featureclass("output.shp")
sdf.spatial.to_featurelayer("New Layer", gis=gis, folder="Analysis")

# Spatial operations
sdf["SHAPE"].geom.buffer(1000)  # Buffer geometries
sdf.spatial.project(3857)  # Reproject

Geometry Objects

from arcgis.geometry import Point, Polyline, Polygon, Geometry
from arcgis.geometry import project, buffer, union, intersect

# Create geometries (always include spatialReference)
pt = Point({"x": -77, "y": 38.9, "spatialReference": {"wkid": 4326}})
line = Polyline({"paths": [[[-77, 38], [-76, 39]]], "spatialReference": {"wkid": 4326}})
poly = Polygon({"rings": [[[-77, 38], [-76, 38], [-76, 39], [-77, 39], [-77, 38]]], 
                "spatialReference": {"wkid": 4326}})

# Geometry operations
buffered = buffer([pt], in_sr=4326, distances=[1000], unit="Meters")[0]
projected = project([pt], in_sr=4326, out_sr=3857)[0]

# From GeoJSON
geom = Geometry({"type": "Point", "coordinates": [-77, 38.9]})

Web Maps

from arcgis.mapping import WebMap
import json

# Load
item = gis.content.get("WEBMAP_ID")
wm = WebMap(item)

# Inspect layers
for layer in wm.layers:
    print(layer.title, layer.url)

# Get raw definition for modification
data = item.get_data()  # Returns dict

# Modify and save
data["operationalLayers"][0]["visibility"] = False
item.update(data=json.dumps(data))

# Create new web map
from arcgis.mapping import WebMap
wm = WebMap()
wm.add_layer(fl)
wm.save(item_properties={"title": "New Map", "tags": "analysis"})

Content Management

# Search
results = gis.content.search(f'title:"My Layer" owner:{gis.users.me.username} type:"Feature Service"')

# Create/publish
csv_item = gis.content.add({"title": "Data", "type": "CSV"}, data="data.csv")
published = csv_item.publish()

# Update
item.update(item_properties={"description": "Updated"})
item.update(data="new_data.csv")  # Replace data

# Share
item.share(org=True)
item.share(groups=["GROUP_ID"])
item.share(everyone=True)

# Move/delete
item.move(folder="Archive")
item.delete()

Common Patterns

Check Before Create

def get_or_create_item(gis, title, item_type, create_func):
    results = gis.content.search(f'title:"{title}" owner:{gis.users.me.username} type:"{item_type}"')
    if results:
        return results[0]
    return create_func()

Error Handling

from arcgis.gis import GISError

try:
    result = fl.edit_features(updates=features)
    # Check for partial failures
    for r in result.get("updateResults", []):
        if not r.get("success"):
            print(f"Failed OID {r.get('objectId')}: {r.get('error')}")
except GISError as e:
    print(f"API Error: {e}")

NaN Handling

import pandas as pd
import numpy as np

# Convert NaN to None before edit_features
def clean_for_agol(df):
    return df.replace({np.nan: None, pd.NaT: None})

Reference Files

  • Large dataset patterns → See references/large-datasets.md
  • Geocoding & routing → See references/geocoding-routing.md
  • Spatial analysis tools → See references/spatial-analysis.md
  • Admin & user management → See references/admin.md

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

94/100Analyzed 2/11/2026

An excellent, comprehensive technical reference for the ArcGIS Python API, featuring clear code snippets for common workflows and best practices.

90
95
95
95
95

Metadata

Licenseunknown
Version-
Updated2/8/2026
Publisherfranzenjb

Tags

api