I want to download attachments from an ArcGIS Online Feature Layer and use them for further operations. So far, I did this using
search_result = gis.content.search(ArcGIS_content, "Feature Layer")
item = search_result[0]
FeatureLayer = item.layers[0]
FeatureObjectIDs = FeatureLayer.query(where = "1=1", return_ids_only = True)
for objID in FeatureObjectIDs["objectIds"]:
print("Checking object", str(objID) + "...")
attachments_list = FeatureLayer.attachments.get_list(oid = objID)
in order to get the object IDs and then iterate through all items of the Feature Layer. However, this takes a lot of time and few items actually have an attachment. How can I change the where parameter so I get only the object IDs of objects with an attachment?
Solved! Go to Solution.
The Attachment Manager submodule of the Python API does allow you to do a query on all attachments. If you do not specify a query string, it will return information about every attachment from the layer.
Notably, the output includes the parent object/global ID. You can pull that column out and turn around to query the parent service with that list.
l = gis.content.get('647e966722f943d0b5d49f82288a839e').layers[0] # adjust as needed to get your particular service / layer
attachments = l.attachments.search(as_df=True)
attachments['PARENTOBJECTID'].drop_duplicates().to_list()
The result: a list of objectids with attachments!
Now, that addresses the title of your post. But in the body of your post, you mention downloading the items, too. You could feed that objectid list into your original script if you like, but it's worth noting that using the attachments.search() method and returning the results as a dict (as opposed to a DataFrame), each attachment includes the property "DOWNLOAD_URL".
So you could try something like this:
downloads = [a['DOWNLOAD_URL'] for a in l.attachments.search()]
And then you have list of URLs from which you can iteratively download every attachment.
hello
this code might help you, it is used in the arcgisonline notebook.
Regards
The Attachment Manager submodule of the Python API does allow you to do a query on all attachments. If you do not specify a query string, it will return information about every attachment from the layer.
Notably, the output includes the parent object/global ID. You can pull that column out and turn around to query the parent service with that list.
l = gis.content.get('647e966722f943d0b5d49f82288a839e').layers[0] # adjust as needed to get your particular service / layer
attachments = l.attachments.search(as_df=True)
attachments['PARENTOBJECTID'].drop_duplicates().to_list()
The result: a list of objectids with attachments!
Now, that addresses the title of your post. But in the body of your post, you mention downloading the items, too. You could feed that objectid list into your original script if you like, but it's worth noting that using the attachments.search() method and returning the results as a dict (as opposed to a DataFrame), each attachment includes the property "DOWNLOAD_URL".
So you could try something like this:
downloads = [a['DOWNLOAD_URL'] for a in l.attachments.search()]
And then you have list of URLs from which you can iteratively download every attachment.