Select to view content in your preferred language

Using Python to identify Map objects used in Esri ArcGIS Enterprise Portal or AGOL Web Applications?

849
2
05-30-2024 03:39 PM
Labels (1)
BBowers_napacounty
Occasional Contributor

Hi!
I'm trying to list the feature layers shown in each map from every web application, dashboard, and storymap on my Enterprise Portal. Is there a way to retrieve all the map objects that belong to an app? Something like this, maybe?:

from arcgis.gis import GIS
from arcgis.mapping import WebMap

gis = GIS(url='https://myesriportal.org/portal', username='admin', password='PUT_PASSWORD_HERE')
webapp_items = gis.content.search(query=f"type:Web Mapping Application", max_items=10000)
webapp_items += gis.content.search(query=f"type:Dashboard", max_items=10000)
webapp_items += gis.content.search(query=f"type:StoryMap", max_items=10000)

#print the web app title, web map title, and layer name
for webapp_item in webapp_items:
    for webmap_item in webapp_item.content.webmaps: # Does something like this exist?
        webmap_obj = WebMap(webmap_item)
        for layer in webmap_obj:
            print(webapp_item.title, webmap_item.title, layer.title)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Thanks in advance for any suggestions!

0 Kudos
2 Replies
MobiusSnake
MVP Regular Contributor

I don't think there's an easy way to pull a list of webmaps from an app, especially given the numerous types of apps you could be dealing with - EXB, WAB, StoryMaps, Dashboards, etc.

One way might be to do this:

  • Scan your portal for webmap items and cache their Item IDs in a set
  • Scan your portal for apps and for each, do the following:
    • Get the item's JSON definition using get_data()
    • Use regex to look for any Item IDs in the JSON
    • Anywhere you find an Item ID, check it against your set, and if you get a hit, print it out

I've used this approach when looking for layers referenced by webmaps and it worked well, I haven't tried it with the app-webmap scenario.

I can imagine at least two scenarios where I don't think this would work and you'd need some extra logic:

  • An app that uses an external organization's webmap
  • Embedded content panels that include a URL but not an Item ID

Edit to Add - Re-reading your code I noticed you're not just printing out the webmap Item IDs but also the layer IDs, so you'd probably want to cache those details along with the webmap IDs.

usace_sam_rd3
Emerging Contributor

I still need to complete the section about pulling data sources for apps; but this code goes through all maps and creates an inventory all layers and adds them to a hosted table (feature layer variable is  warehouse_maps_svc_lyr)

#Build Map Inventory table - Maps and associated layers

from arcgis.mapping import WebMap
from arcgis.features import FeatureSet
import pandas as pd
wm_items = gis.content.search("*", item_type="Web Map", max_items=500)
print("This ArcGIS Online Organization contains {} web maps.".format(len(wm_items)))

map_count = 0
layer_count =0

for webmap_item in wm_items:
    
    map_count = map_count + 1
    print("---------------------")
    print("Map ",map_count, " of ",len(wm_items))
    ago_map_id = webmap_item.id
    print("Map ID:",ago_map_id)
    map_title = webmap_item.title
    map_owner = webmap_item.owner
    print("Map Title: ",map_title)
    #convert to Map
    wmItem = gis.content.get(ago_map_id)
    webmap = WebMap(wmItem)
    try:
        layers = webmap.layers
        tables = webmap.tables
    except Exception as e:
        print("Error setting layers and tables")

    try:
        # Export Feature Services/Tables
        if len(layers) > 0:
            for layer in layers:
                layer_count = layer_count + 1
                if layer.layerType =="GroupLayer":
                    for g in layer.layers:
                        lyr_url = g.url
                        lyr_id = g.id
                        lyr_name = g.title
                        print("Group Layer Name:",lyr_name)
                        print("Group Layer ID:",lyr_id)
                        print("Group Layer URL:",lyr_url)
                        layer_data = {
                            'ago_map_id': ago_map_id, 
                            'map_title':map_title, 
                            'map_owner':map_owner, 
                            'ago_layer_id': lyr_id,
                            'layer_title':lyr_name,
                            'layer_url':lyr_url}
                        df = pd.DataFrame(layer_data, index=[0])
                        feature_set = FeatureSet.from_dataframe(df)
                        result = warehouse_maps_svc_lyr.edit_features(adds=feature_set)
                else:
                    lyr_url = layer.url
                    lyr_id = layer.id
                    lyr_name = layer.title
                    print("Layer Name:",lyr_name)
                    print("Layer ID:",lyr_id)
                    print("Layer URL:",lyr_url)
                    
                    layer_data = {
                            'ago_map_id': ago_map_id, 
                            'map_title':map_title, 
                            'map_owner':map_owner, 
                            'ago_layer_id': lyr_id,
                            'layer_title':lyr_name,
                            'layer_url':lyr_url}
                    df = pd.DataFrame(layer_data, index=[0])
                    feature_set = FeatureSet.from_dataframe(df)
                    result = warehouse_maps_svc_lyr.edit_features(adds=feature_set)
        if len(tables) > 0 :
            for table in tables:
                print("Table")
                layer_count = layer_count + 1
                lyr_url = table.url
                lyr_id = table.id
                lyr_name = table.title
                print("Table Name:",lyr_name)
                print("Table ID:",lyr_id)
                print("Table URL:",lyr_url)
                
                layer_data = {
                        'ago_map_id': ago_map_id, 
                        'map_title':map_title, 
                        'map_owner':map_owner, 
                        'ago_layer_id': lyr_id,
                        'layer_title':lyr_name,
                        'layer_url':lyr_url}
                df = pd.DataFrame(layer_data, index=[0])
                feature_set = FeatureSet.from_dataframe(df)
                result = warehouse_maps_svc_lyr.edit_features(adds=feature_set)
                
    except Exception as e:
        print("Error getting properties")
print("\t{}\n\t{}".format("Map Count: " + str(map_count), "Layer Count: " + str(layer_count)))   

 

0 Kudos