I am trying to bind a perspective dropdown component value prop to the results of the sys.tag.browse function, I can get a messy batch pretty easily by using a script transformation on a tag path like this:
This will return the one item I have in that folder and the names of the two folders inside of it.
However, what I need it to do is to do a recursive search inside the additional folders and return those tags as well. At that point, I need to only use the ânameâ and âfullPathâ in my object to be used with the dropdown component.
Goal return format:
value = '[default]test_folder'
browse_result = system.tag.browse(value, {}).getResults()
return [{'value': result['fullPath'], 'label': result['name']} for result in browse_result]
Nest a dictionary literal inside a list comprehension - so youâre looping through every element from getResults(), and for each one, construction a dictionary with value and label members (necessary for Perspectiveâs dropdown to work properly).
Thats exactly the format I need it in!
is there a way to incorporate a recursive browse into that?
I tried adding if result['hasChildren'] == True: browseTags(result['fullPath'], filter)
But I keep getting errors.
I also tried creating a function to accomplish this, but that only returns the tag at the root and the two folders, it doesnât do the recursive browse.
If I do a simple print instead of return, it does show me all the item, but still only returns the root tags.
def browseTags(path, filter):
# Call the browse function
results = system.tag.browse(path, filter).getResults()
# Loop through every item in the results and print it
for result in results:
if result['hasChildren'] == False:
print result
# If the item has children, call the function to repeat the process but starting at the child.
elif result['hasChildren'] == True:
browseTags(result['fullPath'], filter)
#return [{'value': result['fullPath'], 'label': result['name']} for result in results]
# Call the function
browse_results = browseTags('[default]Customers/Demo/nampa_ls/Reads', {})
print [{'value': result['fullPath'], 'label': result['name']} for result in browse_result]
Somewhat naive/optimistic implementation - be careful running this anywhere with lots and lots of tags. Basically just recurses the browseTags function as you had it, but adds the results to a continually growing list. The slice with no arguments ([:]) is a slightly underhanded Python way to copy a list in place.
def browseTags(path, browsefilter, current=[]):
# Call the browse function
results = system.tag.browse(path, browsefilter).getResults()
# Loop through every item in a _copy_ of the current results (to avoid concurrently modifying the list)
for result in results[:]:
# no need for == True - a true value automatically passes the if check
if result['hasChildren']:
browseTags(result['fullPath'], browsefilter, current=results)
else:
results.append(result)
else:
return results
# Call the function
browse_results = browseTags('[default]', {})
print [{'value': result['fullPath'], 'label': result['name']} for result in browse_results]
It seems I spoke too soon, I used the wrong tag path in testing it.
It still only brings back the items at the base of the path, and it seems it now duplicates the tag that is not a folder.
def browseTags(path, browsefilter, current=[]):
# Call the browse function
results = system.tag.browse(path, browsefilter).getResults()
tagList = []
# Loop through every item in a _copy_ of the current results (to avoid concurrently modifying the list)
for result in results[:]:
# no need for == True - a true value automatically passes the if check
if result['hasChildren']:
recursive_results = browseTags(result['fullPath'], browsefilter, current=results)
for result in recursive_results:
tagList.append(result)
else:
tagList.append(result)
return tagList
I think its due to the dictionary being inside a list, but trying to do any sort of manipulation on the label / value pairs is proving to be difficult.
To make it more human readable, and because browsing recursively adds a lot of duplicate name tags I am trying to use the âfullPathâ twice and splitting down the label string to only show the parent folder of the tag like this:
One good option to remove duplication - replace the list structure thatâs passed between executions with a dictionary - dictionaries are keyed and will automatically replace duplicate values, so if you key the entries off the full name you wonât end up with duplicates.
It will change the iteration you have to do at the end, though - youâll need to loop through the dictionaryâs items to pull out the tag objects, then put them into the list comprehension.
explained: fullpath.split("/") turns the string into a list of strings, âsplitâ on the / character [-2:] grabs from the second to last item (-2) to the end (nothing after the :) "/".join() takes a sequence of strings and puts them together, using "/" as the delimiter - itâs an exact inverse operation to split()