Sometimes it’s extremely useful to be able to manage your Portal via scripting and handily Esri provides the ArcGIS API for Python for doing just this.
The reason for developing the script we discuss in this Blog was a need for a customer to view our data within it’s corporate on-site ArcGIS Enterprise Portal. Some of our data layers are published within ArcGIS Online (AGOL), and it can be time consuming to share large volumes of map services between Portals. In this instance we wanted to share roughly 1500 items, so a good option was to use the ArcGIS API for Python.
What does the script do?
This script allows you to copy items of interest (in this case Map and Image Services) between an AGOL Portal and an Enterprise Portal. The script does not explicitly copy the actual item, instead it copies the key ‘ingredients’ that make up that item in AGOL e.g., the title, URL, and type of item.
How would I get started?
You will need to have ArcGIS Pro installed and licenses on the machine you are developing so you can import the relevant EsriPython libraries, as well as a Python IDE running the ArcGIS Pro Python environment.
The code
The section below shows the start of the script. Note that the variables need to be configured to your specific setup. The AGOL Portal will be the source, while your local ArcGIS Enterprise will be the target Portal.
From arcgis.gis import GIS
# local ArcGIS Enterprise service information
localUsername = “ENTERPRISE USERNAME”
localPassword = “ENTERPRISE PASSWORD”
localPortalServer = “myserver.yourcompanyname.local”
localPortalServerPath = “portal”
localPortalServerPort = “443”# AGOL service information
agolUsername = “AGOL USERNAME”
agolPassword = “AGOL PASSWORD”
The script section below connects to the local Enterprise Portal. In this code example I have included “verify_cert=False”. This may not be necessary for your setup as most live/production installations will have properly configured security certification – however I had an unsecured test Enterprise Portal installed and for the code to work I had to pass this argument.
# connect to the destination portal instance
localgis = GIS(“https://” + localPortalServer + “:” + localPortalServerPort + “/” + localPortalServerPath, localUsername, localPassword, verify_cert=False)
When copying items into the target Portal, by default the items will be copied into the root directory. In most cases this is probably not ideal, so I decided to create a folder for all content to be copied to. If a folder of same name already exists then no error is thrown. This means that there is no need to check for an existing folder with the same name, and also that the contents of the folder will not be deleted.
However, the same cannot be said of items that you create (e.g. map image or feature layers) – the names for which should be unique. Later, you will see that the code skips items if they already exist in the target destination.
# create folder to put content into
folder_name = “upload_folder”
localgis.content.create_folder(folder_name)
Now we are ready to connect to the source which is an AGOL Portal. Once connected we must get a session token.
# connect to source portal (ArcGIS Online in this case)
gis = GIS(“https://arcgis.com”, agolUsername, agolPassword)
token = gis._con.token
We are going to search for items in the source portal which have a tag “Load21”. You may use other search criteria e.g., search by title or even URL. Max_items is an important argument here. The default is 1000, which may be sufficient for your needs. Further information on search options can be found in the Esri online Help for ContentManager.
# search for items in source portal that match the tag “Load21″
search_result = gis.content.search(query=”tags:” + ‘Load21’, max_items=5000)
The last part of the script loops through the search results from the AGOL Portal and checks to see if the item already exists within the Enterprise/target Portal. If the search result count is zero, then the item is added using dataProps variable. This has been populated with the item details harvested from the search result. You need this information along with the token in order to add the item:
- Title
- Type
- URL
As an optional argument we also pass the folder name to place the newly copied items into.
# loop through each item in search_result list and add to destination Portal
- for item in search_result:
dataProps = {‘title’: item.title, ‘type’: item.type, ‘url’: item.url, ‘serviceUsername’: agolUsername, ‘servicePassword’: agolPassword, ‘token’: token}
# check if item is already in local GIS before trying to add.
local_result = localgis.content.search(query=”title:” + item.title, max_items=1)
if len(local_result) == 0:
localgis.content.add(item_properties=dataProps, folder=folder_name)print(“Finished”)
Conclusion
The process for copying an item via such scripting is very quick – just a few seconds. You should find that using the ArcGIS API for Python in this way will save you a lot of laborious and tedious work – especially if you have hundreds or thousands of items to copy.
Posted by Simon Earnshaw, GIS Developer