ArcGIS Online Notebooks
Authentication
Always use notebook-native authentication:
from arcgis.gis import GIS
gis = GIS("home") # NEVER use credentials in notebooks
print(f"Connected as: {gis.users.me.username}")
Feature Layer Operations
Query with Pagination (Large Datasets)
from arcgis.features import FeatureLayer
import pandas as pd
fl = FeatureLayer("https://services.arcgis.com/.../FeatureServer/0", gis=gis)
count = fl.query(return_count_only=True)
if count > 10000:
all_data = []
offset = 0
while offset < count:
chunk = fl.query(result_offset=offset, result_record_count=5000).sdf
all_data.append(chunk)
offset += 5000
df = pd.concat(all_data, ignore_index=True)
else:
df = fl.query(where="1=1", return_all_records=True).sdf
Update Features in Chunks
def push_updates(fl, df, key_field, chunk_size=200):
"""Update feature attributes from DataFrame, matching on key_field."""
features = fl.query(where="1=1", out_fields="*").features
df_indexed = df.set_index(key_field)
updates = []
for ft in features:
key = ft.attributes.get(key_field)
if key in df_indexed.index:
row = df_indexed.loc[key]
for col, val in row.items():
if col != key_field:
ft.attributes[col] = None if pd.isna(val) else val
updates.append(ft)
if len(updates) >= chunk_size:
result = fl.edit_features(updates=updates)
print(f"Updated {len(updates)} features")
updates = []
if updates:
fl.edit_features(updates=updates)
Add New Features
from arcgis.features import Feature
from arcgis.geometry import Point
new_features = [
Feature(geometry=Point({"x": -77.0, "y": 38.9, "spatialReference": {"wkid": 4326}}),
attributes={"name": "DC Office", "status": "Active"})
]
fl.edit_features(adds=new_features)
Delete Features
# By OID
fl.edit_features(deletes="1,2,3")
# By query
oids = fl.query(where="status='Inactive'", return_ids_only=True)['objectIds']
if oids:
fl.edit_features(deletes=",".join(map(str, oids)))
Web Map Manipulation
import copy
import json
item = gis.content.get("ITEM_ID")
webmap_data = item.get_data() # Returns dict, not JSON string
# Modify operational layers
for layer in webmap_data.get('operationalLayers', []):
layer['visibility'] = False
# Group layers have nested 'layers'
for sublayer in layer.get('layers', []):
sublayer['visibility'] = True
# Save changes
item.update(data=json.dumps(webmap_data))
# Or create new map
new_data = copy.deepcopy(webmap_data)
props = {
'title': 'New Map',
'type': 'Web Map',
'tags': 'auto-generated',
'text': json.dumps(new_data)
}
new_item = gis.content.add(item_properties=props)
Content Management
# Search with proper escaping
results = gis.content.search(
f'title:"{title}" owner:{gis.users.me.username} type:"Web Map"'
)
# Check exists before create
if results:
results[0].update(data=json.dumps(new_data))
else:
gis.content.add(item_properties=props)
# Move to folder
item.move(folder="Analysis Results")
# Share
item.share(org=True) # or groups=['group_id']
Common Gotchas
get_data()returns dict, not string — usejson.dumps()when savingedit_features()silently fails on mismatched field names — verify field names first- NaN values must be converted to
Nonebefore updating - Chunk writes to avoid timeouts (200 features per batch is safe)
- Always pass
gis=gisto FeatureLayer if using secured services return_all_records=Truecan timeout on large datasets — use pagination instead
