A big thank you to @Karan for directing me into the right path. I was able to come up with a general solution for any data path (Right click RMB any property in the user interface > Copy Data Path) and then use the function:
def get_property_name(data_path) -> str:
s = data_path
i = s.find('.')
data_path_1 = ""
data_path_2 = s
if i > 0:
ri = s.rindex('.')
data_path_1 = '.' + s[0:ri]
data_path_2 = s[ri+1:len(s)]
data = eval("bpy.context.object" + data_path_1)
return data.rna_type.properties[data_path_2].name if hasattr(data, data_path_2) else ''
Sample Outputs:
print(get_property_name('rotation_euler'))
print(get_property_name('rigid_body.collision_shape'))
print(get_property_name('modifiers["Bevel"].width'))
print(get_property_name('modifiers["Fluid"].flow_settings.surface_distance'))
# outputs:
#
# Eurler Rotation
# Collision Shape
# Width
# Surface Emission