I've used this script to great effect over the years. Thanks to all who have contributed to it. I just wanted to post my slightly improved version that includes Web Experiences (kudos @Big-Chill), Web Maps, better exception handling, and hyperlinks the titles (in Jupyter Notebooks).
Output should look something like this:
from arcgis.gis import GIS
import pandas as pd
from IPython.display import display, HTML
# Log in to portal; prompts for PW automatically
gis = GIS('your-portal-url', 'username')
# Layer ID to search for
find_id = 'a405b06ae8e24f94a2768a4581b79e73'
# Get the content based on ID
content_item = gis.content.get(find_id)
# Check if content is found
if content_item:
find_url = content_item.url
# URL snippet for web maps e.g. https://osit.maps.arcgis.com/apps/mapviewer/index.html?webmap=
web_map_url_snippet = 'your-webmap-domain-path'
# Pull list of all web maps in portal
webmaps = gis.content.search('', item_type='Web Map', max_items=-1)
# Return subset of map IDs which contain the service URL we're looking for
matches = [m.id for m in webmaps if m.url and find_url in m.url]
# Create empty list to populate with results
app_list = []
exp_list = []
web_map_list = [] # New list for web maps
# Pull list of all web apps in portal
webapps = gis.content.search('', item_type='Application', max_items=-1)
# Check each web app for matches
for w in webapps:
try:
# Get the JSON as a string
wdata = str(w.get_data())
criteria = [
wdata.find(find_url) > -1, # Check if URL is directly referenced
any([wdata.find(i) > -1 for i in matches]) # Check if any matching maps are in app
]
# If layer is referenced directly, append app to list
if any(criteria):
app_list.append(w)
# Some apps don't have data, so we'll just skip them if they throw a TypeError
except:
continue
# Pull list of all web experience apps
webexp = gis.content.search('', item_type='Web Experience', max_items=-1)
# Check each web experience app for matches
for wx in webexp:
try:
# Get the JSON as a string
wxdata = str(wx.get_data())
criteria = [
wxdata.find(find_url) > -1, # Check if URL is directly referenced
any([wxdata.find(i) > -1 for i in matches]) # Check if any matching maps are in app
]
# If layer is referenced directly, append app to list
if any(criteria):
exp_list.append(wx)
# Some apps don't have data, so we'll just skip them if they throw a TypeError
except:
continue
# Check each web map for matches
for wm in webmaps:
try:
# Get the JSON as a string
wmdata = str(wm.get_data())
criteria = [
wmdata.find(find_url) > -1, # Check if URL is directly referenced
any([wmdata.find(i) > -1 for i in matches]) # Check if any matching maps are in app
]
# If layer is referenced directly, append web map to list
if any(criteria):
# Construct the complete web map URL
wm_url = f'{web_map_url_snippet}{wm.id}'
web_map_list.append({'Title': f'<a href="{wm_url}" target="_blank">{wm.title}</a>', 'ID': wm.id, 'Type': 'Web Map'})
# Some web maps don't have data, so we'll just skip them if they throw a TypeError
except:
continue
# Create DataFrames
app_df = pd.DataFrame([
{'Title': f'<a href="{a.url}" target="_blank">{a.title}</a>', 'ID': a.id, 'Type': a.type}
for a in app_list
])
exp_df = pd.DataFrame([
{'Title': f'<a href="{b.url}" target="_blank">{b.title}</a>', 'ID': b.id, 'Type': b.type}
for b in exp_list
])
web_map_df = pd.DataFrame(web_map_list)
# Display the HTML content
display(HTML(web_map_df.to_html(escape=False)))
display(HTML(app_df.to_html(escape=False)))
display(HTML(exp_df.to_html(escape=False)))
else:
print(f"Content with ID '{find_id}' not found.")