Hi everyone,
Trying to assign thumbnail images to existing FGCD metadata of feature classes in a geodatabase. The thumbnail images are in .jpg format and are on a local drive with a prefix matching the name of the feature class (the gdb is also on the local drive).
Example: feature class is Zip_Code_Tabulation_Areas and corresponding thumbnail image is Zip_Code_Tabulation_Areas_thumbnail.jpg
Trying to follow the documentation from https://pro.arcgis.com/en/pro-app/latest/arcpy/metadata/metadata-class.htm
import arcpy
import os
arcpy.env.overwriteOutput = True
from arcpy import metadata as md
# set the workspace
arcpy.env.workspace = r"D:\gisdata\rigis_download\rigis_services_SPF_2023.gdb"
# create the list of feature classes within the local geodatabase
fc_list = arcpy.ListFeatureClasses()
# iterate through each feature class to assign a thumbnail to the metadata
for each in fc_list:
try:
print('the feature class is ' + each)
thumbnailImage = r"D:\gisdata\rigis_download\thumbnails" + "\\" + each + "_thumbnail.jpg"
print('the thumbnail is ' + thumbnailImage)
tgt_item_md = md.Metadata(each)
tgt_item_md.thumbnailUri(thumbnailImage)
tgt_item_md.save()
except:
print('this did not work')
print('done')
It never works for any of the feature classes and sometimes actually deletes the jpgs from the directory all together. Error is:
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Tried multiple variations of what I ~think~ is the critical piece to no avail:
tgt_item_md.thumbnailUri(thumbnailImage)
tgt_item_md.thumbnailUri = thumbnailImage
I "think" it may be because the variable thumbnailImage is just a string, and not the image itself? I am not proficient enough in python to figure out how to create a variable of the actual image?
Although the documentation implies it can be a path as a string:
thumbnailUri (Read and Write) | A local or network path, or a URL, to a graphic file that describes and helps to identify the item. Derived from the Thumbnail that is extracted from the item's metadata. When setting this value, if a URL is provided, the identified file will be downloaded and incorporated into the item’s metadata. | String |
tgt_item_md.isReadOnly returns False so the metadata should be writeable.
Thank you for any help. I am probably missing something easy.
Solved! Go to Solution.
I have upgraded my Pro 3.0 to Pro 2.9.3 as that is the last version that didn't give me tons of issues (especially with popups and attachments), so was testing in Stand Alone IDLE 3.7.11.
Just tried on my other box with Pro 3.0.3 on it, and ran in a Notebook. Seems to be working as expected.
I did add a check to make sure the jpg is there before adding it, as if not, it will fail at some point, and have to re-copy all the jpegs again to run.
Not sure where/how you are looking at the Thumbnails, but good old Catalog shows them as all being updated:
I do make sure I don't have Map/Pro/Catalog open and connected to the workspace so I don't have to deal with lock issues.
Also, can confirm that all images that were successfully copied to the thumbnail are deleted from the source folder.
R_
I had a similar issue same as @compass_cartographic where I was getting the error message
TypeError: 'NoneType' object is not callable
So I ended up at this thread and the solution was to change tgt_item_md.thumbnailUri(thumb_path) to tgt_item_md.thumbnailUri = thumb_path.
I think the issue is a "chicken and egg" scenario. I had a folder with hundreds of datasets I wanted to insert a generic thumbnail into. How can you update something if nothing exists? So when you want to update the thumbnail you need to set it rather than update an existing one when you are creating metadata for the first time.
I had a similar problem with update tags and summary. I had to run my code twice, first to import , that gave me something that exists then I ran the code again to update it.
Here is my code for people to review.
import arcpy
from arcpy import metadata as md
"""
Comment out 3-lines as required to update metadata accordingly.
"""
# Set the standard-format metadata XML file's path
# This dataset I used ArcPro to populate with lots of generic metadata which I want to apply to all other datasets in the same folder.
src_file_path = r"C:\Project\Raster\CHIRPS2_0\AfricaMonthly\chirps-v2.0.1981.01.tif"
# Generic thumbnail image to be applied to all metadata
thumb_path = r'C:\Scratch\chirps.png'
# Set the current workspace
arcpy.env.workspace = r"C:\Project\Raster\CHIRPS2_0\AfricaMonthly"
# Get and print a list of GRIDs from the workspace
rasters = arcpy.ListRasters("*", "TIF")
for raster in rasters:
if raster != "chirps-v2.0.1981.01.tif": # skip self
print(raster)
yr = raster[12:16] # Extract year from file name
mth = raster[17:19] # Extract month from file name
tgt_item_md = md.Metadata(raster)
if not tgt_item_md.isReadOnly:
# These 3 lines import metadata and update thumbnail
#tgt_item_md.importMetadata(src_file_path)
#tgt_item_md.thumbnailUri = thumb_path
#tgt_item_md.save()
# These 3 lines update tags and summary which now EXIST due to the previous run of import.
tgt_item_md.tags = tgt_item_md.tags + "," + yr
tgt_item_md.summary = tgt_item_md.summary + " Year = " + yr + ", Month = " + mth
tgt_item_md.save()
Metadata documentation shows setting content equal to, not putting in parrens.
This works for me:
tgt_item_md.thumbnailUri = thumbnailImage
R_
Thank you - I have already tried that, but will try again...
Might want to make sure you have a copy of all the images. "Most" of the time when it sucessfully updates the thumbnail, it deletes the photo from the source location.
R_
I have reloaded all the .jpgs to ensure the directory contains each one. Re ran with
tgt_item_md.thumbnailUri = thumbnailImage
Some of the jpgs disappeared again, but for those that disappeared, they still do not show up in the metadata when I view it (I forgot to mention I am using Pro 3.0). Tried running the script in both pyscripter as a standalone script, and from within a Pro Jupyter Notebook.
I have upgraded my Pro 3.0 to Pro 2.9.3 as that is the last version that didn't give me tons of issues (especially with popups and attachments), so was testing in Stand Alone IDLE 3.7.11.
Just tried on my other box with Pro 3.0.3 on it, and ran in a Notebook. Seems to be working as expected.
I did add a check to make sure the jpg is there before adding it, as if not, it will fail at some point, and have to re-copy all the jpegs again to run.
Not sure where/how you are looking at the Thumbnails, but good old Catalog shows them as all being updated:
I do make sure I don't have Map/Pro/Catalog open and connected to the workspace so I don't have to deal with lock issues.
Also, can confirm that all images that were successfully copied to the thumbnail are deleted from the source folder.
R_
Thank you so much for helping! Have no real idea what resolved the problem as nothing was working when I shut down last night, but this morning when I rebooted my machine, the thumbnails were present in the metadata. Everything seems to have worked! Very mysterious and frustrating. But at least I know the code I've been working with is correct and for this I am grateful! Thanks again - I really appreciate your time!
I had a similar issue same as @compass_cartographic where I was getting the error message
TypeError: 'NoneType' object is not callable
So I ended up at this thread and the solution was to change tgt_item_md.thumbnailUri(thumb_path) to tgt_item_md.thumbnailUri = thumb_path.
I think the issue is a "chicken and egg" scenario. I had a folder with hundreds of datasets I wanted to insert a generic thumbnail into. How can you update something if nothing exists? So when you want to update the thumbnail you need to set it rather than update an existing one when you are creating metadata for the first time.
I had a similar problem with update tags and summary. I had to run my code twice, first to import , that gave me something that exists then I ran the code again to update it.
Here is my code for people to review.
import arcpy
from arcpy import metadata as md
"""
Comment out 3-lines as required to update metadata accordingly.
"""
# Set the standard-format metadata XML file's path
# This dataset I used ArcPro to populate with lots of generic metadata which I want to apply to all other datasets in the same folder.
src_file_path = r"C:\Project\Raster\CHIRPS2_0\AfricaMonthly\chirps-v2.0.1981.01.tif"
# Generic thumbnail image to be applied to all metadata
thumb_path = r'C:\Scratch\chirps.png'
# Set the current workspace
arcpy.env.workspace = r"C:\Project\Raster\CHIRPS2_0\AfricaMonthly"
# Get and print a list of GRIDs from the workspace
rasters = arcpy.ListRasters("*", "TIF")
for raster in rasters:
if raster != "chirps-v2.0.1981.01.tif": # skip self
print(raster)
yr = raster[12:16] # Extract year from file name
mth = raster[17:19] # Extract month from file name
tgt_item_md = md.Metadata(raster)
if not tgt_item_md.isReadOnly:
# These 3 lines import metadata and update thumbnail
#tgt_item_md.importMetadata(src_file_path)
#tgt_item_md.thumbnailUri = thumb_path
#tgt_item_md.save()
# These 3 lines update tags and summary which now EXIST due to the previous run of import.
tgt_item_md.tags = tgt_item_md.tags + "," + yr
tgt_item_md.summary = tgt_item_md.summary + " Year = " + yr + ", Month = " + mth
tgt_item_md.save()